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作为返回值。

浙公网安备 33010602011771号