springMvc _ 请求与响应


请求与响应

其他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 问题

实例

@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 解决优化方案

@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类型参数 _ 实例

  • 注意:请求参数key的名称要和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)

  • json对象({key1:value1,key2:value2,...})

(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发送请求

2.5.1 其他日期格式(携带两个不同的日期格式)

@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)

声明:三二一的一的二|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - springMvc _ 请求与响应


三二一的一的二