• Spring4MVC 请求参数映射和Content-type


    前言

    对于spring的controller方法参数映射,常用的注解有@RequestParam, @PathVariable, @RequestBody。另外不使用注解,请求参数也能够自动映射到方法形参上。到底有什么区别呢,
    什么情况下该使用什么注解呢,本文做一个简单总结,不涉及源码,只是使用总结。使用的spring4版本为最新的 4.3.24.RELEASE

    不使用注解(不传则为null)

    基本数据类型和日期类型

    不用注解,springmvc可以自动的将请求参数映射到同名的方法形参上,get请求和post请求都可以。
    ** 默认情况下,传入的日期类型必须为 yyyy/MM/dd HH:mm:ss 格式。例如 2018/12/21 17:01:12 **

    • get请求(Content-Type : application/x-www-form-urlencoded)

    get请求

    • post 请求(Content-Type : application/x-www-form-urlencoded)
      post请求
      方法代码
    @RequestMapping(value = "getNoAnno")
        @ResponseBody
        public String getNoAnno(String name, String sex, Integer age, Date createTime) {
            System.out.println(name);
            System.out.println(sex);
            System.out.println(age);
            System.out.println(createTime == null ? null : DateUtils.dateToString(createTime, "yyyy-MM-dd HH:mm:ss"));
            return "success";
        }
    

    但是有时候我们需要传入的日期格式是这样的yyyy-MM-dd HH:mm:ss ,怎么处理呢,只要在对应的参数上加上 **@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") ** 注解
    不过需要注意的是,pattern如果设置为yyyy-MM-dd HH:mm:ss,那么传入的参数必须严格遵守这个格式,例如传入 ‘2019-12-02’,就会报错。
    反而pattern如果设置为yyyy-MM-dd,传入的实际值如果含有时间信息,则时间信息会被忽略掉,例如传入 ‘2019-02-12 12:02:21’, 后面的时间信息会被忽略,服务器得到的时间是 2019-02-12 00:00:00

    @RequestMapping(value = "getNoAnno")
        @ResponseBody
        public String getNoAnno(String name, String sex, Integer age, @DateTimeFormat(pattern = "yyyy-MM-dd") Date createTime) {
            System.out.println(name);
            System.out.println(sex);
            System.out.println(age);
            System.out.println(createTime == null ? null : DateUtils.dateToString(createTime, "yyyy-MM-dd HH:mm:ss"));
            return "success";
        }
    

    自定义类型POJO

    不用注解,springmvc可以自动的将请求参数映射到pojo类的同名属性上,get请求和post请求都可以。
    这种情况要求POJO的属性值与参数名一一对应。例如一个简单的Pojo类:User.java

    public class User {
        private String name;
    
        private Integer age;
    
        private String sex;
    
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        // DateTimeFormat注解用于处理Date类型参数转换,如果不加这个注解,那么请求参数必须是 yyyy/MM/dd HH:mm:ss 格式的,加了之后请求参数就需要 yyyy-MM-dd HH:mm:ss 格式了
        private Date createTime;
        ...
    
    

    controller 方法代码

    
        @RequestMapping("withNoAnnoModel")
        @ResponseBody
        public String withNoAnnoModel(User user) {
            if (user == null) {
                System.out.println("user is null");
            } else {
                System.out.println(user.getName() + ":" + user.getSex() + ":" + user.getAge() + ":" + user.getCreateTime());
            }
            return "success";
        }
    
    • get 请求
      get请求

    • post 请求
      post请求

    @PathVariable注解

    @PathVariable 注解用于url参数上,get和post请求参数支持。

    @RequestMapping("withPathVariable/{type}/{id}")
        @ResponseBody
        public String withPathVariable(@PathVariable("type") String type, @PathVariable("id") Integer id) {
            System.out.println(type + ": " + id);
            return "success";
        }
    

    @RequestParam 注解

    @RequestParam注解可以把request.getParameter()获取的参数转换为我们需要的方法形参,也就是说它可以把get请求?后面携带的key=value形式的参数绑定到方法形参上,也支持post请求body里
    的请求参数,但目前我发现它只能对于基本数据类型,String和Date类型进行绑定,自定义类型好像不行(也有可能是我自己没找对方法,欢迎评论指出),如果要使用自定义类型,可以不加注解
    @RequestParam 有一个name属性,如果请求参数和方法形参不一致,可以通过name属性进行调整,例如@RequestParam ("dateStr") String date, 前端传过来的dateStr属性就会映射到方法的date形参上
    @RequestParam有一个required属性,表示是否必须,默认为true。也就是说前端如果没有传这个参数过来,会报错 Required ** parameter is not present
    手动设置为false就可以了,不传则为null

    @RequestMapping("withRequestParam")
        @ResponseBody
        public String withRequestParam1(@RequestParam String name, @RequestParam String sex, @RequestParam Integer age, @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date createTime) {
            System.out.println(name, "null");
            System.out.println(sex, "null");
            System.out.println(age, null);
            System.out.println(createTime == null ? null : DateUtils.dateToString(createTime, "yyyy-MM-dd HH:mm:ss"));
            return "success";
        }
    
    • get 请求
      get请求
    • post 请求
      post

    @RequestBody注解

    该注解用于读取Request请求的body部分数据(由此,get请求不适用该注解),使用系统配置的HttpMessageConverter进行解析,然后把相应的数据绑定到方法形参上
    常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,比如说:application/json或者是application/xml等。一般情况下来说常用其来处理application/json类型。

    对于日期类型的处理,默认情况下Date类型要求传入的参数格式为: yyyy/MM/dd HH:mm:ss 格式,在PoJo类的date属性上添加@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    注解,可以指定传入的参数格式。
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")

    @RequestMapping("withjsonModel")
        @ResponseBody
        public String withjsonModel(@RequestBody User user) {
            if (user == null) {
                System.out.println("user is null");
            } else {
                System.out.println(user.getName() + ":" + user.getSex() + ":" + user.getAge() + ":" + user.getCreateTime());
            }
            return "success";
        }
    

    复杂对象Array,List,Map

    复合对象的话,直接用.号连接,List的话用[]来表示下标,map类型的话用 [] 来包裹键
    User.java

    public class User {
        private String name;
    
        private Integer age;
    
        private String sex;
    
        private Address address;
    
        private List<String> ids;
    
        private Map<String, Object> params;
        ... get setter方法
    }
    

    Address.java

    public class Address {
        private String area;
    
        private String code;
    
        private String street;
    

    controller方法代码

     @RequestMapping("complexModel")
        @ResponseBody
        public String complexModel(User user) {
            System.out.println(user.getName());
            System.out.println(user.getParams());
            System.out.println(user.getIds());
            System.out.println(user.getAddress().getArea());
            System.out.println(user.getAddress().getStreet());
            System.out.println(user.getAddress().getCode());
            return "success";
        }
    // 输出信息
    12lsf
    {key1=value1, key2=value2}
    [1, 2]
    浙江省
    西湖区
    123123
    

    get请求
    http://127.0.0.1:8080/admin/user/complexModel?name=12lsf&age=12&sex=1&ids[0]=1&ids[1]=2&params[key1]=value1&params[key2]=value2&address.area=浙江省&address.street=西湖区&address.code=123123

  • 相关阅读:
    静态INCLUDE与动态INCLUDE的区别
    SQL注入
    SpringMVC
    设计模式—七大原则
    Demo小细节-2
    Java运算符
    Java内部类的基本解析
    接口类和抽象类
    Statement和PreparedStatement
    ArrayList,LinkedLIst,HashMap
  • 原文地址:https://www.cnblogs.com/liu-shijun/p/11004210.html
Copyright © 2020-2023  润新知