请求与响应
其他springMvc笔记
SpringMVC _ 起步(http://mxzfun.xyz/index.php/archives/553/)
springMvc _ 请求与响应(http://mxzfun.xyz/index.php/archives/557)
SpringMVC _ REST风格(http://mxzfun.xyz/index.php/archives/558)
SpringMVC _ SSM整合、拦截器(http://mxzfun.xyz/index.php/archives/562/)
二、请求与响应
2.1 请求映射路径
2.1.1 问题
- UserController有一个save方法,访问路径为http://localhost/save
- BookController也有一个save方法,访问路径为http://localhost/save
- 当访问http://localhost/saved的时候,到底是访问UserController还是 BookController?
实例
@Controller
public class BookController {
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("book save ...");
return "{'module':'book save'}";
}
}
@Controller
public class UserController {
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'user save'}";
}
@RequestMapping("/delete")
@ResponseBody
public String delete(){
System.out.println("user delete ...");
return "{'module':'user delete'}";
}
}
2.1.2 解决优化方案
- 在类上添加
@RequestMapping("/XXX")
方法。 - 访问时路径为“http://localhost/book/save”。
@Controller
@RequestMapping("/book")
public class BookController {
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("book save ...");
return "{'module':'book save'}";
}
}
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'user save'}";
}
@RequestMapping("/delete")
@ResponseBody
public String delete(){
System.out.println("user delete ...");
return "{'module':'user delete'}";
}
}
2.1.3 请求映射路径 —— @RequestMapping
2.2 请求参数
2.2.1 请求方式
- Get请求
- Post请求
2.2.2 参数传递 _ GET
实例
@Controller
public class UserController {
@RequestMapping("/jkget2")
@ResponseBody
public String commonParam(String name){
System.out.println("普通参数传递 name ==> "+name);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'jkget2'}";
}
}
GET请求中文乱码
- 如果我们传递的参数中有中文,你会发现接收到的参数会出现中文乱码问题。
- 例:http://localhost/commonParam?name=张三&age=18
- 可以通过修改pom.xml来解决GET请求中文乱码问题。
<uriEncoding>UTF-8</uriEncoding>
<!--访问路径编解码字符集-->
GET中文乱码解决方案 _ 实例(pom.xml)
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port>
<path>/</path>
<uriEncoding>UTF-8</uriEncoding><!--访问路径编解码字符集-->
</configuration>
</plugin>
</plugins>
</build>
2.2.3 参数传递 _ POST
- 接受参数都一样。
- 但传递的参数中有中文,一样会出现乱码问题。
POST中文乱码解决方案 实例 配置过滤器
public class ServletContainersInitConfig extends
AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
//乱码处理、配置过滤器
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
}
2.3 五种类型参数传递
- 普通参数
- POJO类型参数
- 嵌套POJO类型参数
- 数组类型参数
- 集合类型参数
(1)普通参数
- 普通参数:url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数。
如果形参与地址参数名不一致该如何解决?
- 解决方案:使用
@RequestParam
注解。
@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(@RequestPaam("name") String
userName , int age){
System.out.println("普通参数传递 userName ==> "+userName);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'common param different name'}";
}
(2)POJO类型参数
- 后台接收参数的时候在比较复杂的情况下,可以考虑使用POJO数据类型。
- POJO参数:请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数。
//POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
System.out.println("pojo参数传递 user ==> "+user);
return "{'module':'pojo param'}";
}
注意:
- POJO参数接收,前端GET和POST发送请求数据的方式不变。
- 请求参数key的名称要和POJO中属性的名称一致,否则无法封装。
(3)嵌套POJO类型参数
- 如果实体类中有多个引用类型的属性,应该怎么搞?
- 嵌套POJO参数:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属 性参数。
- 例:
public class Address {
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
private String province;
private String city;
}
public class User {
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private String name;
private int age;
}
嵌套POJO类型参数 _ 实例
//POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
System.out.println("pojo参数传递 user ==> "+user);
return "{'module':'pojo param'}";
}
(4)数组类型参数
- 如果前端需要获取用户的爱好,爱好绝大多数情况下都是多个,如何发送请求数据和接收数据呢?
- 数组参数:请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型即可接收参数。
实例
//数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
return "{'module':'array param'}";
}
(5)集合类型参数
- 数组能接收多个值,集合也可以接收多个值。
- 但会报错,SpringMVC将List看做是一个POJO对象来处理,将其创建一个对象并准备把前端的数据封装到对象中,但是List是一个接口无法创建对象,所以报错。
解决方案 —— 使用@RequestParam注解
- 集合保存普通参数:请求参数名与形参集合对象名相同且请求参数为多个,
@RequestParam
绑定 参数关系。 - 对于简单数据类型使用数组会比集合更简单些。
//集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
System.out.println("集合参数传递 likes ==> "+ likes);
return "{'module':'list param'}";
}
(6)知识点:@RequestParam
2.4 响应json数据(常用)
- 现在比较流行的开发方式为异步调用。
- 前后台以异步方式进行交换,传输的数据使用的是JSON,所以前端如果发送的是JSON数据,后端该如何接收?
2.4.1 json普通数组
- json普通数组
(["value1","value2","value3",...])
(1)pom.xml
- SpringMVC默认使用的是jackson来处理json的转换,所以需要在pom.xml添加jackson依赖。
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
(2)PostMan发送JSON数据
["a","b","c"]
(3)开启SpringMVC注解支持 —— @EnableWebMvc
@Configuration
@ComponentScan("com.li.controller")
//开启json数据类型自动转换
@EnableWebMvc
public class SpringMvcConfig {
}
(4)参数前添加@RequestBody
//使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
System.out.println("list common(json)参数传递 list ==> "+likes);
return "{'module':'list common for json param'}";
}
2.4.2 json对象(POJ0)
(1)请求和数据的发送
{
"name":"itcast",
"age":15,
"address":{
"province":"beijing",
"city":"beijing"
}
}
(2)@RequestBody _ 后端接收数据
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
System.out.println("pojo(json)参数传递 user ==> "+user);
return "{'module':'pojo for json param'}";
}
2.4.3 json对象数组(POJ0)
- json对象数组
([{key1:value1,...},{key2:value2,...}])
- 集合中保存多个POJO该如何实现?
(1)请求和数据的发送
[
{"name":"itcast","age":15},
{"name":"itheima","age":12}
]
(2)后端接收数据
@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'}";
}
2.4.4 总结
SpringMVC接收JSON数据的实现步骤
- 导入jackson包;
- 使用PostMan发送JSON数据;
- 开启SpringMVC注解驱动,在配置类上添加@EnableWebMvc注解;
- Controller方法的参数前添加@RequestBody注解。
2.4.5 知识点(@EnableWebMvc、@RequestBody)
@RequestBody与@RequestParam区别
区别
- @RequestParam用于接收url地址传参,表单传参【application/x-www-formurlencoded】
- @RequestBody用于接收json数据【application/json】
应用
- 后期开发中,发送json格式数据为主,@RequestBody应用较广。
- 如果发送非json格式数据,选用@RequestParam接收请求参数。
2.5 日期类型参数传递
- 日期类型比较特殊,对于日期的格式有N多中输入方式。
- 针对这么多日期格式,SpringMVC该如何接收,它能很好的处理日期类型数据么?
(1)编写方法接收日期数据
- 在UserController类中添加方法,把参数设置为日期类型。
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date)
System.out.println("参数传递 date ==> "+date);
return "{'module':'data param'}";
}
(2)使用PostMan发送请求
- 略
- (使用PostMan发送GET请求,并设置date参数 http://localhost/dataParam?date=2088/08/08)
2.5.1 其他日期格式(携带两个不同的日期格式)
- 例:使用PostMan发送请求,携带两个不同的日期格式。
- http://localhost/dataParam?date=2088/08/08&date1=2088-08-08
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,Date date1)
System.out.println("参数传递 date ==> "+date);
return "{'module':'data param'}";
}
- 这个报错,报400。
- 现在传递的不符合其默认格式,SpringMVC就无法进行格式转换,所以报错。
解决方案 —— @DateTimeFormat
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
@DateTimeFormat(pattern="yyyy-MM-dd") Date date1)
System.out.println("参数传递 date ==> "+date);
System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
return "{'module':'data param'}";
}
2.5.2 携带时间的日期
- 使用PostMan发送请求,携带两个不同的日期格式。
http://localhost/dataParam?date=2088/08/08&date1=2088-08-08&date2=2088/08/08 8:08:08
- 修改UserController类,添加第三个参数。
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
@DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
@DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date
date2)
System.out.println("参数传递 date ==> "+date);
System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
System.out.println("参数传递 date2(yyyy/MM/dd HH:mm:ss) ==> "+date2);
return "{'module':'data param'}";
}
2.5.3 知识点 —— @DateTimeFormat
2.5.4 内部实现原理
(1)类型转换
- 前端传递字符串,后端使用日期Date接收
- 前端传递JSON数据,后端使用对象接收
- 前端传递字符串,后端使用Integer接收
- 后台需要的数据类型有很多中
- 在数据的传递过程中存在很多类型的转换
(2)SpringMVC是如何实现类型转换的?
- SpringMVC中提供了很多类型转换接口和实现类。
例如:
Converter接口
`HttpMessageConverter接口
类型转换器 —— Converter接口
HttpMessageConverter接口
- 该接口是实现对象与JSON之间的转换工作。
- 注意:SpringMVC的配置类把@EnableWebMvc当做标配配置上去,不要省略。
2.6 响应
2.6.1 响应页面(了解)
实例(设置返回页面)
@Controller
public class UserController {
//注意
// 1.此处不能添加@ResponseBody,如果加了该注入,会直接将page.jsp当字符串返回前端
// 2.方法需要返回String
@RequestMapping("/toJumpPage")
public String toJumpPage(){
System.out.println("跳转页面");
return "page.jsp";
}
}
2.6.2 响应数据
(1)文本数据(了解)
实例(设置返回文本内容)
@Controller
public class UserController {
@RequestMapping("/toText")
//注意此处该注解就不能省略,如果省略了,会把response text当前页面名称去查找,如果没有报404错误
@ResponseBody
public String toText(){
System.out.println("返回纯文本数据");
return "response text";
}
}
(2)json数据(对象集合转json数组)
响应POJO对象
- 返回值为实体类对象,设置返回值为实体类类型,即可实现返回对应对象的json数据,需要依赖
@ResponseBody注解
和@EnableWebMvc注解
。
@Controller
public class UserController {
@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO(){
System.out.println("返回json对象数据");
User user = new User();
user.setName("itcast");
user.setAge(15);
return user;
}
}
响应POJO集合对象
@Controller
public class UserController {
@RequestMapping("/toJsonList")
@ResponseBody
public List<User> toJsonList(){
System.out.println("返回json集合数据");
User user1 = new User();
user1.setName("lisi");
user1.setAge(15);
User user2 = new User();
user2.setName("wangwu");
user2.setAge(12);
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
return userList;
}
}
2.6.3 知识点 —— @ResponseBody
说明
- 该注解可以写在类上或者方法上;
- 写在类上就是该类下的所有方法都有@ReponseBody功能;
当方法上有@ReponseBody注解后:
- 方法的返回值为字符串,会将其作为文本内容直接响应给前端;
- 方法的返回值为对象,会将对象转换成JSON响应给前端。
此处又使用到了类型转换,内部还是通过Converter接口的实现类完成的,所以Converter除了前面 所说的功能外,它还可以实现:
- 对象转Json数据
(POJO -> json)
- 集合转Json数据
(Collection -> json)
- 对象转Json数据
Comments | NOTHING