• 灵活运用的@RequestParam和@RequestBody


    最近在编写项目的过程中,老出现前后端传递参数格式不一致、不统一的问题,对于一个已经快工作一年的Java程序员来说,实属不合格,所以我就下来好好研究了一下@RequestParam和@RequestBody的区别,避免大家遭遇同等错误;

    一 @RequestParam注解

    @Target(ElementType.PARAMETER)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface RequestParam {
    
    	/**
    	 * 参数名称(和value同等意思)
    	 */
    	@AliasFor("name")
    	String value() default "";
    
    	/**
    	 * 参数名称 (和name同等意思)
    	 */
    	@AliasFor("value")
    	String name() default "";
    
    	/**
    	 * 是否必选(默认必选)
    	 */
    	boolean required() default true;
    
    	/**
    	 * 参数默认值
    	 */
    	String defaultValue() default ValueConstants.DEFAULT_NONE;
    
    }
    

    (1)@RequestParam总体上来说,该注解类拥有三个参数:

      a)value、name 属性都标识请求参数名(必须配置);

      b)required:参数是否必传,默认为 true,可以设置为非必传 false;(如果设置了必传或默认,请求未传递参数,将会抛出异常);

      c)defaultValue:参数默认值,如果设置了该值,required 将会自动设置为 false;

    (2)@RequestParam注解获取的参数放在请求哪?

      a)get请求的 requestHeaders 中 content-type 这个字段,使用 form-data 表单形式携带参数请求;

      b)Spring中的@RequestParam注解接收的参数大多数场景是来自requestHeaders中,即请求头,也就是url中,格式为:http://localhost:8080?name=yc&age=23,由于 url 长度有限制,所以参数需要限制数量和值得长度;

    (3)如何使用:

      使用一:利用Postman工具,使用form-data提交Get请求

      

      执行代码:

    @RequestMapping(value = "/test", method = RequestMethod.GET)
        public void test(@RequestParam("id") Integer id,
                         @RequestParam("name") String name,
                         @RequestParam("age") Integer age) {
            log.info("id = {}, name = {}, age = {}", id, name, age);
        }
    

      结果:

    id = 1, name = yc, age = 23
    

      使用二:不使用@RequestParam注解直接进行对象属性赋值(不推荐使用,容易和@ReuqestBody混淆)

      代码执行:

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        private Integer id;
        private String name;
        private Integer age;
    }
    
    @RequestMapping(value = "/test", method = RequestMethod.GET)
        public void test(User user) {
            log.info("id = {}, name = {}, age = {}", user.getId(), user.getName(), user.getAge());
        }

      结果:

    id = 1, name = yc, age = 23

    (4)使用场景:

      a)请求是为了查找资源,获取服务器数据;

      b)请求结果无持续性的副作用,例如:不会对数据库进行添加、修改、删除操作;

      c)传入的参数不会太长,因为Get请求可能会产生很长的URL,或许会超过某些浏览器与服务器对URL的长度限制,导致请求失败;

     二、@RequestBody注解

    @Target(ElementType.PARAMETER)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface RequestBody {
    
    	/**
    	 * 默认参数必传
    	 */
    	boolean required() default true;
    
    }
    

    (1)@RequestBody注解只拥有一个参数:

      required 默认为 true,即对象中的属性必须有一个要传,否则会抛出异常:org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing

    (2)@RequestBody注解获取的参数在请求哪?

      a)post请求的requestHeaders请求头中有content-type字段,一般用来处理:applicatin/json格式的参数;

      b)Spring中的@RequestBody注解是用来接收请求体中的参数数据,即requestBody请求体中,故不受参数数据长度的限制;

    (3)如何使用?

      使用Postman工具发送json格式的数据:

      

      执行代码:

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        private Integer id;
        private String name;
        private Integer age;
    
    }
    
    @RequestMapping(value = "/test", method = RequestMethod.POST)
        public void test(@RequestBody User user) {
            log.info("id = {}, name = {}, age = {}", user.getId(), user.getName(), user.getAge());
        }
    

      结果:

    id = 1, name = yc, age = 23
    

    (4)使用场景:

      a)请求的结果有持续性作用,例如:对数据库添加、更新、删除操作;

      b)若使用Get请求,表单参数过长;

      c)要传送的数据不是采用7位的ASCII编码;

    测试三:使用Post请求,@RequestParam也可以接收参数;

      注意:也可以使用这种方式用,发送Post请求,参数拼接到url之后,这是因为协议之间没有做严格的区分,但这种方式不建议使用,这种方式就使用Get方式即可。例如:localhost:8888/optimus-prime/project/test?id=1&name=yc&age=23 使用浏览器请求数据,这种方式Get请求,但后端使用Post方式接收,访问不成功!

      

      执行代码:

        @PostMapping(value = "/test")
        public void test(@RequestParam("id") Integer id,
                         @RequestParam("name") String name,
                         @RequestParam("age") Integer age) {
            log.info("id = {}, name = {}, age = {}", id, name, age);
        }
    

      结果:

    id = 1, name = yc, age = 12
    

    额外知识1:Http协议常用的四种请求方式:Post、Get、Put、Delete等;其中Put、Delete请求方式很少见,都可用Post方式代替!

      a)对数据库而言: get 请求不修改数据库,只是查询。Post是增加记录,put是更新,Delete数据库删除;

      b)Put,Post,Delete 方式的请求参数会直接放在requestBody里;

      c)处理 request uri 部分的注解,路径参数变量:@PathVariable;

      d)处理request header部分的注解:   @RequestHeader, @CookieValue,@RequestParam;

      e)处理request body部分的注解:@RequestParam, @RequestBody;  

    综上所述:@RequestParam注解既可以接收Get方式的请求头中的参数,也可以接收Post方式的请求体中的参数;

    额外知识2:get请求的 headers 中没有 content-type 这个字段,post 的 content-type 有 :

      a)application/x-www-form-urlencoded  这种就是一般的文本表单用 post 传地数据,只要将得到的 data 用 @RequestParam 或 request.getParamter() 获取即可;

      b)multipart/form-data ,用于文件上传,此时 form 的 enctype 属性必须指定为 multipart/form-data;

      c)application/json,将数据以json对象的格式传递;

      d)text/xml;

      e)put 和 delete 请求的headers 是有 content-type 这个字段的,只不过这两个方法类型目前不常用;

    每天进步一点点,开心!  

      

  • 相关阅读:
    Deepin Linux下安装安卓应用的各种方式
    win下的终端使用指南
    IDEA自定义TODO
    WSL的ssh-agent问题
    MySQL数据类型
    MySQL常用命令.md
    Period 时间坑
    exp/imp管理
    expdp和impdp管理(逻辑导入导出)
    同义词
  • 原文地址:https://www.cnblogs.com/blogtech/p/11172168.html
Copyright © 2020-2023  润新知