做为一个常年提供各类Http接口的后端而言,如何获取请求参数能够说是一项基本技能了,本篇为《190824-SpringBoot系列教程web篇之Get请求参数解析姿式汇总》以后的第二篇,对于POST请求方式下,又能够怎样获取请求参数呢java
本篇主要内容包括如下几种姿式git
<!-- more -->github
首先得搭建一个web应用才有可能继续后续的测试,借助SpringBoot搭建一个web应用属于比较简单的活;web
建立一个maven项目,pom文件以下spring
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.7</version> <relativePath/> <!-- lookup parent from update --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-cloud.version>Finchley.RELEASE</spring-cloud.version> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </pluginManagement> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>
添加项目启动类Application.cass
json
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class); } }
在演示请求参数的解析实例中,咱们使用终端的curl命令来发起http请求(主要缘由是截图上传太麻烦,仍是终端的文本输出比较方便;缺点是不太直观)vim
接下来咱们正式进入参数解析的妖娆姿式篇,会介绍一下常见的一些case(并不能说包含了全部的使用case)后端
下面全部的方法都放在 ParamPostRest
这个Controller中bash
@RestController @RequestMapping(path = "post") public class ParamPostRest { }
在正式介绍以前,强烈推荐看一下《190824-SpringBoot系列教程web篇之Get请求参数解析姿式汇总》, 由于get传参的姿式,在post参数解析中一样适用,下面的内容并不会再次详细介绍app
首先看一下最基本的使用case,和get请求里的case同样,咱们先开一个接口
@PostMapping(path = "req") public String requestParam(HttpServletRequest req) { return JSONObject.toJSONString(req.getParameterMap()); }
咱们测试下两种post请求下,会出现怎样的结果
# 常规的表单提交方式 # content-type: application/x-www-form-urlencoded ➜ ~ curl 'http://127.0.0.1:8080/post/req' -X POST -d 'name=yihui&age=18' {"name":["yihui"],"age":["18"]}% # json传提交 ➜ ~ curl 'http://127.0.0.1:8080/post/req' -X POST -H 'content-type:application/json;charset:UTF-8' -d '{"name": "yihui", "age": 20}' {}%
从上面的case中能够知道,经过传统的表达方式提交的数据时,获取参数和get获取参数使用姿式同样;然而固然传入的是json串格式的数据时,直接经过javax.servlet.ServletRequest#getParameter
获取不到对应的参数
咱们经过debug,来看一下在传json串数据的时候,若是咱们要获取数据,能够怎么作
上面截图演示了咱们从请求的InputStream中获取post参数;因此再实际使用的时候须要注意,流中的数据只能读一次,读完了就没了; 这个和咱们使用GET传参是有很大的差异的
注意:若是您有一个打印请求参很多天志的切面,在获取post传的参数时须要注意,是否是把流的数据读了,致使业务中没法获取到正确的数据!!!
上面说到传json串数据时,后端直接经过HttpServletRequest
获取数据不太方便,那么有更优雅的使用姿式么?下面咱们看一下@RequestBody
注解的使用
@Data public class BaseReqDO implements Serializable { private static final long serialVersionUID = 8706843673978981262L; private String name; private Integer age; private List<Integer> uIds; } @PostMapping(path = "body") public String bodyParam(@RequestBody BaseReqDO req) { return req == null ? "null" : req.toString(); }
只须要在参数中添加@RequestBody
注解便可,而后这个接口就支持json串的POST提交了
# json串数据提交 ➜ ~ curl 'http://127.0.0.1:8080/post/body' -X POST -H 'content-type:application/json;charset:UTF-8' -d '{"name": "yihui", "age": 20}' BaseReqDO(name=yihui, age=20, uIds=null)% # 表单数据提交 ➜ ~ curl 'http://127.0.0.1:8080/post/body' -X POST -d 'name=yihui&age=20' {"timestamp":1566987651551,"status":415,"error":"Unsupported Media Type","message":"Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported","path":"/post/body"}%
说明:使用@RequestBody
注解以后,可解析提交的json串;但再也不支持表单提交参数方式(application/x-www-form-urlencoded
)
使用RequestEntity来解析参数,可能并不太常见,它用来解析json串提交的参数也比较合适,使用姿式也比较简单
@PostMapping(path = "entity") public String entityParam(RequestEntity requestEntity) { return Objects.requireNonNull(requestEntity.getBody()).toString(); }
使用case以下
# json串数据提交 ➜ ~ curl 'http://127.0.0.1:8080/post/entity' -X POST -H 'content-type:application/json;charset:UTF-8' -d '{"name": "yihui", "age": 20}' {name=yihui, age=20}% # 表单数据提交不行 ➜ ~ curl 'http://127.0.0.1:8080/post/entity' -X POST -d 'name=yihui&age=19' {"timestamp":1566988137298,"status":415,"error":"Unsupported Media Type","message":"Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported","path":"/post/entity"}%
文件上传也是一个比较常见的,支持起来也比较简单,有两种方式,一个是使用MultipartHttpServletRequest参数来获取上传的文件;一个是借助 @RequestParam
注解
private String getMsg(MultipartFile file) { String ans = null; try { ans = file.getName() + " = " + new String(file.getBytes(), "UTF-8"); } catch (IOException e) { e.printStackTrace(); return e.getMessage(); } System.out.println(ans); return ans; } /** * 文件上传 * * curl 'http://127.0.0.1:8080/post/file' -X POST -F 'file=@hello.txt' * * @param file * @return */ @PostMapping(path = "file") public String fileParam(@RequestParam("file") MultipartFile file) { return getMsg(file); } @PostMapping(path = "file2") public String fileParam2(MultipartHttpServletRequest request) { MultipartFile file = request.getFile("file"); return getMsg(file); }
测试case以下
# 建立一个文本文件 ➜ ~ vim hello.txt hello, this is yhh's spring test! # 使用curl -F 实现文件上传,注意使用姿式 ➜ ~ curl 'http://127.0.0.1:8080/post/file' -F 'file=@hello.txt' file = hello, this is yhh's spring test! ➜ ~ curl 'http://127.0.0.1:8080/post/file2' -F 'file=@hello.txt' file = hello, this is yhh's spring test!
上面介绍的几种有别于GET篇中的请求姿式,请注意GET请求参数的解析方式,在POST请求中,可能也是适用的,为何说可能?由于在post请求中,不一样的content-type
,对参数的解析影响仍是有的;
须要注意的是,对于传统的表单提交(application/x-www-form-urlencoded)方式,post的参数解析依然可使用
尽信书则不如,以上内容,纯属一家之言,因我的能力有限,不免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激
下面一灰灰的我的博客,记录全部学习和工做中的博文,欢迎你们前去逛逛