
- 外文名
- Request
- 使用协议
- HTTP/1.1
- 请求方法
- GET
- 使用者
- 127.0.0.1
-
2021-05-21 09:12:21
@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
更多相关内容 -
@RequestBody的使用
2018-07-09 16:13:57提示:建议一定要看后面的@RequestBody的核心逻辑源码以及六个重要结论!本文前半部分的内容都是一些基 本知识常识,可选择性跳过。 声明:本文是基于SpringBoot,进行的演示说明。 基础知识介绍: @Request...提示:建议一定要看后面的@RequestBody的核心逻辑源码以及六个重要结论!本文前半部分的内容都是一些基
本知识常识,可选择性跳过。声明:本文是基于SpringBoot,进行的演示说明。
基础知识介绍:
@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);而最常用的使用请求体传参的无疑是POST请求了,所以使用@RequestBody接收数据时,一般都用POST方式进行提交。在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。
注:一个请求,只有一个RequestBody;一个请求,可以有多个RequestParam。
注:当同时使用@RequestParam()和@RequestBody时,@RequestParam()指定的参数可以是普通元素、
数组、集合、对象等等(即:当,@RequestBody 与@RequestParam()可以同时使用时,原SpringMVC接收
参数的机制不变,只不过RequestBody 接收的是请求体里面的数据;而RequestParam接收的是key-value
里面的参数,所以它会被切面进行处理从而可以用普通元素、数组、集合、对象等接收)。
即:如果参数时放在请求体中,application/json传入后台的话,那么后台要用@RequestBody才能接收到;
如果不是放在请求体中的话,那么后台接收前台传过来的参数时,要用@RequestParam来接收,或
则形参前 什么也不写也能接收。注:如果参数前写了@RequestParam(xxx),那么前端必须有对应的xxx名字才行(不管其是否有值,当然可以通
过设置该注解的required属性来调节是否必须传),如果没有xxx名的话,那么请求会出错,报400。注:如果参数前不写@RequestParam(xxx)的话,那么就前端可以有可以没有对应的xxx名字才行,如果有xxx名
的话,那么就会自动匹配;没有的话,请求也能正确发送。
追注:这里与feign消费服务时不同;feign消费服务时,如果参数前什么也不写,那么会被默认是
@RequestBody的。如果后端参数是一个对象,且该参数前是以@RequestBody修饰的,那么前端传递json参数时,必须满足以下要求:
-
后端@RequestBody注解对应的类在将HTTP的输入流(含请求体)装配到目标类(即:@RequestBody后面的类)时,会根据json字符串中的key来匹配对应实体类的属性,如果匹配一致且json中的该key对应的值符合(或可转换为),这一条我会在下面详细分析,其他的都可简单略过,但是本文末的核心逻辑代码以及几个结论一定要看! 实体类的对应属性的类型要求时,会调用实体类的setter方法将值赋给该属性。
-
json字符串中,如果value为""的话,后端对应属性如果是String类型的,那么接受到的就是"",如果是后端属性的类型是Integer、Double等类型,那么接收到的就是null。
-
json字符串中,如果value为null的话,后端对应收到的就是null。
-
如果某个参数没有value的话,在传json字符串给后端时,要么干脆就不把该字段写到json字符串中;要么写value时, 必须有值,null 或""都行。千万不能有类似"stature":,这样的写法,如:
注:关于@RequestParam()的用法,这里就不再一一说明了,可详见 《程序员成长笔记(一)》中的相关章节。
示例详细说明:
先给出两个等下要用到的实体类
User实体类:
Team实体类:
@RequestBody直接以String接收前端传过来的json数据:
后端对应的Controller:
使用PostMan测试:
@RequestBody以简单对象接收前端传过来的json数据:
后端对应的Controller:
使用PostMan测试:
@RequestBody以复杂对象接收前端传过来的json数据:
后端对应的Controller:
使用PostMan测试:
@RequestBody与简单的@RequestParam()同时使用:
后端对应的Controller:
使用PostMan测试:
@RequestBody与复杂的@RequestParam()同时使用:
后端对应的Controller:
使用PostMan测试:
@RequestBody接收请求体中的json数据;不加注解接收URL中的数据并组装为对象:
后端对应的Controller:
使用PostMan测试:
注:如果在后端方法参数前,指定了@RequestParam()的话,那么前端必须要有对应字段才行(当然可以通过设置
该注解的required属性来调节是否必须传),否者会报错;如果参数前没有任何该注解,那么前端可以传,也可
以不传,如:上图中,如果我们传参中没有指定token,那么请求能正常进去,但是token为null;如果在String token前指定了@RequestParam(“token”),那么前端必须要有token这个键时,请求才能正常进去,否者报400错误。
@RequestBody与前端传过来的json数据的匹配规则
声明:根据不同的Content-Type等情况,Spring-MVC会采取不同的HttpMessageConverter实现来进行信息转换解析。
下面介绍的是最常用的:前端以Content-Type 为application/json,传递json字符串数据;后端以@RequestBody
模型接收数据的情况。解析json数据大体流程概述:
Http传递请求体信息,最终会被封装进com.fasterxml.jackson.core.json.UTF8StreamJsonParser中(提示:Spring采用CharacterEncodingFilter设置了默认编码为UTF-8),然后在public class BeanDeserializer extends BeanDeserializerBase implements java.io.Serializable中,通过 public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) throws IOException方法进行解析。核心逻辑分析示例:
假设前端传的json串是这样的: {"name1":"邓沙利文","age":123,"mot":"我是一只小小小小鸟~"} 后端的模型只有name和age属性,以及对应的setter/getter方法;给出一般用到的deserializeFromObject(JsonParser p, DeserializationContext ctxt)方法的核心逻辑:
小技巧之指定模型中的属性对应什么key
这里简单介绍,更多的可参考:
public class BeanPropertyMap implements Iterable<SettableBeanProperty>,java.io.Serializable
给出Controller中的测试类:
给出模型中的属性(setter/getter方法没截出来):
使用postman测试一下,示例:
上图简单测试了一下,但是测得并不全面,这里就不带大家一起测试了,直接给出。
全面的结论:
结论①:@JsonAlias注解,实现:json转模型时,使json中的特定key能转化为特定的模型属性;但是模型转json时,
对应的转换后的key仍然与属性名一致,见:上图示例中的name字段的请求与响应。
以下图进一步说明:此时,json字符串转换为模型时,json中key为Name或为name123或为name的都能识别。
结论②:@JsonProperty注解,实现:json转模型时,使json中的特定key能转化为指定的模型属性;同样的,模
型转json时,对应的转换后的key为指定的key,见:示例中的motto字段的请求与响应。
以下图进一步说明:此时,json字符串转换为模型时,key为MOTTO的能识别,但key为motto的不能识别。
结论③:@JsonAlias注解需要依赖于setter、getter,而@JsonProperty注解不需要。
结论④:在不考虑上述两个注解的一般情况下,key与属性匹配时,默认大小写敏感。
结论⑤:有多个相同的key的json字符串中,转换为模型时,会以相同的几个key中,排在最后的那个key的值给模
型属性复制,因为setter会覆盖原来的值。见示例中的gender属性。结论⑥:后端@RequestBody注解对应的类在将HTTP的输入流(含请求体)装配到目标类(即:@RequestBody后面
的类)时,会根据json字符串中的key来匹配对应实体类的属性,如果匹配一致且json中的该key对应的值
符合(或可转换为)实体类的对应属性的类型要求时,会调用实体类的setter方法将值赋给该属性。^_^ 如有不当之处,欢迎指正
^_^ 代码托管链接
https://github.com/JustryDeng...RequestBody...^_^ 本文已经被收录进《程序员成长笔记(二)》,笔者JustryDeng
-
-
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-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
。但可以入参后再转换,参考如下:
@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/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中
总结 •在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
-
Request
2018-08-16 14:57:431 Request 1.1 什么是Request 代表HTTP请求的对象. 在浏览器向服务器发送请求之后, 服务器接受到请求, 在调用service方法处理请求之前, 会创建Request对象, 并把所有的请求信息( 请求行、请求头、请求实体 ) ...1 Request
1.1 什么是Request
代表HTTP请求的对象.
在浏览器向服务器发送请求之后, 服务器接受到请求, 在调用service方法处理请求之前, 会创建Request对象, 并把所有的请求信息( 请求行、请求头、请求实体 ) 全部封装到Request对象中.
1.2 Request继承关系ServletRequest(接口) 通用的Request接口, 提供了一个Request对象应该具有的功能. | |-- HttpServletRequest(接口) 继承了ServletRequest接口, 并且添加了很多和Http协议相关的方法 | |- xxRequest --> Request对象
2 Request的功能
2.1 获取客户机的基本信息、获取请求头信息
getRequestURL() – 获取浏览器发送请求的完整URL地址
getRemoteAddr() – 获取浏览器所在主机的IP地址
getMethod() – 获取请求方式
getContextPath() – 获取当前Web应用的虚拟路径
getHeader(String name) – 根据请求头的名字获取请求头信息代码示例:
//1.getRequestURL() -- 获取浏览器发送请求的完整URL地址 String url = request.getRequestURL().toString(); System.out.println("url: "+url); //2.getRemoteAddr() -- 获取浏览器所在主机的IP地址 String ip = request.getRemoteAddr(); System.out.println("ip: "+ip); //3.getContextPath() -- 动态获取当前Web应用的虚拟路径 String path = request.getContextPath(); System.out.println("path: "+path);// /day14 String method = request.getMethod(); System.out.println("method: "+method);// GET //4.getHeader() -- 获取请求头信息 String host = request.getHeader("host"); String referer = request.getHeader("Referer"); System.out.println("host: "+host); System.out.println("referer: "+referer); response.getWriter().write("RequestDemo1...");
2.2 获取请求参数
getParameter(String name) – 通过请求参数的名称获取对应的参数值
getParameterValues(String name) – 通过请求参数的名称获取对应的多个参数值所组成的数组.
getParameterMap() – 返回所有请求参数组成的map集合.
代码示例://1.获取用户名 String username = request.getParameter("username"); System.out.println("username="+username); //2.获取爱好 String[] likes = request.getParameterValues("like"); System.out.println( Arrays.toString(likes) ); //3.获取所有参数组成的map集合 Map<String, String[]> map = request.getParameterMap(); for(Map.Entry<String, String[]> entry:map.entrySet() ){ System.out.print(entry.getKey()+"="); System.out.println(Arrays.toString(entry.getValue())); }
请求参数乱码问题:
1、乱码产生的原因:编码时和解码时使用的码表不一致造成的!
(1) 编码: 浏览器发送数据给服务器需要将数据转成字节, 默认使用的编码为 UTF-8
(2) 解码: 服务器接收浏览器发送过来的数据, 将字节转回字符, 默认使用的iso885-1
由于两端使用的编码不一致因此会产生乱码!
2、解决乱码方式:
(1)根据乱码产生的原理, 手动编解码来解决乱码
代码实现:String username = request.getParameter("username"); System.out.println("解决前:username="+username);//乱码 byte[] bytes = username.getBytes("iso8859-1"); username = new String(bytes, "utf-8"); System.out.println("解决后:username="+username);//正确
(2)如果请求方式为POST提交, 可以通过一行代码搞定:
request.setCharacterEncoding("utf-8"); /* * 如果提交方式为POST提交, 可以通过下面这一行代码解决 * 乱码: 这行代码会通知服务器使用utf-8来接收请求实体 * 内容中的数据. */ String username = request.getParameter("username"); System.out.println("username="+username);
由于request.setCharacterEncoding(“utf-8”);会通知服务器使用utf-8来接收请求实体内容中的数据, 而POST方式提交的参数刚好在请求实体内容中, 所以这行代码对POST提交的参数乱码会起作用, 而GET提交的参数不在请求实体内容中, 所以这行代码对GET提交的参数乱码不会起作用!!
总结: 在解决请求参数时, 先判断请求方式, 如果是POST提交, 可以通过下面这行来搞定:
request.setCharacterEncoding("utf-8"); //注意! 这行代码必须要放在任何获取参数的代码之前执行, 否则将不会起作用!
如果是GET提交, 就需要通过手动编解码来解决乱码, 类似于下面的代码:
byte[] bytes = username.getBytes("iso8859-1");//username是乱码 username = new String(bytes, "utf-8"); System.out.println("解决后:username="+username);//正确
2.3 实现请求转发
可以实现资源的跳转,并且是服务器内部同一个Web应用的资源跳转。
(1)实现请求转发:request.getRequestDispatcher("所转发到资源的路径").forward(request, response);
注意: 转发时的路径是从Web应用的虚拟路径后面开始写!, 比如我们要转发到:
http://localhost/day14/RequestDemo4, 其中传入的路径为: /RequestDemo4
(2)请求转发的特点:
a.一次请求,一次响应
b. 地址栏地址不会发生变化(改变)
c. 转发属于服务器内部的资源跳转, 只能在同一个Web应用内部的资源之间进行跳转. 不可以在不同的Web应用或者不同的虚拟主机之间进行跳转.
(3)请求转发的细节问题:
a. 在转发之前, 如果往response缓冲区写入了数据, 但是还没有打给浏览器, 在转发时就会被清空!
b .在转发之前, 如果往response缓冲区写入了数据, 并且强制打给了浏览器, 转发将会失败!
c. 在一个资源中, 不能进行多次转发, 但是可以进行多重转发.
2.4 作为域对象使用
域对象: 如果一个对象具有一个可以被看见的(或访问的)范围, 利用该对象上提供的map集合就可以在整个范围内实现资源的共享!
域对象提供的操作数据的方法:setAttribute(String name, Object value) -- 添加一个域属性 getAttribute(String name) -- 获取一个域属性 removeAttribute(String name) -- 删除一个域属性
域对象的三大特征:
(1)生命周期: 一次请求开始时创建request对象. 一次请求结束时销毁Request对象
(2)作用范围: 整个请求链
(3)主要功能: 在整个作用范围内实现数据的共享!域对象一般都会和请求转发配合着使用, 用于将数据从某一个资源(比如Servlet)转发带到另外一个资源处(Servlet/JSP)
2.5 实现请求包含
请求包含是服务器内部的资源合并现象如果浏览器发送请求访问服务器中的A, A在处理时, 发现不能独立的处理这次请求, 需要另外一个B共同来处理请求, 此时可以在A中将B包含进来, 包含后的结果就是A+B一起来处理请求, 处理的结果也会合并在一起, 一起发送给浏览器.
实现代码:response.getWriter().write("<p>Demo8...before...</p>"); //将Demo9包含进来和当前Servlet一起来处理请求 request.getRequestDispatcher("/RequestDemo9").include(request,response); response.getWriter().write("<p>Demo8...after...</p>");
-
Spring Boot当中获取request的三种方式
2022-03-27 15:30:05本篇博客主要记录request相关知识,也是开发当中经常遇到的,感兴趣的跟小编一起学习吧! -
Request介绍
2019-09-15 23:54:36request和response是服务器创建的两个对象给我们使用,request封装了浏览器发送过来的所有数据,如果是获取浏览器发送过来的信息那么就找request对象,如果想告诉浏览器展示信息那么就找response对象; 1.2 Requst... -
request和response的区别!!!
2020-05-18 19:20:36文章目录一、request和response介绍二、request对象(一)获取请求参数(二)实现请求转发(三)作为域对象使用(四)案例:模拟查询所有门店功能三、response对象(一)向客户端发送数据(二)实现重定向 ... -
urllib.request.urlopen详解
2021-08-06 23:29:39urllib.request 请求模块 urllib.error 异常处理模块 urllib.parse url解析模块 urllib.robotparser robots.txt解析模块 python2中urllib2库中的很多方法在python3中被移至urllib.request库中。 urllib.request.... -
request用法以及详解
2019-07-04 19:50:501request概述 request是Servlet.service()方法的一个参数,类型为javax.servlet.http.HttpServletRequest。在客户端发出每个请求时,服务器都会创建一个request对象,并把请求数据封装到request中,然后在调用... -
Pull Request 与 Merge Request 的区别
2020-05-12 08:00:00点击上方“前端技术砖家”关注这篇文章只为说明一个问题:“Pull Request 与 Merge Request 有什么区别?”在我的想象中,有一双滑板鞋~不好意思,跑偏了。在我的想象... -
urllib.request详细介绍
2019-03-24 15:18:46参考博客原址:https://blog.csdn.net/bo_mask/article/details/76067790在Python2版本中,有urllib和urlib2两个库可以用来实现request的发送。而在Python3中,已经不存在urllib2这个库了,统一为urllib。Python3 ... -
文件上传报错:Current request is not a multipart request
2022-04-21 09:08:29文件上传报错:Current request is not a multipart request -
el-upload使用http-request自定义上传和进度条实战
2021-09-24 09:05:09项目中发现使用默认的el-upload上传动作发送上传请求的时候不会带上请求头,于是想通过自定义请求也就是http-request来自定义上传。实践证明这条路是通的,不过有个小问题就是原本上传的进度条没了。于是搞一个... -
request
2018-08-13 16:29:21request简介 request 是一个http的客户端,支持https。 安装 npm i request -D 使用 const request = require('request'); request.get(url,{params,headers}, (err, response, body) => { ... -
AjaxRequest(Ajax使用包)
2011-10-21 16:53:02Ajax开发包Ajax开发包Ajax开发包Ajax开发包Ajax开发包Ajax开发包Ajax开发包Ajax开发包Ajax开发包Ajax开发包 -
@RequestBody原理
2021-01-27 15:50:25这个其实是SpringMVC中做的一个处理机制,在整个SpringMVC的处理流程中,会通过HandlerMethod来代理每个Map后的controller和method,在通过反射invoke method的过程中,会解析request来获得arguments,而@RequestBo -
修改request请求参数
2021-02-13 00:28:31本质上来讲,request请求当中的参数是无法更改的,也不能添加或者删除;但在后台程序中,一般对request的参数的操作,都是通过request的getParameter、getParameterNames、getParameterValues等方法执行的;所以我们... -
[HTTP] 回顾Request请求信息数据
2021-04-08 12:47:34request 对象和 response 对象的原理 request 和 response 对象是由服务器创建的。接着我们来使用它们 request 对象是来获取请求消息,response 对象是来设置响应消息 其基本原理,如下图 ???? request 对象继承... -
python的request库详细讲解、七个方法、举例子爬取
2021-09-30 08:47:28目录准备库、测试安装request库启动idle测试百度网页,打印出来Requests库的7个主要方法(前言)request.get(url)Request库的2个重要对象Response对象的属性实际的例子爬取网页的通用代码框架Requests库的异常提供了... -
request接口测试
2021-06-07 19:39:55content 以字节形式(二进制)返回 Request扩充 1 :添加等待时间 requests.get(url,timeout=1) # 超过等待时间则报错 2 :添加请求头信息 requests.get(url,headers=headers) # 设置请求头 3 :添加文件 requests.... -
nodejs request模块
2021-03-12 09:50:30文章目录nodejs request模块什么是npm 包 requestnpm安装request和使用demo1: 检测rinkeby 网络是否正常 nodejs request模块 什么是npm 包 request 相信 Node.js 开发者对 Request 都不会陌生,这是一个 Node.js ... -
Python 中request数据的获取
2021-04-27 01:12:17@app.route('/users', methods=['GET', '..."print(request.data)//同:request.get_data()print(request.json)如何获取request的参数在于客户端请求头Headers中参数:Content-Type的设置以及传参的方式一、Conte... -
golang NewRequest gorequest 实现http请求
2020-11-21 12:38:043.gorequest 通过go语言实现http请求 1.http.Post import ( "net/http" "net/url" ) data := url.Values{"start":{"100"}, "hobby":{"xxxx"}} body := strings.NewReader(data.Encode()) resp, err := ... -
Request请求转发详解
2020-07-07 16:16:46直接来,RequestDemo5代码,get请求和post请求都请求转发了,转发到RequestDemo6请求 RequestDemo5代码 package com.lingaolu.request; import javax.servlet.RequestDispatcher; import javax.servlet.... -
Python Flask中Request请求
2019-06-27 16:29:00Request是个对象,不管是Python还是Java,虽然request这个对象可能叫的名字不一样,(在其他语言中可能叫HttpRequest)。 当客户端浏览器去访问一个www.baidu.com地址时,Http协议会向服务器传递一个request对象。... -
springboot接口多次获取request中的body内容
2020-12-29 19:23:212.3.1 继承HttpServletRequestWrapper包装类,每次读取body后,再将参数写会request 2.3.2 将包装类加入过滤器链 3. 参考资料 1. 概述 在使用springboot开发接口时,会将参数转化为Bean,用来进行参数的自动校验... -
Postman报:400 Bad Request
2022-03-07 16:52:39Postman报:400 Bad Request 1、Postman请求并没有请求到后台Api(由于语法错误,服务器无法理解请求); 2、入参出错范围:cookie、header、body、form-data、x-www-form-urlencoded、属性未加引号、Url路径有中文... -
thinkphp6 请求(request)变量
2019-11-11 08:55:32可以通过Request对象完成全局输入变量的检测、获取和安全过滤,支持包括$_GET、$_POST、$_REQUEST、$_SERVER、$_SESSION、$_COOKIE、$_ENV等系统变量,以及文件上传信息。 检测变量是否设置 可以使用has方法来检测... -
SpringMVC+ajax上传文件+提交表单数据报错The current request is not a multipart request
2019-09-24 10:52:18``` @RequestMapping(value = "contact" ,method = RequestMethod.POST) @ResponseBody public Dto contact( MultipartFile file, DbBusinessInformation businessInformation, HttpServletRequest request)...