POST、GET、@RequestBody和@RequestParam区别_requestbodyutil.getvalue-程序员宅基地

技术标签: Java基础  

@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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_38004638/article/details/99655322

智能推荐

友华光猫超级密码获取——PT622&PT632_pt622g超级密码-程序员宅基地

文章浏览阅读4.8w次,点赞5次,收藏14次。前言上上周家里宽带升级成了200M,原有的100M光猫不能用了,电信公司给换上了一个新的1000M光猫,同时也将网络连接方式给从原来的光猫桥接改成光猫路由了,这让我自己的小服务器顿时与外界失去联系了。于是想进入光猫管理界面把连接方式修改回来,哪曾想进去后根本没有发现修改页面,好吧,知道是电信公司搞得鬼,我需要扒掉电信公司给带的套,无套作业才爽嘛。_pt622g超级密码

解决idea 2020.2版本安装jclasslib无法使用_jclasslib-bytecode-viewer插件没用-程序员宅基地

文章浏览阅读2.1k次,点赞5次,收藏5次。使用jclasslib不光可以直观地查看某个类对应的字节码文件,还可以查看类的基本信息、常量池、接口、属性、函数等信息。使用idea自带插件下载的方式安装在这就不说啦……网络上一大堆啦……说说我遇到的问题:我的idea版本是2020.2的,使用插件市场下载jclasslib后,点击view只有show Bytecode,没有JClasslib我怀疑应该是我的idea版本和插件的版本不太兼容,或者是新版的插件有其他更改导致然后找到了插件官网https://plugins.je..._jclasslib-bytecode-viewer插件没用

深色地图_科技公司如何使用“深色图案”来欺骗您-程序员宅基地

文章浏览阅读108次。深色地图Websites like Amazon, Facebook, and Google don’t just appear: people make them. Everything about their design is intentional, is serving some kind of purpose—and sometimes those designs deliberate..._深色地图如何制作

软件测试常用方法实例与分析_软件测试如何找测试点实例分析-程序员宅基地

文章浏览阅读5.9k次。软件测试常用方法总结实例分析_软件测试如何找测试点实例分析

Golang 判断数组某个元素是否存在 (isset)_golang isset-程序员宅基地

文章浏览阅读3.9w次。如,现在需要判断命令行是否传了参数,即os.Args[1] 是否存在如果使用下述的判断:package mainimport ( "fmt" "os")func main() { if os.Args[1] != "" { fmt.Println("aaa") } else { fmt.Println("bbb") } }会报错:index out ..._golang isset

使用AI预测北京房价:Bj_HousePricePredict项目解析与实践-程序员宅基地

文章浏览阅读352次,点赞5次,收藏3次。使用AI预测北京房价:Bj_HousePricePredict项目解析与实践项目地址:https://gitcode.com/xiaoyusmd/Bj_HousePricePredict项目简介Bj_HousePricePredict 是一个基于Python的数据挖掘和机器学习项目,其主要目标是通过分析历史数据来预测北京市的房价。该项目包含了数据预处理、特征工程、模型训练与验证等多个环节,提...

随便推点

类模板的分离编译问题_seqlist后为什么加<datatype>-程序员宅基地

文章浏览阅读199次。类模板的分离编译类模板的分离编译,即模板类的定义和其模板成员函数(接口)的定义不在同一文件中。如模板类的定义在.h头文件中,同时在.h头文件中声明接口,而在模板类之外的.cpp文件中定义接口。此时在main函数中,如果只引用.h头文件,编译会报错。原因:大多数编译器,不支持类模板的分离编译!(1)实现分离编译其实也可以实现分离编译。解决办法:在main函数中引用定义接口的.cpp文件,这时..._seqlist后为什么加

利用JavaFx开发windows应用程序 —— 界面篇-程序员宅基地

文章浏览阅读3.1k次。为什么80%的码农都做不了架构师?>>> ..._javafx打印界面

[转]ALSA --- amixer控制声卡驱动实现Line-in功能_amixer scontrols寻找name-程序员宅基地

文章浏览阅读1.3k次。ALSA --- amixer控制声卡驱动实现Line-in功能_amixer scontrols寻找name

main方法参数疑问_一个类example的main()方法的参数是args-程序员宅基地

文章浏览阅读2k次。今天在网上看到一个这样的题目(如下),在我的能力范围之内,我认为此题选择C项,可是答案是D,我不明白原因,求大神帮忙啊。。。一个类Example的main()方法的参数是args,类被如下调用执行:java Example cat main方法中访问args[0]的输出是什么?A、catB、ExampleC、javaD、NullPointerException异常_一个类example的main()方法的参数是args

项目总结——基于WebGL的点云全景可视化_webgl 大量点云处理-程序员宅基地

文章浏览阅读1.6w次,点赞12次,收藏47次。1.项目简介这个项目是我2016年研一上学期的个人项目,目的是使用webgl在浏览器端渲染点云和全景数据,要求流畅高效,能够实现海量点云和全景数据的可视化,以及基于点云的简单量测功能(使用ThreeJS库,也涉及到简单的前端、数据库知识)。这个项目是在我的本科毕业设计的基础上进行的,本科毕设做的是基于webgl的点云可视化(点云网络可视化示例),研一上做的是用多分辨率八叉树建立点云索引,并增加_webgl 大量点云处理

[angular + ngzorro报错]the icon appstore-o does not exist or is not registered._uncaught error: [@ant-design/icons-angular]:the ic-程序员宅基地

文章浏览阅读846次。原因是在build项目的时候找不到路径导致的解决方案在angular.js 中加入 { "glob": "**/*", "input": "./node_modules/@ant-design/icons-angular/src/inline-svg/", "output": "/assets/" }..._uncaught error: [@ant-design/icons-angular]:the icon user-o does not exist o

推荐文章

热门文章

相关标签