精华内容
下载资源
问答
  • @RequestBody和@RequestParam的使用
    2022-04-08 16:19:18

    @RequestBody
    @RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。

    @RequestBody接收的参数是来自requestBody中,即请求体。一般用于处理非 Content-Type: application/x-www-form-urlencoded编码格式的数据,比如:application/json、application/xml等类型的数据。

    GET请求中,因为没有HttpEntity,所以@RequestBody并不适用。

    POST请求中,通过HttpEntity传递的参数,必须要在请求头中声明数据的类型Content-Type,SpringMVC通过使用HandlerAdapter 配置来解析HttpEntity中的数据,然后绑定到相应的bean上。

    如果前端向后端传递的是非实体类对象,后台也可以使用@RequestBody注解,那就用List<Map<String, String>>来接收

    @RequestParam
    用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容。(Http协议中,如果不指定Content-Type,则默认传递的参数就是application/x-www-form-urlencoded类型)

    POST类型和GET类型都可以使用@RequestParam注解来接收参数

    @RequestParam注解有三个参数

    required 表示是否必须,默认为 true,必须。

    defaultValue 可设置请求参数的默认值,如果设置了该值,required=true将失效,自动为false,如果没有传该参数,就使用默认值。

    value 为接收url的参数名(相当于key值)。

    举例:

    //一下两种写法效果一模一样
    @RequestParam("") 或 @RequestParam(value="")
    
    //当配置多个属性的时候
    @RequestParam(value="", required=true, defaultValue="")
        
    //如果使用下面这种方式接值,那么前台穿过来的参数名称就要和inputStr一样,这里才能接收到
    @RequestParam String inputStr
        
    //但是如果加上value属性的话,那么前台传过来的参数名称就要和value属性中的一致才能接收到
    @RequestParam(value="aa") String inputStr  
        
    //如果加上required属性,当required=true就是必须要传参值过来, 当required=false表示不传的话,会给参数赋值为null
    @RequestParam(value="aa", required=true)
    
    //有一种特殊情况是参数为int类型时,设置required=false后参数不传值得话会给int类型参数赋值为null,而int是基本数据类型不能赋值为null,所以会报错,此时要将int类型改为Integer类型
    @RequestParam(value="inputInt", required=false) int inputInt  
    

    @RequestParam接收对象类型
    这里举个栗子

    实体类是People属性如下

    private String name; //姓名
    private int age; //年龄
    private String sex;  //性别
    

    前台代码(拿JSP举例)

    <input type="text" value="黑黑" name="name">
    <input type="text" value="18"  name="age">
    <input type="text" value="男"  name="sex"> 
    

    后台代码

    int addPeople(@RequestParam People people) {}
    //这时候使用@RequestParam注解修饰参数 只要前台传的参数名称和people类中的属性名一致就可以自动封装进People实体类
    

    这里我又想到一个问题,加和不加@RequestParam参数有什么区别呢?
    其实不加@RequestParam参数也没问题(此时的参数名称要和前台传过来的参数名称保持一致),也可以接收到前台传过来的参数,当前台没有传值时接收到的为null,只不过使用@RequestParam是为了用它里面的一些属性,比如默认值或required属性。

    总结
    Post请求接收@RequestBody修饰的参数和@RequestParam修饰的参数,而Get请求则只能接收@RequestParam修饰的参数。
    如果前端传的是Json类型的对象,后台就要使用@RequestBody修饰的实体类接收,如果是单个属性就使用@RequestParam修饰的变量或实体类接收

    更多相关内容
  • POST、GET、@RequestBody和@RequestParam区别

    万次阅读 多人点赞 2019-08-15 21:26:43
    注解@RequestParam接收的参数是来自requestHeader中,即请求头。 RequestParam可以接受简单类型的属性,也可以接受对象类型。 @RequestParam有三个配置参数: required 表示是否必须,默认为 true,必须。 ...

    @RequestParam

    注解@RequestParam接收的参数是来自HTTP请求体或请求url的QueryString中。

    RequestParam可以接受简单类型的属性,也可以接受对象类型。

    @RequestParam有三个配置参数:

    • required 表示是否必须,默认为 true,必须。
    • defaultValue 可设置请求参数的默认值。
    • value 为接收url的参数名(相当于key值)。

    @RequestParam用来处理 Content-Typeapplication/x-www-form-urlencoded 编码的内容,Content-Type默认为该属性。@RequestParam也可用于其它类型的请求,例如:POST、DELETE等请求

    所以在postman中,要选择body的类型为 x-www-form-urlencoded,这样在headers中就自动变为了 Content-Type : application/x-www-form-urlencoded 编码格式。如下图所示:

    但是这样不支持批量插入数据啊,如果改用 json 字符串来传值的话,类型设置为 application/json,点击发送的话,会报错,后台接收不到值,为 null

    但可以入参后再转换,参考如下:

       @PostMapping("/ali-receive")
        public void aliReceive(@RequestParam("message") String message) {
                    ReceiveLog receiveLog = JSON.parseObject(message, ReceiveLog.class);
    
        }

    解决Spring/SpringBoot @RequestParam注解无法读取application/json格式数据:https://blog.csdn.net/weixin_42536015/article/details/106906055

    @RequestParam 接受JSON的字符串:https://blog.csdn.net/qq_40470612/article/details/104225419

     

    不推荐使用@RequestParam接收application/json,这时候就需要使用到@RequestBody。

     

    @RequestBody


    注解@RequestBody接收的参数是来自requestBody中,即请求体。一般用于处理非 Content-Type: application/x-www-form-urlencoded编码格式的数据,比如:application/jsonapplication/xml等类型的数据。

    application/json类型的数据而言,使用注解@RequestBody可以将body里面所有的json数据传到后端,后端再进行解析。

    GET请求中,因为没有HttpEntity,所以@RequestBody并不适用。

    POST请求中,通过HttpEntity传递的参数,必须要在请求头中声明数据的类型Content-Type,SpringMVC通过使用

    HandlerAdapter 配置的HttpMessageConverters来解析HttpEntity中的数据,然后绑定到相应的bean上。

     

    向表中批量插入数据

    举个批量插入数据的例子,Controller层的写法如下图所示:

    由于@RequestBody可用来处理 Content-Typeapplication/json 编码的内容,所以在postman中,选择body的类型为row -> JSON(application/json),这样在 Headers 中也会自动变为 Content-Type : application/json 编码格式。body内的数据如下图所示:

    批量向表中插入两条数据,这里的 saveBatchNovel()方法已经封装了 JPAsaveAll() 方法。body 里面的 json 语句的 key 值要与后端实体类的属性一一对应。

    注意:前端使用$.ajax的话,一定要指定 contentType: "application/json;charset=utf-8;",默认为 application/x-www-form-urlencoded

    后端解析json数据

    上述示例是传递到实体类中的具体写法,那么如果传递到非实体类中,body里面的json数据需要怎么解析呢?我们再来看下面这个例子:

    在body中,我们还是输入上面的json数据,根据分析,上面的json数据是一个List数组内嵌套着map对象,那么在后台的接收形式可写为 List<Map<String, String>>,具体代码如下图所示:

    postman请求:

    控制台输出:

    得出结论,通过@RequestBody可以解析Body中json格式的数据。

     

     

    POST请求时

    @RequestBody --> JSON字符串部分

    @RequestParam --> 请求参数部分

    application/json格局图

    form-data、x-www-form-urlencoded格局图

     

    1、从content-type方面总结:

    ① form-data、x-www-form-urlencoded:不可以用@RequestBody;可以用@RequestParam。见postman的格局,这两种方式的时候没有json字符串部分。

    ② application/json:json字符串部分可以用@RequestBody;url中的?后面参数可以用@RequestParam。见postman的格局

     

    2、从两种注解方式总结:

    @RequestBody

    (@RequestBody Map map)
    (@RequestBody Object object)
    application/json时候可用
    form-data、x-www-form-urlencoded时候不可用
    

    @RequestParam

    (@RequestParam Map map)
    application/json时候,json字符串部分不可用,url中的?后面添加参数即可用,form-data、x-www-form-urlencoded时候可用,但是要将Headers里的Content-Type删掉
    
    (@RequestParam String waterEleId,@RequestParam String enterpriseName)
    application/json时候,json字符串部分不可用,url中的?后面添加参数即可用
    form-data、x-www-form-urlencoded时候可用,且参数可以没有顺序(即前端传过来的参数或者url中的参数顺序不必和后台接口中的参数顺序一致,只要字段名相同就可以),但是要将Headers里的Content-Type删掉
    
    (@RequestParam Object object)
    不管application/json、form-data、x-www-form-urlencoded都不可用
    

    既不是@RequestBody也不是@RequestParam,没有指定参数哪种接收方式

    (Map map)
    (Object object)
    application/json时候:json字符串部分不可用,url中的?后面添加参数不可用。
    因为没有指定,它也不知道到底是用json字符串部分还是?后面添加参数部分,所以干脆都不可以用
    form-data、x-www-form-urlencoded时都不可用,见图二
    
    (HttpServletRequest request)
    application/json不可用
    form-data、x-www-form-urlencoded时可用
    

    GET请求

    @RequestBody

    RequestBody -- Map / Object
    GET请求中不可以使用@RequestBody
    

    @RequestParam

    (@RequestParam Map map)
    在url中的?后面添加参数即可使用
    
    (@RequestParam String waterEleId,@RequestParam String enterpriseName)
    在url中的?后面添加参数即可使用
    
    (@RequestParam Object object)
    GET请求中不可以使用
    

    当使用GET请求时,通过postman添加?后面的参数,不用在url中自己一个一个拼,点击Params,在下面key-value中输入就自动拼接到url中

     

     

    举栗子

    上传文件,包含了图中圈出来的两部分

    如果这样,没有@RequestParam,那么url?后的参数就拿不到

    @RequestMapping(value = "/leadingIn", method = RequestMethod.POST)
        public ResponseObj<Boolean> leadingIn(Map formData,
                                              HttpServletRequest request,
                                              Map<String, InputStream> files) {
    }
    

    如果control中这样接收,本来想formData只接收url?后的参数,结果将{ "retCode": null, "data": true }这部分内容也拿到了,真实意外之喜。字符串这部分内容还可以从request中取到,见下面完整方法。

    @RequestMapping(value = "/leadingIn", method = RequestMethod.POST)
        public ResponseObj<Boolean> leadingIn(@RequestParam Map formData,
                                              HttpServletRequest request,
                                              Map<String, InputStream> files) {
    }
    

    完整方法

        /**
         * 导入
         */
        @RequestMapping(value = "/leadingIn", method = RequestMethod.POST)
        public ResponseObj<Boolean> leadingIn(@RequestParam Map formData,
                                              HttpServletRequest request,
                                              Map<String, InputStream> files) {
            //测试
            try {
                MultipartHttpServletRequest mulRequest = (MultipartHttpServletRequest) request;
                Set<Map.Entry<String, MultipartFile>> set = mulRequest.getFileMap().entrySet();
                Map<String, InputStream> listFile = new LinkedHashMap<>();
                System.out.println("个数" + set.size());
                for (Map.Entry<String, MultipartFile> each : set) {
                    String fileName = each.getKey();
                    MultipartFile file = each.getValue();
                    //这里需要上传FTP
                    try {
                        listFile.put(fileName, file.getInputStream());
                    } catch (Exception ex) {
                        return new ResponseObj<>(false, null);
                    }
                }
    
                String formjson = mulRequest.getParameter("content");
                ObjectMapper mapper = new ObjectMapper();
                mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
                mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    
    //            boolean result = iInstallWorkOrder.upLoadFile(listFile);
                boolean result = true;
    
                return new ResponseObj<>(result, null);
            } catch (Exception ex) {
                System.out.println(ex.toString());
                return new ResponseObj<>(false, null);
            }
    
        }



    按F12看一下Network里对应请求:

    使用@RequestParam:Content-Type为application/x-www-form-urlencoded,参数在FormData中



    使用@RequestBody:Content-Type为application/json,参数在Request PayLoad中


    总结 •在GET请求中,不能使用@RequestBody。 •在POST请求,可以使用@RequestBody和@RequestParam,但是如果使用@RequestBody,对于参数转化的配置必须统一。
    可以使用多个@RequestParam获取数据,@RequestBody不可以 举个例子,在SpringMVC配置了HttpMessageConverters处理栈中,指定json转化的格式,如Date转成‘yyyy-MM-dd’,则参数接收对象包含的字段如果是Date类型,就只能让客户端传递年月日的格式,不能传时分秒。因为不同的接口,它的参数可能对时间参数有不同的格式要求,所以这样做会让客户端调用同事对参数的格式有点困惑,所以说扩展性不高。 如果使用@RequestParam来接受参数,可以在接受参数的model中设置@DateFormat指定所需要接受时间参数的格式。 另外,使用@RequestBody接受的参数是不会被Servlet转化统一放在request对象的Param参数集中,@RequestParam是可以的。

     

    另外,还有一种应用场景,接口规范为resultful风格时,举个例子:如果要获取某个id下此条问题答案的查询次数的话,则后台就需要动态获取参数,其注解为@PathVariable,并且requestMapping中的value应为value="/{id}/queryNum",截图如下:

     

    参考:

    @RequestParam @RequestBody @PathVariable 等参数绑定注解详解

    https://blog.csdn.net/walkerjong/article/details/7946109

    https://my.oschina.net/u/3372000/blog/906217

    https://www.jianshu.com/p/4981911d5e15

    https://cloud.tencent.com/developer/article/1414464

    展开全文
  • @RequestBody和@RequestParam区别全面详细

    千次阅读 2021-05-21 09:12:21
    注解@RequestParam接收的参数是来自requestHeader中,即请求头。 RequestParam可以接受简单类型的属性,也可以接受对象类型。 @RequestParam有三个配置参数: required 表示是否必须,默认为 true,必须。 default...

    @RequestParam

    注解@RequestParam接收的参数是来自requestHeader中,即请求头。

    RequestParam可以接受简单类型的属性,也可以接受对象类型。

    @RequestParam有三个配置参数:

    required 表示是否必须,默认为 true,必须。
    defaultValue 可设置请求参数的默认值。
    value 为接收url的参数名(相当于key值)。

    @RequestParam用来处理 Content-Type 为 application/x-www-form-urlencoded 编码的内容,Content-Type默认为该属性。@RequestParam也可用于其它类型的请求,例如:POST、DELETE等请求。

    所以在postman中,要选择body的类型为 x-www-form-urlencoded,这样在headers中就自动变为了 Content-Type : application/x-www-form-urlencoded 编码格式。
    但是这样不支持批量插入数据啊,如果改用 json 字符串来传值的话,类型设置为 application/json,点击发送的话,会报错,后台接收不到值,为 null。

    这时候,注解@RequestBody就派上用场了。继续往下看

    @RequestBody

    注解@RequestBody接收的参数是来自requestBody中,即请求体。一般用于处理非 Content-Type: application/x-www-form-urlencoded编码格式的数据,比如:application/json、application/xml等类型的数据。

    就application/json类型的数据而言,使用注解@RequestBody可以将body里面所有的json数据传到后端,后端再进行解析。

    GET请求中,因为没有HttpEntity,所以@RequestBody并不适用。

    POST请求中,通过HttpEntity传递的参数,必须要在请求头中声明数据的类型Content-Type,SpringMVC通过使用

    HandlerAdapter 配置的HttpMessageConverters来解析HttpEntity中的数据,然后绑定到相应的bean上。

    向表中批量插入数据

    举个批量插入数据的例子,Controller层的写法如下图所示:

    由于@RequestBody可用来处理 Content-Type 为 application/json 编码的内容,所以在postman中,选择body的类型为row -> JSON(application/json),这样在 Headers 中也会自动变为 Content-Type : application/json 编码格式。body内的数据如下图所示:

    批量向表中插入两条数据,这里的 saveBatchNovel()方法已经封装了 JPA的 saveAll() 方法。body 里面的 json 语句的 key 值要与后端实体类的属性一一对应。

    注意:前端使用$.ajax的话,一定要指定 contentType: “application/json;charset=utf-8;”,默认为 application/x-www-form-urlencoded。

    后端解析json数据

    上述示例是传递到实体类中的具体写法,那么如果传递到非实体类中,body里面的json数据需要怎么解析呢?我们再来看下面这个例子:

    在body中,我们还是输入上面的json数据,根据分析,上面的json数据是一个List数组内嵌套着map对象,那么在后台的接收形式可写为 List<Map<String, String>>,具体代码如下图所示:

    postman请求:

    控制台输出:

    得出结论,通过@RequestBody可以解析Body中json格式的数据。

    ?
    ?

    POST请求时

    @RequestBody --> JSON字符串部分

    @RequestParam --> 请求参数部分

    application/json格局图

    form-data、x-www-form-urlencoded格局图

    ?

    1、从content-type方面总结:

    ① form-data、x-www-form-urlencoded:不可以用@RequestBody;可以用@RequestParam。见postman的格局,这两种方式的时候没有json字符串部分。

    ② application/json:json字符串部分可以用@RequestBody;url中的?后面参数可以用@RequestParam。见postman的格局

    ?

    2、从两种注解方式总结:

    @RequestBody
    (@RequestBody Map map)
    (@RequestBody Object object)
    application/json时候可用
    form-data、x-www-form-urlencoded时候不可用
    
    @RequestParam
    (@RequestParam Map map)
    application/json时候,json字符串部分不可用,url中的?后面添加参数即可用,form-data、x-www-form-urlencoded时候可用,但是要将Headers里的Content-Type删掉
    
    (@RequestParam String waterEleId,@RequestParam String enterpriseName)
    application/json时候,json字符串部分不可用,url中的?后面添加参数即可用
    form-data、x-www-form-urlencoded时候可用,且参数可以没有顺序(即前端传过来的参数或者url中的参数顺序不必和后台接口中的参数顺序一致,只要字段名相同就可以),但是要将Headers里的Content-Type删掉
    
    (@RequestParam Object object)
    不管application/json、form-data、x-www-form-urlencoded都不可用
    
    既不是@RequestBody也不是@RequestParam,没有指定参数哪种接收方式
    (Map map)
    (Object object)
    application/json时候:json字符串部分不可用,url中的?后面添加参数不可用。
    因为没有指定,它也不知道到底是用json字符串部分还是?后面添加参数部分,所以干脆都不可以用
    form-data、x-www-form-urlencoded时都不可用,见图二
    
    (HttpServletRequest request)
    application/json不可用
    form-data、x-www-form-urlencoded时可用
    

    GET请求

    @RequestBody
    RequestBody -- Map / Object
    GET请求中不可以使用@RequestBody
    
    @RequestParam
    (@RequestParam Map map)
    在url中的?后面添加参数即可使用
    
    (@RequestParam String waterEleId,@RequestParam String enterpriseName)
    在url中的?后面添加参数即可使用
    
    (@RequestParam Object object)
    GET请求中不可以使用
    

    当使用GET请求时,通过postman添加?后面的参数,不用在url中自己一个一个拼,点击Params,在下面key-value中输入就自动拼接到url中

    举列子
    上传文件,包含了图中圈出来的两部分

    如果这样,没有@RequestParam,那么url?后的参数就拿不到

    @RequestMapping(value = "/leadingIn", method = RequestMethod.POST)
        public ResponseObj<Boolean> leadingIn(Map formData,
                                              HttpServletRequest request,
                                              Map<String, InputStream> files) {
    }
    

    如果control中这样接收,本来想formData只接收url?后的参数,结果将{ “retCode”: null, “data”: true }这部分内容也拿到了,真实意外之喜。字符串这部分内容还可以从request中取到,见下面完整方法。

    @RequestMapping(value = "/leadingIn", method = RequestMethod.POST)
        public ResponseObj<Boolean> leadingIn(@RequestParam Map formData,
                                              HttpServletRequest request,
                                              Map<String, InputStream> files) {
    }
    
    完整方法
     /**
         * 导入
         */
        @RequestMapping(value = "/leadingIn", method = RequestMethod.POST)
        public ResponseObj<Boolean> leadingIn(@RequestParam Map formData,
                                              HttpServletRequest request,
                                              Map<String, InputStream> files) {
            //测试
            try {
                MultipartHttpServletRequest mulRequest = (MultipartHttpServletRequest) request;
                Set<Map.Entry<String, MultipartFile>> set = mulRequest.getFileMap().entrySet();
                Map<String, InputStream> listFile = new LinkedHashMap<>();
                System.out.println("个数" + set.size());
                for (Map.Entry<String, MultipartFile> each : set) {
                    String fileName = each.getKey();
                    MultipartFile file = each.getValue();
                    //这里需要上传FTP
                    try {
                        listFile.put(fileName, file.getInputStream());
                    } catch (Exception ex) {
                        return new ResponseObj<>(false, null);
                    }
                }
    
                String formjson = mulRequest.getParameter("content");
                ObjectMapper mapper = new ObjectMapper();
                mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
                mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    
    //            boolean result = iInstallWorkOrder.upLoadFile(listFile);
                boolean result = true;
    
                return new ResponseObj<>(result, null);
            } catch (Exception ex) {
                System.out.println(ex.toString());
                return new ResponseObj<>(false, null);
            }
    
        }
    

    按F12看一下Network里对应请求:

    使用@RequestParam:Content-Type为application/x-www-form-urlencoded,参数在FormData中

    使用@RequestBody:Content-Type为application/json,参数在Request PayLoad中

    总结

    1.  在GET请求中,不能使用@RequestBody
    2. 在POST请求,可以使用@RequestBody和@RequestParam,但是如果使用@RequestBody,对于参数转化			 的配置必须统一。
    3. 可以使用多个@RequestParam获取数据,@RequestBody不可以 
    
    3.1标题举个例子
    	在SpringMVC配置了HttpMessageConverters处理栈中,指定json转化的格式,如Date转成‘yyyy-MM-dd’,则参数接收对象包含的字段如果是Date类型,就只能让客户端传递年月日的格式,不能传时分秒。因为不同的接口,它的参数可能对时间参数有不同的格式要求,所以这样做会让客户端调用同事对参数的格式有点困惑,所以说扩展性不高。 如果使用@RequestParam来接受参数,可以在接受参数的model中设置@DateFormat指定所需要接受时间参数的格式。 另外,使用@RequestBody接受的参数是不会被Servlet转化统一放在request对象的Param参数集中,@RequestParam是可以的。 
    4. 另外,还有一种应用场景,接口规范为resultful风格时,举个例子:如果要获取某个id下此条问题答案的查询次数的话,则后台就需要动态获取参数,其注解为@PathVariable,并且requestMapping中的value应为value="/{id}/queryNum",
    

    参考:

    @RequestParam @RequestBody @PathVariable 等参数绑定注解详解

    https://blog.csdn.net/walkerjong/article/details/7946109

    https://my.oschina.net/u/3372000/blog/906217

    https://www.jianshu.com/p/4981911d5e15

    https://cloud.tencent.com/developer/article/1414464

    展开全文
  • @RequestParam 注解@RequestParam接收的参数是来自HTTP请求体或请求url的QueryString中。 RequestParam可以接受简单类型的属性,也可以接受对象类型。 @RequestParam有三个配置参数: required表示是否必须,...

    @RequestParam

    注解@RequestParam接收的参数是来自HTTP请求体或请求url的QueryString中。

    RequestParam可以接受简单类型的属性,也可以接受对象类型。

    @RequestParam有三个配置参数:

    • required 表示是否必须,默认为 true,必须。
    • defaultValue 可设置请求参数的默认值。
    • value 为接收url的参数名(相当于key值)。

    @RequestParam用来处理 Content-Type 为 application/x-www-form-urlencoded 编码的内容,Content-Type默认为该属性。@RequestParam也可用于其它类型的请求,例如:POST、DELETE等请求

    所以在postman中,要选择body的类型为 x-www-form-urlencoded,这样在headers中就自动变为了 Content-Type : application/x-www-form-urlencoded 编码格式。如下图所示:

    但是这样不支持批量插入数据啊,如果改用 json 字符串来传值的话,类型设置为 application/json,点击发送的话,会报错,后台接收不到值,为 null

    但可以入参后再转换,参考如下:

     
    1. @PostMapping("/ali-receive")

    2. public void aliReceive(@RequestParam("message") String message) {

    3. ReceiveLog receiveLog = JSON.parseObject(message, ReceiveLog.class);

    4.  
    5. }

    解决Spring/SpringBoot @RequestParam注解无法读取application/json格式数据:https://blog.csdn.net/weixin_42536015/article/details/106906055

    @RequestParam 接受JSON的字符串:https://blog.csdn.net/qq_40470612/article/details/104225419

     

    不推荐使用@RequestParam接收application/json,这时候就需要使用到@RequestBody。

     

    @RequestBody


    注解@RequestBody接收的参数是来自requestBody中,即请求体。一般用于处理非 Content-Type: application/x-www-form-urlencoded编码格式的数据,比如:application/jsonapplication/xml等类型的数据。

    application/json类型的数据而言,使用注解@RequestBody可以将body里面所有的json数据传到后端,后端再进行解析。

    GET请求中,因为没有HttpEntity,所以@RequestBody并不适用。

    POST请求中,通过HttpEntity传递的参数,必须要在请求头中声明数据的类型Content-Type,SpringMVC通过使用

    HandlerAdapter 配置的HttpMessageConverters来解析HttpEntity中的数据,然后绑定到相应的bean上。

     

    向表中批量插入数据

    举个批量插入数据的例子,Controller层的写法如下图所示:

    由于@RequestBody可用来处理 Content-Type 为 application/json 编码的内容,所以在postman中,选择body的类型为row -> JSON(application/json),这样在 Headers 中也会自动变为 Content-Type : application/json 编码格式。body内的数据如下图所示:

    批量向表中插入两条数据,这里的 saveBatchNovel()方法已经封装了 JPA的 saveAll() 方法。body 里面的 json 语句的 key 值要与后端实体类的属性一一对应。

    注意:前端使用$.ajax的话,一定要指定 contentType: "application/json;charset=utf-8;",默认为 application/x-www-form-urlencoded

    后端解析json数据

    上述示例是传递到实体类中的具体写法,那么如果传递到非实体类中,body里面的json数据需要怎么解析呢?我们再来看下面这个例子:

    在body中,我们还是输入上面的json数据,根据分析,上面的json数据是一个List数组内嵌套着map对象,那么在后台的接收形式可写为 List<Map<String, String>>,具体代码如下图所示:

    postman请求:

    控制台输出:

    得出结论,通过@RequestBody可以解析Body中json格式的数据。

     

     

    POST请求时

    @RequestBody --> JSON字符串部分

    @RequestParam --> 请求参数部分

    application/json格局图

    form-data、x-www-form-urlencoded格局图

     

    1、从content-type方面总结:

    ① form-data、x-www-form-urlencoded:不可以用@RequestBody;可以用@RequestParam。见postman的格局,这两种方式的时候没有json字符串部分。

    ② application/json:json字符串部分可以用@RequestBody;url中的?后面参数可以用@RequestParam。见postman的格局

     

    2、从两种注解方式总结:

    @RequestBody

     
    1. (@RequestBody Map map)

    2. (@RequestBody Object object)

    3. application/json时候可用

    4. form-data、x-www-form-urlencoded时候不可用

    @RequestParam

     
    1. (@RequestParam Map map)

    2. application/json时候,json字符串部分不可用,url中的?后面添加参数即可用,form-data、x-www-form-urlencoded时候可用,但是要将Headers里的Content-Type删掉

     
    1. (@RequestParam String waterEleId,@RequestParam String enterpriseName)

    2. application/json时候,json字符串部分不可用,url中的?后面添加参数即可用

    3. form-data、x-www-form-urlencoded时候可用,且参数可以没有顺序(即前端传过来的参数或者url中的参数顺序不必和后台接口中的参数顺序一致,只要字段名相同就可以),但是要将Headers里的Content-Type删掉

     
    1. (@RequestParam Object object)

    2. 不管application/json、form-data、x-www-form-urlencoded都不可用

    既不是@RequestBody也不是@RequestParam,没有指定参数哪种接收方式

     
    1. (Map map)

    2. (Object object)

    3. application/json时候:json字符串部分不可用,url中的?后面添加参数不可用。

    4. 因为没有指定,它也不知道到底是用json字符串部分还是?后面添加参数部分,所以干脆都不可以用

    5. form-data、x-www-form-urlencoded时都不可用,见图二

    6.  
    7. (HttpServletRequest request)

    8. application/json不可用

    9. form-data、x-www-form-urlencoded时可用

    GET请求

    @RequestBody

     
    1. RequestBody -- Map / Object

    2. GET请求中不可以使用@RequestBody

    @RequestParam

     
    1. (@RequestParam Map map)

    2. 在url中的?后面添加参数即可使用

     
    1. (@RequestParam String waterEleId,@RequestParam String enterpriseName)

    2. 在url中的?后面添加参数即可使用

     
    1. (@RequestParam Object object)

    2. GET请求中不可以使用

    当使用GET请求时,通过postman添加?后面的参数,不用在url中自己一个一个拼,点击Params,在下面key-value中输入就自动拼接到url中

     

     

    举栗子

    上传文件,包含了图中圈出来的两部分

    如果这样,没有@RequestParam,那么url?后的参数就拿不到

     
    1. @RequestMapping(value = "/leadingIn", method = RequestMethod.POST)

    2. public ResponseObj<Boolean> leadingIn(Map formData,

    3. HttpServletRequest request,

    4. Map<String, InputStream> files) {

    5. }

    如果control中这样接收,本来想formData只接收url?后的参数,结果将{ "retCode": null, "data": true }这部分内容也拿到了,真实意外之喜。字符串这部分内容还可以从request中取到,见下面完整方法。

     
    1. @RequestMapping(value = "/leadingIn", method = RequestMethod.POST)

    2. public ResponseObj<Boolean> leadingIn(@RequestParam Map formData,

    3. HttpServletRequest request,

    4. Map<String, InputStream> files) {

    5. }

    完整方法

     
    1. /**

    2. * 导入

    3. */

    4. @RequestMapping(value = "/leadingIn", method = RequestMethod.POST)

    5. public ResponseObj<Boolean> leadingIn(@RequestParam Map formData,

    6. HttpServletRequest request,

    7. Map<String, InputStream> files) {

    8. //测试

    9. try {

    10. MultipartHttpServletRequest mulRequest = (MultipartHttpServletRequest) request;

    11. Set<Map.Entry<String, MultipartFile>> set = mulRequest.getFileMap().entrySet();

    12. Map<String, InputStream> listFile = new LinkedHashMap<>();

    13. System.out.println("个数" + set.size());

    14. for (Map.Entry<String, MultipartFile> each : set) {

    15. String fileName = each.getKey();

    16. MultipartFile file = each.getValue();

    17. //这里需要上传FTP

    18. try {

    19. listFile.put(fileName, file.getInputStream());

    20. } catch (Exception ex) {

    21. return new ResponseObj<>(false, null);

    22. }

    23. }

    24.  
    25. String formjson = mulRequest.getParameter("content");

    26. ObjectMapper mapper = new ObjectMapper();

    27. mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

    28. mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    29.  
    30. // boolean result = iInstallWorkOrder.upLoadFile(listFile);

    31. boolean result = true;

    32.  
    33. return new ResponseObj<>(result, null);

    34. } catch (Exception ex) {

    35. System.out.println(ex.toString());

    36. return new ResponseObj<>(false, null);

    37. }

    38.  
    39. }



    按F12看一下Network里对应请求:

    使用@RequestParam:Content-Type为application/x-www-form-urlencoded,参数在FormData中



    使用@RequestBody:Content-Type为application/json,参数在Request PayLoad中


    总结 •在GET请求中,不能使用@RequestBody。 •在POST请求,可以使用@RequestBody和@RequestParam,但是如果使用@RequestBody,对于参数转化的配置必须统一。
    可以使用多个@RequestParam获取数据,@RequestBody不可以 举个例子,在SpringMVC配置了HttpMessageConverters处理栈中,指定json转化的格式,如Date转成‘yyyy-MM-dd’,则参数接收对象包含的字段如果是Date类型,就只能让客户端传递年月日的格式,不能传时分秒。因为不同的接口,它的参数可能对时间参数有不同的格式要求,所以这样做会让客户端调用同事对参数的格式有点困惑,所以说扩展性不高。 如果使用@RequestParam来接受参数,可以在接受参数的model中设置@DateFormat指定所需要接受时间参数的格式。 另外,使用@RequestBody接受的参数是不会被Servlet转化统一放在request对象的Param参数集中,@RequestParam是可以的。

     

    另外,还有一种应用场景,接口规范为resultful风格时,举个例子:如果要获取某个id下此条问题答案的查询次数的话,则后台就需要动态获取参数,其注解为@PathVariable,并且requestMapping中的value应为value="/{id}/queryNum",截图如下:

     

    展开全文
  • 在不使用注解的情况下,相当于默认使用了RequestParam里的数据 (这种理解是错误的,真实的原因参考下面段落 有一个有趣的现象 ),而且可以自动封装为对象模型,没有的数据也不会报错,而是设为0值 post请求时,...
  • @RequestBody @RequestBody接收的参数是来自请求体,一般处理application/json、...对于Post请求,可以使用@RequestBody和@RequestParm。但是如果使用@RequestBody对于参数的转化的配置必须统一。 可以使用多个
  • @RequestParam和@RequestBody这两个注解是可以同时使用的。 网上有很多博客说@RequestParam @RequestBody不能同时使用,这是错误的。根据HTTP协议,并没有说post请求不能带URL参数,经验证往一个带有参数的URL发送...
  • 在后端接收的方法里@RequestBody可以@RequestParam同时使用,但一个方法里,@RequestBody只能有一个,@RequestParam可以有多个。@RequestParam使用在GET请求方式中,可以接收普通元素、数组、
  • @RequestParam 注解@RequestParam接收的参数是请求行URL的param 与 请求体中的param。 RequestParam可以接受简单类型的属性,也可以接受对象类型。 @RequestParam有三个配置参数: required 表示是否必须,默认为 ...
  • @RequestBody和@RequestParam的区别与用法

    千次阅读 2020-12-10 13:04:56
    通过查阅资料发现: 尽管@RequestParam和@RequestBody都能接收Post方式请求传来的数据,但是@RequestParam不能接收json字符串,而@RequestBody能。 @RequestBody不能接收form-data类型的内容,@RequestParam能。后来...
  • 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。 使用时机:返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等...
  • @RequestBody和@RequestParam区别与用法1.@RequestBody1.1 简介1.2 例子2. @RequestParam2.1 简介2.2 例子 观前提示: 本文所使用的,IDEA版本为ultimate 2019.1,JDK版本为1.8.0_141,Tomcat版本为9.0.12。 1.@...
  • 在此之前,我一直搞不清楚@RequestBody和@RequestParam到底有什么作用,在很多时候我发现即使我在controller中设置@RequestBody和@RequestParam或者不设置这些,依然能够接收到请求参数,但在某些情况下他们又行不通...
  • @RequestBody 前台的Content-Type必须要改为application/json,我们使用该注解将所有参数转换,在代码部分在一个个取出来,也是目前我使用到最多的注解来获取参数。 @RequestHeader 获取头信息里的值 @Cookie
  • 在不使用注解的情况下,相当于默认使用了RequestParam里的数据 (这种理解是错误的,真实的原因参考下面段落 有一个有趣的现象 ),而且可以自动封装为对象模型,没有的数据也不会报错,而是设为0值 post请求时,...
  • 1.spring的RequestParam注解接收的...password=456,而RequestBody注解接收的参数则是来自于requestBody中,即请求体中。2.如果是从js通过ajax请求传送json字符串到controller层,在接受数据的形参用@RequestBody...
  • 请求方式为get请求时,不可以使用@RequestBody接收参数,会报错 请求方式为post请求时,不可以使用@RequestParam接收参数,会报错 @PathVariable是restful的风格 @GetMapping(value = "/{id}") public String add...
  • 1.@RequestBody 使用此注解接收参数时,适用于请求体格式为 application/json,只能用对象接收 2.@RequestParam 接收的参数是来自HTTP 请求体 或 请求url 的QueryString中 只能用来接收基本数据类型、String 或者...
  • 关于@Requestbody和@Requestparam同时使用

    千次阅读 2020-09-11 08:36:33
    其实data依然为@RequestBody所读取的内容,而url可以通过?的方式来传递参数给@RequestParam 参考:https://blog.csdn.net/qqnbsp/article/details/79892500
  • @RequestParam 用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容。(Http协议中,如果不指定Content-... RequestParam可以接受简单类型的属性,也可以接受对象类型。 实质是将Request.g...
  • @RequestBody和@RequestParam

    2021-01-13 14:44:31
    在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。 注:一个请求,只有一个RequestBody;一个请求,可以有多个RequestPara
  • data中的对象中的所有值都会被认为是@Requestbody中的内容, 这样会造成@RequestBody解析错误, 而@RequestParam获取不到值, 所以在传值时使用以下方式, data中放对象,而单个的参数在url中传 1. 传值 : $http({ ...
  • 不过,当前的大多数浏览器只支持GETPOST,Spring 3.0提供了一个HiddenHttpMethodFilter,允许你通过“_method”的表单参数指定这些特殊的HTTP方法(实际上还是通过POST提交表单)。服务端配置了HiddenHttpMethod
  • 客户端@RequestParam注解的value属性必须指定值,不能为空,且要服务端接口参数名保持一致 如果需要传递多个字符串参数,则使用多个@RequestParam注解与服务端接口参数保持一一对应即可 服务端 @ResponseBody @...
  • @RequestParam 注解@RequestParam接收的参数是来自HTTP请求体或请求url的QueryString中。 RequestParam可以接受简单类型的属性,也可以接受对象类型。 @RequestParam有三个配置参数: required 表示是否必须,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 41,575
精华内容 16,630
关键字:

@requestbody和@requestparam