做爲一個常年提供各類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或者有更好的建議,歡迎批評指正,不吝感激
下面一灰灰的我的博客,記錄全部學習和工做中的博文,歡迎你們前去逛逛