溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何解析Post請(qǐng)求參數(shù)

發(fā)布時(shí)間:2021-10-20 16:25:46 來(lái)源:億速云 閱讀:945 作者:柒染 欄目:大數(shù)據(jù)

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)如何解析Post請(qǐng)求參數(shù),文章內(nèi)容豐富且以專(zhuān)業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

作為一個(gè)常年提供各種Http接口的后端而言,如何獲取請(qǐng)求參數(shù)可以說(shuō)是一項(xiàng)基本技能了,本篇為《190824-SpringBoot系列教程web篇之Get請(qǐng)求參數(shù)解析姿勢(shì)匯總》之后的第二篇,對(duì)于POST請(qǐng)求方式下,又可以怎樣獲取請(qǐng)求參數(shù)呢

本篇主要內(nèi)容包括以下幾種姿勢(shì)

  • @RequestBody json格式

  • RequestEntity

  • MultipartFile 文件上傳

<!-- more -->

I. 環(huán)境搭建

首先得搭建一個(gè)web應(yīng)用才有可能繼續(xù)后續(xù)的測(cè)試,借助SpringBoot搭建一個(gè)web應(yīng)用屬于比較簡(jiǎn)單的活;

創(chuàng)建一個(gè)maven項(xiàng)目,pom文件如下

<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>

添加項(xiàng)目啟動(dòng)類(lèi)Application.cass

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}

在演示請(qǐng)求參數(shù)的解析實(shí)例中,我們使用終端的curl命令來(lái)發(fā)起http請(qǐng)求(主要原因是截圖上傳太麻煩,還是終端的文本輸出比較方便;缺點(diǎn)是不太直觀)

II. POST請(qǐng)求參數(shù)解析

接下來(lái)我們正式進(jìn)入?yún)?shù)解析的妖嬈姿勢(shì)篇,會(huì)介紹一下常見(jiàn)的一些case(并不能說(shuō)包含了所有的使用case)

下面所有的方法都放在 ParamPostRest 這個(gè)Controller中

@RestController
@RequestMapping(path = "post")
public class ParamPostRest {
}

在正式介紹之前,強(qiáng)烈推薦看一下《190824-SpringBoot系列教程web篇之Get請(qǐng)求參數(shù)解析姿勢(shì)匯總》, 因?yàn)間et傳參的姿勢(shì),在post參數(shù)解析中同樣適用,下面的內(nèi)容并不會(huì)再次詳細(xì)介紹

1. HttpServletRequest

首先看一下最基本的使用case,和get請(qǐng)求里的case一樣,我們先開(kāi)一個(gè)接口

@PostMapping(path = "req")
public String requestParam(HttpServletRequest req) {
    return JSONObject.toJSONString(req.getParameterMap());
}

我們測(cè)試下兩種post請(qǐng)求下,會(huì)出現(xiàn)怎樣的結(jié)果

# 常規(guī)的表單提交方式
# 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中可以知道,通過(guò)傳統(tǒng)的表達(dá)方式提交的數(shù)據(jù)時(shí),獲取參數(shù)和get獲取參數(shù)使用姿勢(shì)一樣;然而當(dāng)然傳入的是json串格式的數(shù)據(jù)時(shí),直接通過(guò)javax.servlet.ServletRequest#getParameter獲取不到對(duì)應(yīng)的參數(shù)

我們通過(guò)debug,來(lái)看一下在傳json串?dāng)?shù)據(jù)的時(shí)候,如果我們要獲取數(shù)據(jù),可以怎么做

如何解析Post請(qǐng)求參數(shù)

上面截圖演示了我們從請(qǐng)求的InputStream中獲取post參數(shù);所以再實(shí)際使用的時(shí)候需要注意,流中的數(shù)據(jù)只能讀一次,讀完了就沒(méi)了; 這個(gè)和我們使用GET傳參是有很大的差別的

注意:如果您有一個(gè)打印請(qǐng)求參數(shù)日志的切面,在獲取post傳的參數(shù)時(shí)需要注意,是不是把流的數(shù)據(jù)讀了,導(dǎo)致業(yè)務(wù)中無(wú)法獲取到正確的數(shù)據(jù)!??!

2. RequestBody

上面說(shuō)到傳json串?dāng)?shù)據(jù)時(shí),后端直接通過(guò)HttpServletRequest獲取數(shù)據(jù)不太方便,那么有更優(yōu)雅的使用姿勢(shì)么?下面我們看一下@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();
}

只需要在參數(shù)中添加@RequestBody注解即可,然后這個(gè)接口就支持json串的POST提交了

# json串?dāng)?shù)據(jù)提交
?  ~ 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)%

# 表單數(shù)據(jù)提交
?  ~ 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"}%

說(shuō)明:使用@RequestBody注解之后,可解析提交的json串;但不再支持表單提交參數(shù)方式(application/x-www-form-urlencoded)

3. RequestEntity

使用RequestEntity來(lái)解析參數(shù),可能并不太常見(jiàn),它用來(lái)解析json串提交的參數(shù)也比較合適,使用姿勢(shì)也比較簡(jiǎn)單

@PostMapping(path = "entity")
public String entityParam(RequestEntity requestEntity) {
    return Objects.requireNonNull(requestEntity.getBody()).toString();
}

使用case如下

# json串?dāng)?shù)據(jù)提交
?  ~ 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}%

# 表單數(shù)據(jù)提交不行
?  ~ 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"}%

4. MultipartFile 文件上傳

文件上傳也是一個(gè)比較常見(jiàn)的,支持起來(lái)也比較簡(jiǎn)單,有兩種方式,一個(gè)是使用MultipartHttpServletRequest參數(shù)來(lái)獲取上傳的文件;一個(gè)是借助 @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);
}

測(cè)試case如下

# 創(chuàng)建一個(gè)文本文件
?  ~ vim hello.txt
hello, this is yhh's spring test!

# 使用curl -F 實(shí)現(xiàn)文件上傳,注意使用姿勢(shì)
?  ~ 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!

5. 其他

上面介紹的幾種有別于GET篇中的請(qǐng)求姿勢(shì),請(qǐng)注意GET請(qǐng)求參數(shù)的解析方式,在POST請(qǐng)求中,可能也是適用的,為什么說(shuō)可能?因?yàn)樵趐ost請(qǐng)求中,不同的content-type,對(duì)參數(shù)的解析影響還是有的;

需要注意的是,對(duì)于傳統(tǒng)的表單提交(application/x-www-form-urlencoded)方式,post的參數(shù)解析依然可以使用

上述就是小編為大家分享的如何解析Post請(qǐng)求參數(shù)了,如果剛好有類(lèi)似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI