SpringMVC 请求与响应

//注意,POJO类型必须提供setter方法用于注入,getter方法用于获取,Spring将POJO转JSON时,需要借助POJO的getter方法获取数据。

1 设置请求映射路径

@Controller
@RequestMapping("/user")
//当类上和方法上都添加了@RequestMapping注解,前端发送请求的时候,要和两个注解的value值相加匹配才能访问到,即/user/save。
//@RequestMapping注解value属性前面加不加/都可以。
public class BookController {
    @RequestMapping("/save")
    @ResponseBody
    public String save(){
        System.out.println("UserController_save");
        return "{'module':'user save'}";
    }
    
    @RequestMapping("/delete")
    @ResponseBody
    public String delete(){
        System.out.println("UserController_delete");
        return "{'module':'user delete'}";
    }
}


2 简单请求参数

(1) GET发送单个参数

<1> 发送请求与参数

http://localhost/commonParam?name=itcast

<2> 接收参数

@Controller
public class UserController {
    @RequestMapping("/commonParam")
    @ResponseBody
    public String commonParam(String name){
        System.out.println("普通参数传递 name ==> "+name);
        return "{'module':'commonParam'}";
    }
}

(2) GET发送多个参数

<1> 发送请求与参数

http://localhost/commonParam?name=itcast&age=18

<2> 接收参数

@Controller
public class UserController {
    @RequestMapping("/commonParam")
    @ResponseBody
    public String commonParam(String name,int age){
        System.out.println("普通参数传递 name ==> "+name);
        System.out.println("普通参数传递 age ==> "+age);
        return "{'module':'commonParam'}";
    }
}

(3) GET请求中文乱码

<1> 发送请求与参数

http://localhost/commonParam?name=张三&age=18

<2> 如果传递的参数中有中文,接收到的参数会出现中文乱码问题。

//Tomcat8.5以后的版本已经处理了中文乱码的问题,但是IDEA中的Tomcat插件目前只到Tomcat7,所以需要修改pom.xml来解决GET请求中文乱码问题

<plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.1</version>
    <configuration>
    <port>8080</port>
    <!--tomcat端口号-->
    <path>/</path>
    <!--虚拟目录-->
    <uriEncoding>UTF-8</uriEncoding>
    <!--访问路径编解码字符集-->
    </configuration>
</plugin>

(4) POST发送参数

<1> 发送请求与参数

http://localhost/commonParam
请求体:name=itcast age=18

<2> 接收参数

和GET一致,不用做任何修改。

(5) POST请求中文乱码

<1> 发送请求与参数

http://localhost/commonParam
请求体:name=张三 age=18

<2> 如果传递的参数中有中文,接收到的参数会出现中文乱码问题。

配置过滤器

public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
    //乱码处理
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        //CharacterEncodingFilter是在spring-web包中,所以用之前需要导入对应的jar包。
        filter.setEncoding("UTF-8");
        return new Filter[]{filter};
    }
}


3 复杂请求参数

(1) 普通参数

//url地址传参,请求参数名(请求中的参数名)与形参变量名(方法名中的参数名)相同,定义形参即可接收参数,见上。
//以下为形参名与地址参数名不一致情况。

<1> 发送请求和参数

//形参(username)与地址参数名(name)不一致情况。
http://localhost/commonParamDifferentName?name=张三&age=18

<2> 接收参数

@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(@RequestParam("name") String userName , int age){
    //@RequestParam注解中的值应与地址参数名一致,此时形参变量名可以与地址参数名不一致。
    //@RequestParam注解可以绑定请求参数与处理器方法形参间的关系。
    //写上@RequestParam注解框架就不需要自己去解析注入,能提升框架处理性能。
    System.out.println("普通参数传递 userName ==> "+userName);
    System.out.println("普通参数传递 age ==> "+age);
    return "{'module':'common param different name'}";
}

(2) POJO数据类型

//请求参数名(请求中的参数名)与形参对象属性名(pojo中的属性名)相同,定义POJO类型形参即可接收参数。

<1> POJO类

public class User {
    private String name;
    private int age;
    //setter getter...
}

<2> 发送请求与参数

http://localhost/pojoParam?name=itcast&age=18
//请求参数key的名称要和POJO中属性名一致,否则无法封装。

<3> 接收参数

@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
    //POJO参数接收,前端GET和POST发送请求数据的方式不变。
    System.out.println("pojo参数传递 user ==> "+user);
    return "{'module':'pojo param'}";
}

(3) 嵌套POJO类型参数

//请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数。

<1> POJO类

//POJO对象中嵌套了其他的POJO类。

public class Address {
    private String province;
    private String city;
    //setter getter...
}

public class User {
    private String name;
    private int age;
    private Address address;
    //User类中嵌套了address类。
    //setter getter...
}

<2> 发送请求与参数

http://localhost/pojoParam?name=itcast&age=18&address.province=beijing&addreaa.city=beijing
//请求参数key的名称要和POJO中属性的名称一致,否则无法封装。

<3> 接收参数

//POJO参数:请求参数与形参对象中的属性对应即可完成参数传递。

@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
    System.out.println("pojo参数传递 user ==> "+user);
    return "{'module':'pojo param'}";
}

(4) 数组类型参数

//请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型即可接收参数。

<1> 发送请求与参数

http://localhost/arrayParam?likes=pistol&likes=knife&likes=survival
//参数名必须一致才能封装到一个数组中。

<2> 接收参数

//数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中。

@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
    System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
    return "{'module':'array param'}";
}

(5) 集合类型参数

//请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系。

<1> 发送请求和参数

http://localhost/arrayParam?likes=pistol&likes=knife&likes=survival

<2> 接收参数

//集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据。
//对于简单数据类型使用数组会比集合更简单些。

@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
    System.out.println("集合参数传递 likes ==> "+ likes);
    return "{'module':'list param'}";
}

//若不加@RequestParam,会报错。
//错误的原因是:SpringMVC将List看做是一个POJO对象来处理,将其创建一个对象并准备把前端的数据封装到对象中,但是List是一个接口无法创建对象,所以报错。

 

4 JSON数据传输参数

//现在比较流行的开发方式为异步调用。前后台以异步方式进行交换,传输的数据使用的是JSON。
//中括号表示json数组,大括号表示json对象。

(1) JSON普通数组

//["value1","value2","value3",...]

<1> pom.xml添加依赖

//SpringMVC默认使用的是jackson来处理json的转换,所以需要在pom.xml添加jackson依赖。

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>

<2> PostMan发送JSON数据

["pistol","knife","survival"]

<3> 开启SpringMVC注解支持

//在SpringMVC的配置类中开启SpringMVC的注解支持,这里面就包含了将JSON转换成对象的功能。

@Configuration
@ComponentScan("com.itheima.controller")
//开启json数据类型自动转换。
@EnableWebMvc
public class SpringMvcConfig {
}

<4> 参数前添加@RequestBody

//使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据。

@RequestMapping("/listParamForJson")
@ResponseBody
//@ResponseBody设置当前控制器返回值为响应体。
//@ResponseBody返回值只能为字符串。若不是,则转化为JOSN。其实真正转换工作的还是用jackson,所以必须导入jackson坐标。
//若返回值为字符串,则字符串为响应体。若为对象或者数组、集合则转换为json作为响应体(需要添加jackson坐标)。
public String listParamForJson(@RequestBody List<String> likes){
//@RequestBody将前端发送的json数据转化为对象,并将其与形参对应起来。
//传JSON数据get和post一样,都是在请求体里面,所以使用@RequestBody而非@RequestParam。
    System.out.println("list common(json)参数传递 list ==> "+likes);
    return "{'module':'list common for json param'}";
}

<5> 启动运行程序

(2) JSON对象

//{key1:value1,key2:value2,...}

<1> pom.xml添加依赖

<2> PostMan发送JSON数据

{
    "name":"itcast",
    "age":15,
    //address为user对象中的一个属性,该属性也为对象。
    "address":{
        "province":"beijing",
        "city":"beijing"
    }
}

<3> 开启SpringMVC注解支持

<4> 参数前添加@RequestBody

@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
    System.out.println("pojo(json)参数传递 user ==> "+user);
    return "{'module':'pojo for json param'}";
}

<5> 启动运行程序

(3) JSON对象数组

//[{key1:value1,...},{key2:value2,...}]

<1> pom.xml添加依赖

<2> PostMan发送JSON数据

[
    {"name":"itcast","age":15},
    {"name":"itheima","age":12}
]

<3> 开启SpringMVC注解支持

<4> 参数前添加@RequestBody

@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
    System.out.println("list pojo(json)参数传递 list ==> "+list);
    return "{'module':'list pojo for json param'}";
}

<5> 启动运行程序

(4) @RequestBody与@RequestParam区别

<1> @RequestParam用于接收url地址传参,表单传参[application/x-www-form-urlencoded]
<2> @RequestBody用于接收json数据[application/json]
<3> 后期开发中,发送json格式数据为主,@RequestBody应用较广。
<4> 如果发送非json格式数据,选用@RequestParam接收请求参数。

 

5 日期类型参数传递

<1> 编写方法接收日期数据

//在UserController类中添加方法,把参数设置为日期类型。

@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date){
    System.out.println("参数传递 date ==> "+date);
    return "{'module':'data param'}";
}

<2> 启动Tomcat服务器

//查看控制台是否报错,如果有错误,先解决错误。

<3> 使用PostMan发送请求

//使用PostMan发送GET请求,并设置date参数
http://localhost/dataParam?date=2088/08/08

<4> 查看控制台

SpringMVC可以接收这种日期数据类型,并将其打印在控制台。

<5> 更换日期格式

//为了能更好的看到程序运行的结果,我们在方法中多添加一个日期参数。

@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,@DateTimeFormat(pattern="yyyy-MM-dd") Date date1){
    //若不添加@DateTimeFormat注解,则会报错。
    //因为SpringMVC默认支持的字符串转日期的格式为yyyy/MM/dd,而现在传递的不符合其默认格式,SpringMVC就无法进行格式转换。
    System.out.println("参数传递 date ==> "+date);
    System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
    return "{'module':'data param'}";
}

<6> 使用PostMan发送请求,携带两个不同的日期格式

http://localhost/dataParam?date=2088/08/08&date1=2088-08-08

<7> @DateTimeFormat实现原理

当前端传递json时,后端使用对象接收。当前端传递字符串时,后端Date对象接收。
这个转换是由SpringMVC完成的。SpringMVC中提供了很多类型转换接口和实现类来完成数据类型的转换。
比如Converter接口,框架中有提供很多对应Converter接口的实现类,用来实现不同数据类型之间的转换。
比如HttpMessageConverter接口,该接口是实现对象与JSON之间的转换工作。

 

6 响应

(1) 响应页面

<1> 设置返回页面

@Controller
public class UserController {
    @RequestMapping("/toJumpPage")
    //此处不能添加@ResponseBody,如果加了该注解,会直接将page.jsp当字符串返回前端。
    //此方法需要返回String。
    public String toJumpPage(){
        System.out.println("跳转页面");
        return "page.jsp";
        //在webapp下寻找page.jsp页面并返回,若未能找到,则会报404错误。
    }
}

<2> 启动程序测试

此处涉及到页面跳转,所以不适合采用PostMan进行测试,直接打开浏览器,输入http://localhost/toJumpPage

(2) 响应字符串

<1> 设置返回字符串

@Controller
public class UserController {
    @RequestMapping("/toText")
    @ResponseBody
    //注意此处@ResponseBody注解就不能省略,如果省略了,会把response text当前页面名称去查找,如果没有则会报404错误。
    public String toText(){
        System.out.println("返回纯文本数据");
        return "response text";
    }
}

<2> 启动程序测试

使用PostMan进行测试,输入地址 http://localhost/toText访问

(3) 响应JSON数据

//内部还是通过Converter接口的实现类完成的。

<1> 响应POJO对象

@Controller
public class UserController {
    @RequestMapping("/toJsonPOJO")
    @ResponseBody
    public User toJsonPOJO(){
    //返回值为实体类对象,设置返回值为实体类类型,即可实现返回对应对象的json数据。
    //需要依赖@ResponseBody注解和@EnableWebMvc注解。
        System.out.println("返回json对象数据");
        User user = new User();
        user.setName("itcast");
        user.setAge(15);
        return user;
    }
}

<2> 响应POJO集合对象

@Controller
public class UserController {
    @RequestMapping("/toJsonList")
    @ResponseBody
    public List<User> toJsonList(){
        //返回值为集合对象,设置返回值为集合对象类型,即可实现返回对应集合对象的json数据。
        System.out.println("返回json集合数据");

        User user1 = new User();
        user1.setName("传智播客");
        user1.setAge(15);

        User user2 = new User();
        user2.setName("黑马程序员");
        user2.setAge(12);

        List<User> userList = new ArrayList<User>();
        userList.add(user1);
        userList.add(user2);
        return userList;
    }
}


7 注释小结

(1) @RequestParam 主要用于将前端发送的普通参数与控制器中形参对应起来。
(2) @RequestBody 主要用于将前端发送的JSON参数转化为对象参数,并与控制器中形参对应起来。
(3) @ResponseBody 主要用于置当前控制器方法响应内容为当前返回值,无需解析为页面。
//若不加该注解,Spring会默认认为你返回的是一个需要跳转的目的文件名,加入@ResponseBody是告诉Spring返回值是回写的数据不是跳转的文件名。
<1> 若控制器返回值为String,则会将字符串作为返回值。
<2> 若控制器返回值为对象或对象数组,则会将对象或对象数组转化为JSON作为返回值。

posted @ 2023-10-17 21:55  10kcheung  阅读(75)  评论(0)    收藏  举报