欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot接收接口入?yún)⒌姆绞叫〗Y(jié)

 更新時(shí)間:2024年01月10日 10:01:15   作者:象牙酥  
這篇文章主要給大家介紹了SpringBoot接收接口入?yún)⒌膸追N方式,我們從調(diào)用方的視角去看待這個(gè)問(wèn)題,對(duì)調(diào)用方來(lái)說(shuō),它在調(diào)用接口時(shí)有好幾種傳參方式,下面,將會(huì)依次對(duì)這幾種參數(shù)方式進(jìn)行講解和代碼示例,需要的朋友可以參考下

引言

我們從調(diào)用方的視角去看待這個(gè)問(wèn)題,對(duì)調(diào)用方來(lái)說(shuō),它在調(diào)用接口時(shí)有如下的幾種傳參方式:

Query參數(shù)。表現(xiàn)形式是調(diào)用方在調(diào)用接口時(shí),入?yún)⑹瞧唇釉诮涌诘?code>URI后面的,如/test_get/requestparam_1?name=wangwu&age=18。這種方式在入?yún)€(gè)數(shù)比較少GET請(qǐng)求方式中比較常用。

Path參數(shù)。這是REST風(fēng)格的路徑參數(shù),入?yún)⒅苯悠唇釉诮涌诘?code>URI里面,如/test_pathvar/test1/zhangsan/1,其中的zhangsan1就是就是參數(shù)。這種方式在REST風(fēng)格的接口中比較常用。

Body參數(shù)。這種方式是把入?yún)⒎旁诹?code>請(qǐng)求體當(dāng)中!它跟前兩種入?yún)⒎绞降淖畲髤^(qū)別,就是:

1)前兩種入?yún)⒎绞剿鼈兊娜雲(yún)⒍际侵苯芋w現(xiàn)在了調(diào)用接口時(shí)候的URI

2)而當(dāng)前的這種Body參數(shù)方式,它的入?yún)⑹欠旁诹?code>Body請(qǐng)求體內(nèi)

而且,Body參數(shù)又可以細(xì)分成如下的幾種方式:

application/json 前后端分離項(xiàng)目中常用的傳參方式

x-www-form-urlencoded 上傳表單數(shù)據(jù)

form-data 上傳表單數(shù)據(jù)

raw

binary

另外需要強(qiáng)調(diào)的是,無(wú)論是GET、POST、PUT還是DELETE請(qǐng)求方式,從技術(shù)上來(lái)說(shuō),它們是都支持上面提到的幾種傳參方式的!只不過(guò)在日常的開(kāi)發(fā)中,我們可能習(xí)慣了GET+Query參數(shù)或者POST+Body參數(shù)(application/json)這樣的搭配使用方式

下面,將會(huì)依次對(duì)這幾種參數(shù)方式進(jìn)行講解和代碼示例。

重要說(shuō)明

項(xiàng)目的pom依賴(lài)

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.9.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--Hutool是一個(gè)小而全的Java工具類(lèi)庫(kù)-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.6.3</version>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
        </dependency>
        <!--fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.6</version>
        </dependency>
    </dependencies>

代碼的說(shuō)明

  • 下面所有接口的定義,使用的都是@RequestMapping,且都沒(méi)有指定具體的請(qǐng)求類(lèi)型——如此故意為之就是為了使得接口從技術(shù)上支持各種請(qǐng)求方式(GET POST PUT DELETE等),好方便測(cè)試在不同的請(qǐng)求方式下,是否支持各種不同的傳參方式。但是大家在平日的業(yè)務(wù)代碼開(kāi)發(fā)中,最好是在接口定義時(shí)指定特定的請(qǐng)求方式。
  • 在下面所有的代碼中,我都在方法定義的形參中加上了HttpServletRequest,是因?yàn)槲乙獜?code>HttpServletRequest中獲取請(qǐng)求的方法類(lèi)型(request.getMethod())和URI( request.getRequestURI()),從而在接口的返回結(jié)果在顯現(xiàn)出來(lái),以方便調(diào)試。
  • 大家在自己實(shí)際的業(yè)務(wù)代碼中可以根據(jù)自身需求決定是否加上這個(gè)。不加也不影響入?yún)⒌慕邮眨?/li>
  • 下面所以接口的定義中,方法返回類(lèi)型都是string類(lèi)型,如:
method: [DELETE], uri: [/test_query/requestparam_1], param type: [Query]  ---> SUCCESS! requestParam1 name = wangwu-delete, age = 18

但是看后面調(diào)用方調(diào)用接口的返回結(jié)果,卻是如下所示的json串:

{
    "code": 0,
    "data": "method: [DELETE], uri: [/test_query/requestparam_1], param type: [Query]  ---> SUCCESS! requestParam1 name = wangwu-delete, age = 18",
    "msg": "操作成功",
    "timestamp": 1704766444205
}

可以看到方法返回的String內(nèi)容則是在json串的data這個(gè)key當(dāng)中。
這是因?yàn)樵谖业捻?xiàng)目中,我結(jié)合@RestControllerAdviceResponseBodyAdvice,對(duì)接口返回結(jié)果進(jìn)行了統(tǒng)一的處理。(核心的處理邏輯是:如果接口返回結(jié)果類(lèi)型已經(jīng)是指定的ResultVO,直接返回;否則將接口返回結(jié)果封裝到ResultVO對(duì)象的data字段中,再返回。)

4. 本文旨在展示在各種請(qǐng)求方式下對(duì)不同傳參方式的支持情況,因此下面代碼中,都沒(méi)有對(duì)接口入?yún)⑦M(jìn)行任何的校驗(yàn)——即:校驗(yàn)不是本文的重點(diǎn),關(guān)于接口入?yún)⒌男r?yàn),可以去看我的另一篇博客。

1.Query參數(shù)

Query參數(shù),表現(xiàn)形式是調(diào)用方在調(diào)用接口時(shí),入?yún)⑹瞧唇釉诮涌诘?code>URI后面的,如/test_query/requestparam_1?name=wangwu&age=18。

1.1接口定義方式1:在方法形參的位置,把每個(gè)參數(shù)都平鋪開(kāi)來(lái)

  • 定義方式: 在方法形參的位置,把每個(gè)參數(shù)都平鋪開(kāi)來(lái)
  • 兼容的請(qǐng)求方式GET POST PUT DELETE
  • 適用場(chǎng)景:雖然這種傳參方式,從技術(shù)上來(lái)說(shuō)可用于GET POST PUT DELETE等請(qǐng)求方式,但是在日常開(kāi)發(fā)中一般偏向于應(yīng)用在入?yún)€(gè)數(shù)少(一般少于5個(gè))GET請(qǐng)求方式中
  • 優(yōu)點(diǎn):方便簡(jiǎn)單
  • 缺點(diǎn):
    • 調(diào)用時(shí)入?yún)⒅苯语@示在uri中,不太安全
    • 方法定義時(shí)參數(shù)個(gè)數(shù)如果過(guò)多,方法體結(jié)構(gòu)會(huì)顯得很臃腫
    • 沒(méi)有入?yún)⑿r?yàn)

代碼

package com.su.demo.controller.param_type;

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;


@RestController
@RequestMapping(value = "/param_type/query")
public class TestQueryController {

    /**
     * <ul>
     *     <li><b>入?yún)㈩?lèi)別</b>:Query參數(shù)
     *     <li><b>定義方式</b>: 在方法形參的位置,把每個(gè)參數(shù)都平鋪開(kāi)來(lái)</li>
     *     <li><b>調(diào)用方式</b>: 入?yún)⑵唇釉诮涌诘膗ri后面,如 /test_get/requestparam_1?name=wangwu&age=18</li>
     *     <li><b>兼容的請(qǐng)求方式</b>:GET POST PUT DELETE</li>
     *     <li><b>適用場(chǎng)景</b>:雖然這種傳參方式,適用于GET POST PUT DELETE等請(qǐng)求方式,但是一般偏向于應(yīng)用在 入?yún)€(gè)數(shù)少(一般少于5個(gè))的<b>GET</b>請(qǐng)求方式中</li>
     *     <li><b>優(yōu)點(diǎn)</b>:方便簡(jiǎn)單</li>
     *     <li><b>缺點(diǎn)</b>:1) 入?yún)⒅苯语@示在uri中,不太安全 2)參數(shù)個(gè)數(shù)如果過(guò)多,方法體結(jié)構(gòu)會(huì)顯得很臃腫; 3)沒(méi)有入?yún)⑿r?yàn)</li>
     * </ul>
     * <p><b>注意</b>:根據(jù)自己的需求決定是否在形參中加上HttpServletRequest,我這里是為了從request中獲取method,所以加上了</p>
     */
    @RequestMapping(value = "/test1")
    public String test1(String name, Integer age, HttpServletRequest request) {
        // 從request中獲取一些接口請(qǐng)求時(shí)的元數(shù)據(jù)信息,包括請(qǐng)求方式,Content-type等
        String requestMetaInfo = String.format("method: [%s], uri: [%s], Content-Type: [%s] ", request.getMethod(), request.getRequestURI(),  request.getHeader("Content-Type"));

        return requestMetaInfo + " ---> SUCCESS! name = " + name + ", age = " + age;
    }

}

調(diào)用case

注意看上面這個(gè)/param_type/query/test1接口的定義方式,它并沒(méi)有指定請(qǐng)求方式,因此它支持GET POST PUT DELETE等所有的請(qǐng)求方式(已經(jīng)過(guò)驗(yàn)證),為了節(jié)約文章篇幅,下面只以GET 請(qǐng)求方式的調(diào)用結(jié)果為例,看是否可以在controller代碼中獲取到調(diào)用方傳過(guò)來(lái)的實(shí)參。

發(fā)起請(qǐng)求:

在這里插入圖片描述

接口返回結(jié)果:

在這里插入圖片描述

1.2接口定義方式2:在方法形參的位置,結(jié)合@RequestParam把每個(gè)參數(shù)都平鋪開(kāi)來(lái)

  • 定義方式: 在方法形參的位置,結(jié)合@RequestParam把每個(gè)參數(shù)都平鋪開(kāi)來(lái)
  • 兼容的請(qǐng)求方式GET POST PUT DELETE
  • 適用場(chǎng)景:雖然這種傳參方式,從技術(shù)上來(lái)說(shuō)可用于GET POST PUT DELETE等請(qǐng)求方式,但是在日常開(kāi)發(fā)中一般偏向于應(yīng)用在入?yún)€(gè)數(shù)少(一般少于5個(gè))GET請(qǐng)求方式中
  • 優(yōu)點(diǎn):方便簡(jiǎn)單,且結(jié)合@RequestParam,可實(shí)現(xiàn)入?yún)⒌?code>必填校驗(yàn)/重命名/默認(rèn)值等簡(jiǎn)單的校驗(yàn)功能
  • 缺點(diǎn):
    • 調(diào)用時(shí)入?yún)⒅苯语@示在uri中,不太安全
    • 方法定義時(shí)如果參數(shù)個(gè)數(shù)如果過(guò)多,方法體結(jié)構(gòu)會(huì)顯得很臃腫
    • @RequestParam能支持的校驗(yàn)相對(duì)來(lái)說(shuō)還是比較簡(jiǎn)單

代碼

package com.su.demo.controller.param_type;

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;

@RestController
@RequestMapping(value = "/param_type/query")
public class TestQueryController {

    /**
     * <ul>
     *     <li><b>入?yún)㈩?lèi)別</b>:Query參數(shù)
     *     <li><b>定義方式</b>: 在方法形參的位置,把每個(gè)參數(shù)都平鋪開(kāi)來(lái).并且相較于前一種定義方式,這種方式使用 {@link RequestParam}綁定請(qǐng)求參數(shù)到方法形參, 且需要注意該注解中的各個(gè)屬性的作用!</li>
     *     <li><b>調(diào)用方式</b>: 入?yún)⑵唇釉诮涌诘膗ri后面,如 /test_get/requestparam_1?name=wangwu&age=18</li>
     *     <li><b>兼容的請(qǐng)求方式</b>:GET POST PUT DELETE</li>
     *     <li><b>適用場(chǎng)景</b>:雖然這種傳參方式,適用于GET POST PUT DELETE等請(qǐng)求方式,但是一般偏向于應(yīng)用在 入?yún)€(gè)數(shù)少(一般少于5個(gè))的<b>GET</b>請(qǐng)求方式中</li>
     *     <li><b>優(yōu)點(diǎn)</b>:方便簡(jiǎn)單;且結(jié)合{@link RequestParam},可實(shí)現(xiàn)入?yún)⒌谋靥钚r?yàn)/重命名/默認(rèn)值等簡(jiǎn)單的功能</li>
     *     <li><b>缺點(diǎn)</b>:1) 入?yún)⒅苯语@示在uri中,不太安全
     *                    2)參數(shù)個(gè)數(shù)如果過(guò)多,方法體結(jié)構(gòu)會(huì)顯得很臃腫(當(dāng)前這個(gè)方法有4個(gè)入?yún)?其實(shí)就已經(jīng)有點(diǎn)臃腫了)
     *                    3){@link RequestParam}能支持的校驗(yàn)相對(duì)來(lái)說(shuō)還是比較簡(jiǎn)單</li>
     * </ul>
     */
    @RequestMapping(value = "/test2_requestparam")
    public String test2(@RequestParam String name,
                                @RequestParam(name = "newAge") Integer age,
                                @RequestParam(name = "birth", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date birth,
                                @RequestParam(defaultValue = "true") Boolean enable,
                                HttpServletRequest request) {
        // 從request中獲取一些接口請(qǐng)求時(shí)的元數(shù)據(jù)信息,包括請(qǐng)求方式,Content-type等
        String requestMetaInfo = String.format("method: [%s], uri: [%s], Content-Type: [%s] ", request.getMethod(), request.getRequestURI(),  request.getHeader("Content-Type"));

        return requestMetaInfo + " ---> SUCCESS! name = " + name + ", age = " + age + ", birth = " + birth + ", enable = " + enable;
    }

}

調(diào)用case

注意看上面這個(gè)/param_type/query/test2_requestparam接口的定義方式,它并沒(méi)有指定請(qǐng)求方式,因此它支持GET POST PUT DELETE等所有的請(qǐng)求方式(已經(jīng)過(guò)驗(yàn)證),為了節(jié)約文章篇幅,下面只以GET 請(qǐng)求方式的調(diào)用結(jié)果為例,看是否可以在controller代碼中獲取到調(diào)用方傳過(guò)來(lái)的實(shí)參。

在這里插入圖片描述

可以看到,參數(shù)都獲取到了。

1.3接口定義方式3:把入?yún)⒎庋b到一個(gè)實(shí)體中

  • 定義方式: 把入?yún)⒎庋b到一個(gè)實(shí)體中
  • 兼容的請(qǐng)求方式GET POST PUT DELETE
  • 適用場(chǎng)景:雖然這種傳參方式,從技術(shù)上來(lái)說(shuō)可用于GET POST PUT DELETE等請(qǐng)求方式,但是在日常開(kāi)發(fā)中一般偏向于應(yīng)用在入?yún)€(gè)數(shù)多(一般大于5個(gè))GET請(qǐng)求方式中
  • 優(yōu)點(diǎn):因?yàn)閰?shù)都封裝在實(shí)體對(duì)象當(dāng)中了,所以對(duì)參數(shù)的個(gè)數(shù)就沒(méi)有什么的限制了,接口定義的時(shí)候方便多了
  • 缺點(diǎn):對(duì)于這種入?yún)⒌亩x方式來(lái)說(shuō),它是沒(méi)有什么缺點(diǎn)的,硬要說(shuō)缺點(diǎn)的話(huà),其實(shí)是針對(duì)Query這種傳參方式來(lái)說(shuō)的,即:當(dāng)參數(shù)個(gè)數(shù)一多的時(shí)候,參數(shù)都放在請(qǐng)求uri中了,一個(gè)是不太安全,另外也容易造成uri的長(zhǎng)度過(guò)過(guò)長(zhǎng) (雖然http協(xié)議中未明確對(duì)url進(jìn)行長(zhǎng)度限制,但在真正實(shí)現(xiàn)中,url的長(zhǎng)度還是受到限制的,一是服務(wù)器端的限制,二就是游覽器端的限制)

注:再次申明,在下面代碼中,我在方法定義的形參中加上了HttpServletRequest,是因?yàn)槲乙獜?code>HttpServletRequest中獲取請(qǐng)求的方法類(lèi)型(request.getMethod())和URI( request.getRequestURI()),從而在接口的返回結(jié)果在顯現(xiàn)出來(lái),以方便調(diào)試。
大家在自己實(shí)際的業(yè)務(wù)代碼中可以根據(jù)自身需求決定是否加上這個(gè)。不加也不影響入?yún)⒌慕邮眨?/p>

代碼

package com.su.demo.controller.param_type;

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;

@RestController
@RequestMapping(value = "/param_type/query")
public class TestQueryController {

    /**
     * <ul>
     *     <li><b>入?yún)㈩?lèi)別</b>:Query參數(shù)
     *     <li><b>定義方式</b>: 把入?yún)⒎庋b到一個(gè)實(shí)體中(入?yún)€(gè)數(shù)多于5個(gè)時(shí)一般用這種方式)
     *     <li><b>調(diào)用方式</b>: 入?yún)⑵唇釉诮涌诘膗ri后面,如 /test_get/requestparam_1?name=wangwu&age=18</li>
     *     <li><b>兼容的請(qǐng)求方式</b>:GET POST PUT DELETE</li>
     *     <li><b>適用場(chǎng)景</b>:從技術(shù)上來(lái)說(shuō)這種傳參方式,同時(shí)適用于GET POST PUT DELETE等多種請(qǐng)求方式,但是一般我個(gè)從偏向于在入?yún)€(gè)數(shù)大于5個(gè)的<b>GET</b>請(qǐng)求方式中使用</li>
     *     <li><b>優(yōu)點(diǎn)</b>:因?yàn)閰?shù)都封裝在實(shí)體bean當(dāng)中了,所以對(duì)參數(shù)的個(gè)數(shù)就沒(méi)有什么的限制了,接口定義的時(shí)候方便多了
     *     <li><b>缺點(diǎn)</b>:對(duì)于這種入?yún)⒌腫定義方式]來(lái)說(shuō),它是沒(méi)有什么缺點(diǎn)的.硬要說(shuō)缺點(diǎn)的話(huà),其實(shí)是針對(duì)Query這種傳參方式來(lái)說(shuō)的,即當(dāng)參數(shù)個(gè)數(shù)一多的時(shí)候,參數(shù)都放在請(qǐng)求uri中容易造成uri的長(zhǎng)度過(guò)過(guò)長(zhǎng)
     *     (雖然http協(xié)議中未明確對(duì)url進(jìn)行長(zhǎng)度限制,但在真正實(shí)現(xiàn)中,url的長(zhǎng)度還是受到限制的,一是服務(wù)器端的限制,二就是游覽器端的限制)</li>
     * </ul>
     */
    @RequestMapping(value = "/test3_entity")
    public String test3(UserDTO userDTO, HttpServletRequest request) {
        // 從request中獲取一些接口請(qǐng)求時(shí)的元數(shù)據(jù)信息,包括請(qǐng)求方式,Content-type等
        String requestMetaInfo = String.format("method: [%s], uri: [%s], Content-Type: [%s] ", request.getMethod(), request.getRequestURI(),  request.getHeader("Content-Type"));

        return requestMetaInfo + " ---> SUCCESS! userDTO = " + userDTO;
    }

}

其中UserDTO 的代碼如下:

package com.su.demo.bean.dto;

import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;

@Data
public class UserDTO {
    /**
     * 主鍵ID
     */
    private Long id;

    /**
     * 用戶(hù)姓名
     */
    private String name;

    /**
     * 用戶(hù)狀態(tài) true:?jiǎn)⒂?;false:禁用
     */
    private Boolean enable;

    /**
     * 用戶(hù)生日
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date birth;
}

調(diào)用case

注意看上面這個(gè)/param_type/query/test3_entity接口的定義方式,它并沒(méi)有指定請(qǐng)求方式,因此它支持GET POST PUT DELETE等所有的請(qǐng)求方式(已經(jīng)過(guò)驗(yàn)證),為了節(jié)約文章篇幅,下面只以POST 請(qǐng)求方式的調(diào)用結(jié)果為例,看是否可以在controller代碼中獲到調(diào)用方傳過(guò)來(lái)的實(shí)參。

在這里插入圖片描述

可以看到,參數(shù)都獲取到了。

1.4接口定義方式4:用原生的HttpServletRequest接收參數(shù)

  • 定義方式: 在方式形參的位置,用原生的HttpServletRequest接收
  • 兼容的請(qǐng)求方式GET POST PUT DELETE
  • 適用場(chǎng)景:現(xiàn)在很少用這種方式去接收入?yún)⒘恕?/li>
  • 優(yōu)點(diǎn):HttpServletRequest是整個(gè)請(qǐng)求,可以獲取到所有的數(shù)據(jù).且HttpServletRequest、HttpServletResponse都是內(nèi)置對(duì)象,可以使用
  • 缺點(diǎn):代碼中再去從request中拿到參數(shù),比較麻煩

代碼

package com.su.demo.controller.param_type;

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;

@RestController
@RequestMapping(value = "/param_type/query")
public class TestQueryController {

    /**
     * <ul>
     *     <li><b>入?yún)㈩?lèi)別</b>:Query參數(shù)
     *     <li><b>定義方式</b>: 在方式形參的位置,用原生的{@link HttpServletRequest}接收
     *     <li><b>調(diào)用方式</b>: 入?yún)⑵唇釉诮涌诘膗ri后面,如 /test_get/requestparam_1?name=wangwu&age=18</li>
     *     <li><b>兼容的請(qǐng)求方式</b>:GET POST PUT DELETE</li>
     *     <li><b>適用場(chǎng)景</b>:從技術(shù)上來(lái)說(shuō),這種傳參方式同時(shí)適用于GET POST PUT DELETE等請(qǐng)求方式,但是正常情況下比較少用這種方式來(lái)獲取參數(shù)了</li>
     *     <li><b>優(yōu)點(diǎn)</b>:{@link HttpServletRequest}是整個(gè)請(qǐng)求,可以獲取到所有的數(shù)據(jù).且HttpServletRequest、HttpServletResponse都是內(nèi)置對(duì)象,可以使用</li>
     *     <li><b>缺點(diǎn)</b>:代碼中再去從request中拿到參數(shù),比較麻煩</li>
     * </ul>
     * <p> 注意,這種方式其實(shí)也可以獲取body請(qǐng)求體里面的數(shù)據(jù),參考https://blog.csdn.net/qq_24850045/article/details/121927722
     */
    @RequestMapping(value = "/test4_request")
    public String test4(HttpServletRequest request) throws IOException {
        // 從request中獲取一些接口請(qǐng)求時(shí)的元數(shù)據(jù)信息,包括請(qǐng)求方式,Content-type等
        String requestMetaInfo = String.format("method: [%s], uri: [%s], Content-Type: [%s] ", request.getMethod(), request.getRequestURI(),  request.getHeader("Content-Type"));

        String name = request.getParameter("name");
        Integer age = Integer.parseInt(request.getParameter("age")); // 需要進(jìn)行類(lèi)型轉(zhuǎn)換

        return requestMetaInfo + " ---> SUCCESS! name = " + name + ", age = "  + age;
    }

}

調(diào)用case

注意看上面這個(gè)/param_type/query/test4_request接口的定義方式,它并沒(méi)有指定請(qǐng)求方式,因此它支持GET POST PUT DELETE等所有的請(qǐng)求方式(已經(jīng)過(guò)驗(yàn)證),為了節(jié)約文章篇幅,下面只以PUT 請(qǐng)求方式的調(diào)用結(jié)果為例,看是否可以在controller代碼中獲到調(diào)用方傳過(guò)來(lái)的實(shí)參。

在這里插入圖片描述

可以看到,參數(shù)都獲取到了。

1.5接口定義方式5:用Map結(jié)合RequestParam接收參數(shù)

  • 定義方式: 在方式形參的位置,用Map結(jié)合RequestParam接收參數(shù)
  • 兼容的請(qǐng)求方式GET POST PUT DELETE
  • 適用場(chǎng)景:適用于參數(shù)個(gè)數(shù)較多,但是自己又想偷懶不想專(zhuān)門(mén)定義一個(gè)實(shí)體來(lái)接收入?yún)⒌膱?chǎng)景。一般不推薦使用這種方式。
  • 優(yōu)點(diǎn):簡(jiǎn)單方便,偷懶很開(kāi)心
  • 缺點(diǎn):1)需要在代碼中通過(guò)指定特定的key的方式去獲取入?yún)ⅲ容^麻煩;2)利用map去get到入?yún)⒅?,還需要手動(dòng)的去做非空判斷+數(shù)據(jù)類(lèi)型轉(zhuǎn)換等,很麻煩;3)而且這種接收入?yún)⒌姆绞?,沒(méi)有辦法結(jié)合org.springframework.validation.annotation.Validated來(lái)做入?yún)⑿r?yàn)!

代碼

package com.su.demo.controller.param_type;

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;

@RestController
@RequestMapping(value = "/param_type/query")
public class TestQueryController {

    /**
     * <ul>
     *     <li><b>入?yún)㈩?lèi)別</b>:Query參數(shù)
     *     <li><b>定義方式</b>: 在方式形參的位置,結(jié)合{@link RequestParam}用Map接收
     *     <li><b>調(diào)用方式</b>: 入?yún)⑵唇釉诮涌诘膗ri后面,如 /test_get/requestparam_1?name=wangwu&age=18</li>
     *     <li><b>兼容的請(qǐng)求方式</b>:GET POST PUT DELETE</li>
     *     <li><b>適用場(chǎng)景</b>:適用于參數(shù)個(gè)數(shù)較多,但是自己又想偷懶不想專(zhuān)門(mén)定義一個(gè)實(shí)體來(lái)接收入?yún)⒌膱?chǎng)景。一般不推薦使用這種方式。</li>
     *     <li><b>優(yōu)點(diǎn)</b>:簡(jiǎn)單方便</li>
     *     <li><b>缺點(diǎn)</b>:需要在代碼中通過(guò)指定特定的key的方式去獲取入?yún)?,比較麻煩;而且這種接收入?yún)⒌姆绞?,沒(méi)有辦法結(jié)合{@link org.springframework.validation.annotation.Validated}來(lái)做入?yún)⑿r?yàn)</li>
     * </ul>
     */
    @RequestMapping(value = "/test5_map")
    public String test5(@RequestParam Map<String, String> paramMap, HttpServletRequest request) throws IOException {
        // 從request中獲取一些接口請(qǐng)求時(shí)的元數(shù)據(jù)信息,包括請(qǐng)求方式,Content-type等
        String requestMetaInfo = String.format("method: [%s], uri: [%s], Content-Type: [%s] ", request.getMethod(), request.getRequestURI(),  request.getHeader("Content-Type"));

        String name = paramMap.get("name");
        // 判斷:如果paramMap.get("age")為null,則age賦默認(rèn)值0;否則進(jìn)行入?yún)㈩?lèi)型的轉(zhuǎn)換
        Integer age = null == paramMap.get("age") ? 0: Integer.parseInt(paramMap.get("age"));

        return requestMetaInfo + " ---> SUCCESS! name = " + name + ", age = "  + age;
    }

}

調(diào)用case

注意看上面這個(gè)/param_type/query/test5_map接口的定義方式,它并沒(méi)有指定請(qǐng)求方式,因此它支持GET POST PUT DELETE等所有的請(qǐng)求方式(已經(jīng)過(guò)驗(yàn)證),為了節(jié)約文章篇幅,下面只以DELETE 請(qǐng)求方式的調(diào)用結(jié)果為例,看是否可以在controller代碼中獲到調(diào)用方傳過(guò)來(lái)的實(shí)參。

在這里插入圖片描述

可以看到,參數(shù)都獲取到了。

2.Path參數(shù)

Path參數(shù),表現(xiàn)形式是入?yún)⒅苯悠唇釉诮涌诘?code>URI里面,如/test_pathvar/test1/zhangsan/1,其中的zhangsan1就是就是參數(shù)。這種方式在REST風(fēng)格的接口中比較常用。

REST(英文:Representational State Transfer,簡(jiǎn)稱(chēng)REST,意思:表述性狀態(tài)轉(zhuǎn)換,描述了一個(gè)架構(gòu)樣式的網(wǎng)絡(luò)系統(tǒng),比如web應(yīng)用),一定要記住==它是一種軟件架構(gòu)風(fēng)格!而不是標(biāo)準(zhǔn)!==它只是提供了一組設(shè)計(jì)原則和約束條件。它主要用于客戶(hù)端和服務(wù)器交互類(lèi)的軟件?;谶@個(gè)風(fēng)格設(shè)計(jì)的軟件可以更簡(jiǎn)潔,更有層次,更易于實(shí)現(xiàn)緩存等機(jī)制。
REST指的是一組架構(gòu)(約束條件)和原則。滿(mǎn)足這些(約束條件)和(原則)的應(yīng)用程序或設(shè)計(jì)就是 Restful

2.1接口定義方式:用占位符的方式把入?yún)⒎庋b到請(qǐng)求路徑中

  • 定義方式: 用占位符的方式把入?yún)⒎庋b到請(qǐng)求路徑中,然后再通過(guò)@PathVariable注解可以將URL中的占位符參數(shù)綁定到控制器(controller)處理方法的形參中
  • 兼容的請(qǐng)求方式GET POST PUT DELETE
  • 適用場(chǎng)景:從技術(shù)上來(lái)說(shuō),這種傳參方式同時(shí)適用于GET POST PUT DELETE等多種請(qǐng)求方式。 但是一般入?yún)€(gè)數(shù)較少,且你開(kāi)發(fā)的是REST風(fēng)格的接口,那可以考慮用這種方式
  • 優(yōu)點(diǎn)和缺點(diǎn):優(yōu)點(diǎn)和缺點(diǎn),其實(shí)就是REST風(fēng)格的接口的優(yōu)點(diǎn)和缺點(diǎn)了,大家可以自行去查閱

代碼

package com.su.demo.controller.param_type;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping(value = "/param_type/path_variable")
public class TestPathVarController {


    /**
     * <ul>
     *     <li><b>入?yún)㈩?lèi)別</b>:PathVariable路徑參數(shù)方式
     *     <li><b>定義方式</b>: 用占位符的方式把入?yún)⒎庋b到請(qǐng)求路徑中,然后再通過(guò)@PathVariable注解可以將URL中的占位符參數(shù)綁定到控制器(controller)處理方法的形參中. </li>
     *     <li><b>調(diào)用方式</b>: REST風(fēng)格路徑參數(shù),入?yún)⑵唇釉诮涌诘腢RI里面,如/test_pathvar/test1/zhangsan/1 </li>
     *     <li><b>兼容的請(qǐng)求方式</b>:GET POST PUT DELETE</li>
     *     <li><b>適用場(chǎng)景</b>:從技術(shù)上來(lái)說(shuō),這種傳參方式同時(shí)適用于GET POST PUT DELETE等多種請(qǐng)求方式.
     *         但是一般入?yún)€(gè)數(shù)小于5個(gè),且你開(kāi)發(fā)的是REST風(fēng)格的接口,那可以考慮用這種方式
     *         </li>
     * </ul>
     * <p>REST(英文:Representational State Transfer,簡(jiǎn)稱(chēng)REST,意思:表述性狀態(tài)轉(zhuǎn)換,描述了一個(gè)架構(gòu)樣式的網(wǎng)絡(luò)系統(tǒng),比如web應(yīng)用),是一種軟件架構(gòu)風(fēng)格不是標(biāo)準(zhǔn)哦!
     * 只是提供了一組設(shè)計(jì)原則和約束條件。它主要用于客戶(hù)端和服務(wù)器交互類(lèi)的軟件?;谶@個(gè)風(fēng)格設(shè)計(jì)的軟件可以更簡(jiǎn)潔,更有層次,更易于實(shí)現(xiàn)緩存等機(jī)制。
     * REST 指的是一組架構(gòu)(約束條件)和原則。滿(mǎn)足這些(約束條件)和(原則)的應(yīng)用程序或設(shè)計(jì)就是 Restful。</p>
     */
    @RequestMapping(value = "/test1/{name}/{age}")
    public String test1(@PathVariable("name") String name, @PathVariable("age") Integer myage, HttpServletRequest request) {
        // 從request中獲取一些接口請(qǐng)求時(shí)的元數(shù)據(jù)信息,包括請(qǐng)求方式,Content-type等
        String requestMetaInfo = String.format("method: [%s], uri: [%s], Content-Type: [%s] ", request.getMethod(), request.getRequestURI(),  request.getHeader("Content-Type"));
        return requestMetaInfo + " ---> SUCCESS! name = " + name + ", myage = "  + myage;
    }
}

調(diào)用case

注意看上面這個(gè)/param_type/path_variable/test1/{name}/{age}接口的定義方式,它并沒(méi)有指定請(qǐng)求方式,因此它支持GET POST PUT DELETE等所有的請(qǐng)求方式(已經(jīng)過(guò)驗(yàn)證),為了節(jié)約文章篇幅,下面只以GET 請(qǐng)求方式的調(diào)用結(jié)果為例,看是否可以在controller代碼中獲到調(diào)用方傳過(guò)來(lái)的實(shí)參。

可以看到,參數(shù)都獲取到了。

3.Body參數(shù)

Body參數(shù),這種方式是把入?yún)⒎旁诹?code>請(qǐng)求體當(dāng)中!它跟前兩種入?yún)⒎绞降淖畲髤^(qū)別,就是:

  1. 前兩種入?yún)⒎绞剿鼈兊娜雲(yún)⒍际侵苯芋w現(xiàn)在了調(diào)用接口時(shí)候的URI
  2. 而當(dāng)前的這種Body參數(shù)方式,它的入?yún)⑹欠旁诹薶ttp請(qǐng)求的請(qǐng)求體內(nèi)
    而且,Body參數(shù)又可以細(xì)分成如下的幾種方式:
    • application/json 前后端分離項(xiàng)目中常用的傳參方式
    • form-data
    • x-www-form-urlencoded
    • raw
    • binary

下面分別進(jìn)行說(shuō)明

3.1 application/json

這種入?yún)⒎绞?,入?yún)⒎旁趆ttp請(qǐng)求的請(qǐng)求體當(dāng)中,并且Content-Type=application/json。

3.1.1 接口定義方式1:在方式形參的位置,用原生的HttpServletRequest接收

  • 定義方式: 在方式形參的位置,用原生的HttpServletRequest接收
  • 兼容的請(qǐng)求方式GET POST PUT DELETE
  • 適用場(chǎng)景:從技術(shù)上來(lái)說(shuō),這種傳參方式同時(shí)適用于GET POST PUT DELETE等請(qǐng)求方式,但是正常情況下比較少用這種方式來(lái)獲取Content-Type=application/json的body參數(shù)了
  • 優(yōu)點(diǎn):HttpServletRequest是整個(gè)請(qǐng)求,可以獲取到所有的數(shù)據(jù)。且HttpServletRequest、HttpServletResponse都是內(nèi)置對(duì)象,可以使用
  • 缺點(diǎn):碼中再去從request中拿到參數(shù),老麻煩了,可以看下面的代碼

代碼

package com.su.demo.controller.param_type;

import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson.JSON;
import com.su.demo.bean.dto.UserDTO;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@RestController
@RequestMapping(value = "/param_type/body_json")
public class TestBodyController {


    /**
     * <ul>
     *     <li><b>入?yún)㈩?lèi)別</b>:body參數(shù)方式
     *     <li><b>定義方式</b>: 在方式形參的位置,用原生的{@link HttpServletRequest}接收
     *     <li><b>調(diào)用方式</b>: 參數(shù)放在請(qǐng)求體 body 當(dāng)中
     *     <li><b>兼容的請(qǐng)求方式</b>:GET POST PUT DELETE</li>
     *     <li><b>適用場(chǎng)景</b>:從技術(shù)上來(lái)說(shuō),這種傳參方式同時(shí)適用于GET POST PUT DELETE等請(qǐng)求方式,但是正常情況下比較少用這種方式來(lái)獲取body參數(shù)了</li>
     *     <li><b>優(yōu)點(diǎn)</b>:{@link HttpServletRequest}是整個(gè)請(qǐng)求,可以獲取到所有的數(shù)據(jù).且HttpServletRequest、HttpServletResponse都是內(nèi)置對(duì)象,可以使用</li>
     *     <li><b>缺點(diǎn)</b>:代碼中再去從request中拿到參數(shù),老麻煩,可以看下面的代碼</li>
     * </ul>
     * <p> 注意,這種方式其實(shí)也可以獲取body請(qǐng)求體里面的數(shù)據(jù),參考https://blog.csdn.net/qq_24850045/article/details/121927722
     */
    @RequestMapping(value = "/test1_request")
    public String test1(HttpServletRequest request) throws IOException {
        // 從request中獲取一些接口請(qǐng)求時(shí)的元數(shù)據(jù)信息,包括請(qǐng)求方式,Content-type等
        String requestMetaInfo = String.format("method: [%s], uri: [%s], Content-Type: [%s] ", request.getMethod(), request.getRequestURI(),  request.getHeader("Content-Type"));

        ServletInputStream inputStream = request.getInputStream();
        // 用hutool工具包的read方式,將inputStream讀取成string
        String body = IoUtil.read(inputStream, "UTF-8");
        System.out.println("body = " + body);
        // 用fastjson將json字符串轉(zhuǎn)換成bean
        UserDTO userDTO = JSON.parseObject(body, UserDTO.class);

        return requestMetaInfo + " ---> SUCCESS! userDTO = " + userDTO;
    }
}

其中UserDTO的代碼如下:

package com.su.demo.bean.dto;

import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

@Data
public class UserDTO {
    /**
     * 主鍵ID
     */
    private Long id;

    /**
     * 用戶(hù)姓名
     */
    private String name;

    /**
     * 用戶(hù)狀態(tài) true:?jiǎn)⒂茫籪alse:禁用
     */
    private Boolean enable;

    /**
     * 用戶(hù)生日
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date birth;
}

調(diào)用case

注意看上面這個(gè)/param_type/body_json/test1_request接口的定義方式,它并沒(méi)有指定請(qǐng)求方式,因此它支持GET POST PUT DELETE等所有的請(qǐng)求方式(已經(jīng)過(guò)驗(yàn)證),為了節(jié)約文章篇幅,下面只以POST 請(qǐng)求方式的調(diào)用結(jié)果為例,看是否可以在controller代碼中獲取到調(diào)用方傳過(guò)來(lái)的實(shí)參。

在這里插入圖片描述

可以看到,參數(shù)都獲取到了。

3.1.2 接口定義方式2:在方式形參的位置,用RequestBody接收

  • 定義方式: 在在方式形參的位置,用RequestBody接收
  • 兼容的請(qǐng)求方式GET POST PUT DELETE
  • 適用場(chǎng)景:從技術(shù)上來(lái)說(shuō),這種傳參方式同時(shí)適用于GET POST PUT DELETE等請(qǐng)求方式,但是正常情況下一般用在POST或 PUT 請(qǐng)求中
  • 優(yōu)點(diǎn):
    • 方法形參的定義非常簡(jiǎn)潔;
    • 調(diào)用的時(shí)候參數(shù)放在body中,參數(shù)體可以很大,不像Query入?yún)⒎绞皆诋?dāng)參數(shù)過(guò)多的時(shí)候容易觸發(fā)服務(wù)器端Request header is too large的報(bào)錯(cuò)
  • 缺點(diǎn):用String類(lèi)型來(lái)接收參數(shù),接收之后再轉(zhuǎn)換成bean實(shí)體,還是稍微顯得有點(diǎn)麻煩

代碼

package com.su.demo.controller.param_type;

import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson.JSON;
import com.su.demo.bean.dto.UserDTO;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@RestController
@RequestMapping(value = "/param_type/body_json")
public class TestBodyController {

   /**
     * <ul>
     *     <li><b>入?yún)㈩?lèi)別</b>:body參數(shù)方式
     *     <li><b>定義方式</b>: 在方式形參的位置,用{@link RequestBody}接收
     *     <li><b>調(diào)用方式</b>: 參數(shù)放在請(qǐng)求體 body 當(dāng)中
     *     <li><b>兼容的請(qǐng)求方式</b>:GET POST PUT DELETE</li>
     *     <li><b>適用場(chǎng)景</b>:從技術(shù)上來(lái)說(shuō),這種傳參方式同時(shí)適用于GET POST PUT DELETE等請(qǐng)求方式,但是正常情況下一般用在POST或PUT請(qǐng)求中</li>
     *     <li><b>優(yōu)點(diǎn)</b>:1)方法形參的定義非常簡(jiǎn)潔;
     *                  2)調(diào)用的時(shí)候參數(shù)放在body中,參數(shù)體可以很大,不像Query入?yún)⒎绞皆诋?dāng)參數(shù)過(guò)多的時(shí)候容易觸發(fā)服務(wù)器端"Request header is too large"的報(bào)錯(cuò)
     *         </li>
     *     <li><b>缺點(diǎn)</b>:用String類(lèi)型來(lái)接收參數(shù),接收之后再轉(zhuǎn)換成bean實(shí)體,還是稍微顯得有點(diǎn)麻煩</li>
     * </ul>
     */
    @RequestMapping(value = "/test2_requestbody_string")
    public String test2(@RequestBody String body, HttpServletRequest request) {
        // 從request中獲取一些接口請(qǐng)求時(shí)的元數(shù)據(jù)信息,包括請(qǐng)求方式,Content-type等
        String requestMetaInfo = String.format("method: [%s], uri: [%s], Content-Type: [%s] ", request.getMethod(), request.getRequestURI(),  request.getHeader("Content-Type"));

        System.out.println("body = " + body);
        // 用fastjson將json字符串轉(zhuǎn)換成bean
        UserDTO userDTO = JSON.parseObject(body, UserDTO.class);

        return requestMetaInfo + " ---> SUCCESS! userDTO = " + userDTO;
    }

}

調(diào)用case

注意看上面這個(gè)/param_type/body_json/test2_requestbody_string接口的定義方式,它并沒(méi)有指定請(qǐng)求方式,因此它支持GET POST PUT DELETE等所有的請(qǐng)求方式(已經(jīng)過(guò)驗(yàn)證),為了節(jié)約文章篇幅,下面只以PUT 請(qǐng)求方式的調(diào)用結(jié)果為例,看是否可以在controller代碼中獲取到調(diào)用方傳過(guò)來(lái)的實(shí)參。

在這里插入圖片描述

可以看到,參數(shù)都獲取到了。

3.1.3 接口定義方式3:用一個(gè)實(shí)例來(lái)接收RequestBody入?yún)?/h4>
  • 定義方式: 在方式形參的位置,用RequestBody接收,而且是直接用一個(gè)實(shí)例類(lèi)來(lái)接收了(spring自動(dòng)調(diào)用相應(yīng)的org.springframework.http.converter.HttpMessageConverter去做了入?yún)⒌霓D(zhuǎn)換)
  • 兼容的請(qǐng)求方式GET POST PUT DELETE
  • 適用場(chǎng)景:從技術(shù)上來(lái)說(shuō),這種傳參方式同時(shí)適用于GET POST PUT DELETE等請(qǐng)求方式,但是正常情況下一般用在POST或 PUT 請(qǐng)求中
  • 優(yōu)點(diǎn):
    • 方法形參的定義非常簡(jiǎn)潔;
    • 調(diào)用的時(shí)候參數(shù)放在body中,參數(shù)體可以很大,不像Query入?yún)⒎绞皆诋?dāng)參數(shù)過(guò)多的時(shí)候容易觸發(fā)服務(wù)器端Request header is too large的報(bào)錯(cuò)
  • 缺點(diǎn):好像沒(méi)啥缺點(diǎn)

工作中前后端分離項(xiàng)目一般用這用方式比較多

代碼

package com.su.demo.controller.param_type;

import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson.JSON;
import com.su.demo.bean.dto.UserDTO;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@RestController
@RequestMapping(value = "/param_type/body_json")
public class TestBodyController {

    /**
     * <ul>
     *     <li><b>入?yún)㈩?lèi)別</b>:body參數(shù)方式
     *     <li><b>定義方式</b>: 在方式形參的位置,用{@link RequestBody}接收,
     *         而且是直接用一個(gè)實(shí)例類(lèi)來(lái)接收了(spring自動(dòng)調(diào)用相應(yīng)的{@link org.springframework.http.converter.HttpMessageConverter}去做轉(zhuǎn)換)
     *         </li>
     *     <li><b>調(diào)用方式</b>: 參數(shù)放在請(qǐng)求體 body 當(dāng)中
     *     <li><b>兼容的請(qǐng)求方式</b>:GET POST PUT DELETE</li>
     *     <li><b>適用場(chǎng)景</b>:從技術(shù)上來(lái)說(shuō),這種傳參方式同時(shí)適用于GET POST PUT DELETE等請(qǐng)求方式,但是正常情況下一般用在POST或PUT請(qǐng)求中</li>
     *     <li><b>優(yōu)點(diǎn)</b>:1)方法形參的定義非常簡(jiǎn)潔;
     *                  2)調(diào)用的時(shí)候參數(shù)放在body中,參數(shù)體可以很大,不像Query入?yún)⒎绞皆诋?dāng)參數(shù)過(guò)多的時(shí)候容易觸發(fā)服務(wù)器端"Request header is too large"的報(bào)錯(cuò)
     *         </li>
     *     <li><b>缺點(diǎn)</b>:好像沒(méi)啥缺點(diǎn)</li>
     * </ul>
     */
    @RequestMapping(value = "/test3_requestbody_entity")
    public String test3(@RequestBody UserDTO userDTO, HttpServletRequest request) {
        // 從request中獲取一些接口請(qǐng)求時(shí)的元數(shù)據(jù)信息,包括請(qǐng)求方式,Content-type等
        String requestMetaInfo = String.format("method: [%s], uri: [%s], Content-Type: [%s] ", request.getMethod(), request.getRequestURI(),  request.getHeader("Content-Type"));

        return requestMetaInfo + " ---> SUCCESS! userDTO = " + userDTO;
    }

}

調(diào)用case

注意看上面這個(gè)/param_type/body_json/test3_requestbody_entity接口的定義方式,它并沒(méi)有指定請(qǐng)求方式,因此它支持GET POST PUT DELETE等所有的請(qǐng)求方式(已經(jīng)過(guò)驗(yàn)證),為了節(jié)約文章篇幅,下面只以DELETE 請(qǐng)求方式的調(diào)用結(jié)果為例,看是否可以在controller代碼中獲取到調(diào)用方傳過(guò)來(lái)的實(shí)參。

在這里插入圖片描述

可以看到,參數(shù)都獲取到了。

3.1.4 接口定義方式4:用Map來(lái)接收RequestBody入?yún)?/h4>
  • 定義方式: 在方式形參的位置,用RequestBody接收,而且是直接用一個(gè)Map的實(shí)例類(lèi)來(lái)接收了
  • 兼容的請(qǐng)求方式GET POST PUT DELETE
  • 適用場(chǎng)景:適用于參數(shù)個(gè)數(shù)較多,但是自己又想偷懶不想專(zhuān)門(mén)定義一個(gè)實(shí)體來(lái)接收入?yún)⒌膱?chǎng)景。一般不推薦使用這種方式
  • 優(yōu)點(diǎn):簡(jiǎn)單方便,偷懶很開(kāi)心
  • 缺點(diǎn):1)需要在代碼中通過(guò)指定特定的key的方式去獲取入?yún)?,比較麻煩;2)利用map去get到入?yún)⒅?,還需要手動(dòng)的去做非空判斷+數(shù)據(jù)類(lèi)型轉(zhuǎn)換等,很麻煩;3)而且這種接收入?yún)⒌姆绞?,沒(méi)有辦法結(jié)合org.springframework.validation.annotation.Validated來(lái)做入?yún)⑿r?yàn)!

一般不推薦使用這種方式

代碼

package com.su.demo.controller.param_type;

import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson.JSON;
import com.su.demo.bean.dto.UserDTO;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@RestController
@RequestMapping(value = "/param_type/body_json")
public class TestBodyController {

   /**
     * <ul>
     *     <li><b>入?yún)㈩?lèi)別</b>:body參數(shù)方式
     *     <li><b>定義方式</b>: 在方式形參的位置,用{@link RequestBody}接收,
     *         而且是直接用一個(gè)Map對(duì)象實(shí)例類(lèi)來(lái)接收了(spring自動(dòng)調(diào)用相應(yīng)的{@link org.springframework.http.converter.HttpMessageConverter}去做轉(zhuǎn)換)
     *         </li>
     *     <li><b>調(diào)用方式</b>: 參數(shù)放在請(qǐng)求體 body 當(dāng)中
     *     <li><b>兼容的請(qǐng)求方式</b>:GET POST PUT DELETE</li>
     *     <li><b>適用場(chǎng)景</b>:從技術(shù)上來(lái)說(shuō),這種傳參方式同時(shí)適用于GET POST PUT DELETE等請(qǐng)求方式,一般使用在偷懶不想專(zhuān)門(mén)定義一個(gè)實(shí)體來(lái)接收入?yún)⒌膱?chǎng)景。一不太推薦使用這種方式/li>
     *     <li><b>優(yōu)點(diǎn)</b>:1)方法形參的定義非常簡(jiǎn)潔;
     *                  2)調(diào)用的時(shí)候參數(shù)放在body中,參數(shù)體可以很大,不像Query入?yún)⒎绞皆诋?dāng)參數(shù)過(guò)多的時(shí)候容易觸發(fā)服務(wù)器端"Request header is too large"的報(bào)錯(cuò)
     *         </li>
     *     <li><b>缺點(diǎn)</b>:好像沒(méi)啥缺點(diǎn)</li>
     * </ul>
     */
    @RequestMapping(value = "/test4_requestbody_map")
    public String test4(@RequestBody Map<String, String> paramMap, HttpServletRequest request) {
        // 從request中獲取一些接口請(qǐng)求時(shí)的元數(shù)據(jù)信息,包括請(qǐng)求方式,Content-type等
        String requestMetaInfo = String.format("method: [%s], uri: [%s], Content-Type: [%s] ", request.getMethod(), request.getRequestURI(),  request.getHeader("Content-Type"));

        String name = paramMap.get("name");
        // 判斷:如果paramMap.get("age")為null,則age賦默認(rèn)值0;否則進(jìn)行入?yún)㈩?lèi)型的轉(zhuǎn)換
        Integer age = null == paramMap.get("age") ? 0: Integer.parseInt(paramMap.get("age"));

        return requestMetaInfo + " ---> SUCCESS! name = " + name + ", age = " + age;
    }

}

調(diào)用case

注意看上面這個(gè)/param_type/body_json/test4_requestbody_map接口的定義方式,它并沒(méi)有指定請(qǐng)求方式,因此它支持GET POST PUT DELETE等所有的請(qǐng)求方式(已經(jīng)過(guò)驗(yàn)證),為了節(jié)約文章篇幅,下面只以POST 請(qǐng)求方式的調(diào)用結(jié)果為例,看是否可以在controller代碼中獲取到調(diào)用方傳過(guò)來(lái)的實(shí)參。

在這里插入圖片描述

可以看到,參數(shù)都獲取到了。

3.2 x-www-form-urlencoded

x-www-form-urlencodedform-data,兩者都可以用來(lái)上傳前端表單數(shù)據(jù),下面簡(jiǎn)單將兩者的不同列舉出來(lái)

1.支持的入?yún)㈩?lèi)型不同: x-www-form-urlencoded只支持普通的文本內(nèi)容,不支持上傳File文件!而form-data則支持上傳File文件(如圖片、音頻、視頻)。

2. 編碼不同: x-www-form-urlencoded的編碼方式就隱藏在名字里urlencoded,即使用js中encodeURI()函數(shù);而form-data的格式,要比 x-www-form-urlencoded復(fù)雜的多,它會(huì)把內(nèi)容分成多個(gè)部分,每個(gè)部分都支持不同的格式

3. x-www-form-urlencoded占用字節(jié)少,form-data占用字節(jié)多

x-www-form-urlencoded會(huì)將表單內(nèi)的數(shù)據(jù)轉(zhuǎn)換為鍵值對(duì),比如name=lisi&age=23,并放在請(qǐng)求體body中進(jìn)行傳輸

3.2.1 接口定義方式1:在方法形參的位置,把每個(gè)參數(shù)都平鋪開(kāi)來(lái)

  • 定義方式: 方法形參的位置,把每個(gè)參數(shù)都平鋪開(kāi)來(lái),也可以使用@RequestParam注解
  • 兼容的請(qǐng)求方式POST PUT DELETE,注意,不兼容GET請(qǐng)示方式
  • 適用場(chǎng)景:雖然這種傳參方式,適用于POST PUT DELETE等請(qǐng)求方式,但是一般偏向于應(yīng)用在 用POST或 PUT方式去發(fā)送的表單數(shù)據(jù),且參數(shù)個(gè)數(shù)少,且表單字段都是普通類(lèi)型(即表單字段不是File文件)
  • 優(yōu)點(diǎn):方便簡(jiǎn)單
  • 缺點(diǎn):1)參數(shù)個(gè)數(shù)如果過(guò)多,方法體結(jié)構(gòu)會(huì)顯得很臃腫

代碼

package com.su.demo.controller.param_type;

import cn.hutool.core.io.IoUtil;
import com.su.demo.bean.dto.TeacherDTO;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.Map;

@RestController
@RequestMapping(value = "/param_type/body_form_urlencoded")
public class TestFormUrlEncodeController {

    /**
     * <p>注意,如果使用GET請(qǐng)求方式,則后端獲取不到入?yún)ⅲ。。?lt;/p>
     * <ul>
     *     <li><b>入?yún)㈩?lèi)別</b>:表單參數(shù)方式,Content-Type=application/x-www-form-urlencoded
     *     <li><b>定義方式</b>: 在方法形參的位置,把每個(gè)參數(shù)都平鋪開(kāi)來(lái)</li>
     *     <li><b>調(diào)用方式</b>: 入?yún)⒎旁诒韱沃?,且Content-Type=application/x-www-form-urlencoded</li>
     *     <li><b>兼容的請(qǐng)求方式</b>:POST PUT DELETE</li>
     *     <li><b>適用場(chǎng)景</b>:雖然這種傳參方式,適用于POST PUT DELETE等請(qǐng)求方式,但是一般偏向于應(yīng)用在 用<b>POST</b>或b>PUT</b>方式去發(fā)送的表單數(shù)據(jù),且參數(shù)個(gè)數(shù)少,且表單字段都是普通類(lèi)型(即表單字段不是File文件),</li>
     *     <li><b>優(yōu)點(diǎn)</b>:方便簡(jiǎn)單</li>
     *     <li><b>缺點(diǎn)</b>:1)參數(shù)個(gè)數(shù)如果過(guò)多,方法體結(jié)構(gòu)會(huì)顯得很臃腫</li>
     * </ul>
     */
    @RequestMapping(value = "/test1_requestparam")
    public String test1(String name, @RequestParam(name = "age", required = false) Integer age, Boolean enable, HttpServletRequest request) {
        // 從request中獲取一些接口請(qǐng)求時(shí)的元數(shù)據(jù)信息,包括請(qǐng)求方式,Content-type等
        String requestMetaInfo = String.format("method: [%s], uri: [%s], Content-Type: [%s] ", request.getMethod(), request.getRequestURI(),  request.getHeader("Content-Type"));

        return requestMetaInfo + " ---> SUCCESS! name = " + name + ", age = " + age + ", enable = " + enable;
    }
}

調(diào)用case

注意看上面這個(gè)/param_type/body_form_urlencoded/test1_requestparam接口的定義方式,它并沒(méi)有指定請(qǐng)求方式,因此它支持GET POST PUT DELETE等所有的請(qǐng)求方式(已經(jīng)過(guò)驗(yàn)證)——經(jīng)過(guò)實(shí)測(cè)發(fā)現(xiàn),當(dāng)請(qǐng)示方式為GET 的時(shí)候,后端代碼獲取不到入?yún)?!而?dāng)請(qǐng)求方式為POST PUT DELETE的時(shí)候,后端可以獲取到入?yún)ⅰ?br />下面是示例

GET,傳參失敗

在這里插入圖片描述

可以看到,沒(méi)有獲取到入?yún)ⅲ?/p>

POST PUT DELETE 傳參成功

為了節(jié)約文章篇幅,下面只以POST 請(qǐng)求方式的調(diào)用結(jié)果為例,看是否可以在controller代碼中獲取到調(diào)用方傳過(guò)來(lái)的實(shí)參。

在這里插入圖片描述

可以看到,參數(shù)都獲取到了。

3.2.2 接口定義方式2:用一個(gè)實(shí)例來(lái)接收入?yún)?/h4>
  • 定義方式: 把入?yún)⒎庋b到一個(gè)實(shí)體中,且實(shí)體一定不能使用@RequestParam@RequestBody注解修飾
  • 兼容的請(qǐng)求方式POST PUT DELETE,注意,不兼容GET請(qǐng)示方式
  • 適用場(chǎng)景:雖然這種傳參方式,適用于POST PUT DELETE等請(qǐng)求方式,但是一般偏向于應(yīng)用在 用POSTPUT方式去發(fā)送的表單數(shù)據(jù),且表單字段都是普通類(lèi)型(即表單字段不是File文件)
  • 優(yōu)點(diǎn):方便簡(jiǎn)單,不管表單字段個(gè)個(gè)數(shù)多或少,一般如果表單字段類(lèi)型沒(méi)有File文件類(lèi)型的,都可以使用這種方式
  • 缺點(diǎn):缺點(diǎn)的話(huà)就是針對(duì)Content-Type=application/x-www-form-urlencoded這種入?yún)⒎绞絹?lái)說(shuō)了:不能上傳文件

代碼

package com.su.demo.controller.param_type;

import cn.hutool.core.io.IoUtil;
import com.su.demo.bean.dto.TeacherDTO;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.Map;

@RestController
@RequestMapping(value = "/param_type/body_form_urlencoded")
public class TestFormUrlEncodeController {

    /**
     * <p>注意,如果使用GET請(qǐng)求方式,則后端獲取不到入?yún)ⅲ。。≈恢С諴OST PUT DELETE</p>
     * <p>且形參定義那里,一定不能使用{@link RequestParam}修飾</p>
     * <ul>
     *     <li><b>入?yún)㈩?lèi)別</b>:表單參數(shù)方式,Content-Type=application/x-www-form-urlencoded
     *     <li><b>定義方式</b>: 把入?yún)⒎庋b到一個(gè)實(shí)體中(入?yún)€(gè)數(shù)多于5個(gè)時(shí)一般用這種方式)</li>
     *     <li><b>調(diào)用方式</b>: 入?yún)⒎旁诒韱沃?,且Content-Type=application/x-www-form-urlencoded</li>
     *     <li><b>兼容的請(qǐng)求方式</b>:POST PUT DELETE</li>
     *     <li><b>適用場(chǎng)景</b>:雖然這種傳參方式,適用于POST PUT DELETE等請(qǐng)求方式,但是一般偏向于應(yīng)用在 用<b>POST</b>或<b>PUT</b>方式去發(fā)送的表單數(shù)據(jù),且表單字段都是普通類(lèi)型(即表單字段不是File文件),</li>
     *     <li><b>優(yōu)點(diǎn)</b>:方便簡(jiǎn)單,不管表單字段個(gè)個(gè)數(shù)多或少,一般如果表單字段類(lèi)型沒(méi)有File文件類(lèi)型的,都可以使用這種方式</li>
     *     <li><b>缺點(diǎn)</b>:缺點(diǎn)的話(huà)就是針對(duì)Content-Type=application/x-www-form-urlencoded這種入?yún)⒎绞絹?lái)說(shuō)了:不能上傳文件</li>
     * </ul>
     */
    @RequestMapping(value = "/test2_entity")
    public String test2(TeacherDTO teacherDTO, HttpServletRequest request) {
        // 從request中獲取一些接口請(qǐng)求時(shí)的元數(shù)據(jù)信息,包括請(qǐng)求方式,Content-type等
        String requestMetaInfo = String.format("method: [%s], uri: [%s], Content-Type: [%s] ", request.getMethod(), request.getRequestURI(),  request.getHeader("Content-Type"));

        return requestMetaInfo + " ---> SUCCESS! teacherDTO = " + teacherDTO;
    }

}

調(diào)用case

注意看上面這個(gè)/param_type/body_form_urlencoded/test2_entity接口的定義方式,它并沒(méi)有指定請(qǐng)求方式,因此它支持GET POST PUT DELETE等所有的請(qǐng)求方式(已經(jīng)過(guò)驗(yàn)證)——經(jīng)過(guò)實(shí)測(cè)發(fā)現(xiàn),當(dāng)請(qǐng)示方式為GET 的時(shí)候,后端代碼獲取不到入?yún)?!而?dāng)請(qǐng)求方式為POST PUT DELETE的時(shí)候,后端可以獲取到入?yún)ⅰ?br />下面是示例

GET,傳參失敗

在這里插入圖片描述

可以看到,沒(méi)有獲取到入?yún)ⅲ?/p>

POST PUT DELETE 傳參成功

為了節(jié)約文章篇幅,下面只以PUT 請(qǐng)求方式的調(diào)用結(jié)果為例,看是否可以在controller代碼中獲取到調(diào)用方傳過(guò)來(lái)的實(shí)參。

在這里插入圖片描述

可以看到,參數(shù)都獲取到了。

3.2.3 接口定義方式3:用原生的HttpServletRequest接收參數(shù)

  • 定義方式: 用原生的HttpServletRequest接收參數(shù)
  • 兼容的請(qǐng)求方式POST PUT DELETE,注意,不兼容GET請(qǐng)示方式
  • 適用場(chǎng)景:由于當(dāng)請(qǐng)求的Content-Type=application/x-www-form-urlencoded時(shí),只支持GET請(qǐng)求方式,并且即使是GET請(qǐng)求方式能獲取到入?yún)⒘耍蟮男r?yàn)和處理也很麻煩,所以一般不用這種方式來(lái)接收Content-Type=application/x-www-form-urlencoded的請(qǐng)求
  • 優(yōu)點(diǎn):方便簡(jiǎn)單,且這接收入?yún)⒌姆绞?,直接調(diào)用方用GET的請(qǐng)求方式傳參
  • 缺點(diǎn):
    • 1)需要自己在代碼中顯式的從request的inputStream流【獲取+轉(zhuǎn)換+解碼】數(shù)據(jù),很麻煩
    • 2)如果請(qǐng)求方式是POST PUT DELETE等,同時(shí)Content-Type=application/x-www-form-urlencoded,則無(wú)法將入?yún)鞯胶竺娲a中!

代碼

package com.su.demo.controller.param_type;

import cn.hutool.core.io.IoUtil;
import com.su.demo.bean.dto.TeacherDTO;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.Map;

@RestController
@RequestMapping(value = "/param_type/body_form_urlencoded")
public class TestFormUrlEncodeController {

    /**
     * <p>注意,只支持GET請(qǐng)求方式,如果使用POST、PUT、DELETE請(qǐng)求方式,則后端獲取不到入?yún)ⅲ。。?lt;/p>
     * <ul>
     *     <li><b>入?yún)㈩?lèi)別</b>:表單參數(shù)方式,Content-Type=application/x-www-form-urlencoded
     *     <li><b>定義方式</b>: 在方法形參的位置,用{@link HttpServletRequest}來(lái)接收入?yún)?lt;/li>
     *     <li><b>調(diào)用方式</b>: 入?yún)⒎旁诒韱沃?,且Content-Type=application/x-www-form-urlencoded</li>
     *     <li><b>兼容的請(qǐng)求方式</b>:GET</li>
     *     <li><b>適用場(chǎng)景</b>:由于當(dāng)請(qǐng)求的Content-Type=application/x-www-form-urlencoded時(shí),只支持GET請(qǐng)求方式,
     *     并且即使是GET請(qǐng)求方式能獲取到入?yún)⒘?,之后的校?yàn)和處理也很麻煩,所以一般不用這種方式來(lái)接收Content-Type=application/x-www-form-urlencoded的請(qǐng)求</li>
     *     <li><b>優(yōu)點(diǎn)</b>:方便簡(jiǎn)單,且這接收入?yún)⒌姆绞?,直接調(diào)用方用GET的請(qǐng)求方式傳參</li>
     *     <li><b>缺點(diǎn)</b>:1)需要自己在代碼中顯式的從request的inputStream流【獲取+轉(zhuǎn)換+解碼】數(shù)據(jù),很麻煩
     *                    2)如果請(qǐng)求方式是POST PUT DELETE等,同時(shí)Content-Type=application/x-www-form-urlencoded,則無(wú)法將入?yún)鞯胶竺娲a中!
     *      </li>
     * </ul>
     */
    @RequestMapping(value = "/test3_request")
    public String test3(HttpServletRequest request) throws IOException {
        // 從request中獲取一些接口請(qǐng)求時(shí)的元數(shù)據(jù)信息,包括請(qǐng)求方式,Content-type等
        String requestMetaInfo = String.format("method: [%s], uri: [%s], Content-Type: [%s] ", request.getMethod(), request.getRequestURI(),  request.getHeader("Content-Type"));

        ServletInputStream inputStream = request.getInputStream();
        String inputStr = IoUtil.read(inputStream, "UTF-8");
        String decodeRes = URLDecoder.decode(inputStr, "UTF-8");

        return requestMetaInfo + " ---> SUCCESS! " + inputStr + ", decodeResult = " + decodeRes;
    }

}

調(diào)用case

注意看上面這個(gè)/param_type/body_form_urlencoded/test3_request接口的定義方式,它并沒(méi)有指定請(qǐng)求方式,因此它支持GET POST PUT DELETE等所有的請(qǐng)求方式(已經(jīng)過(guò)驗(yàn)證)——但是經(jīng)過(guò)實(shí)測(cè)發(fā)現(xiàn),只有當(dāng)請(qǐng)示方式為GET 的時(shí)候,后端代碼才能獲取到入?yún)?!而?dāng)請(qǐng)求方式為POST PUT DELETE的時(shí)候,后端獲取入?yún)⑹ ?br />下面是示例

GET,傳參成功

在這里插入圖片描述

可以看到,獲取到入?yún)ⅲ?/p>

POST PUT DELETE 傳參失敗

為了節(jié)約文章篇幅,下面只以POST 請(qǐng)求方式的調(diào)用結(jié)果為例,看是否可以在controller代碼中獲取到調(diào)用方傳過(guò)來(lái)的實(shí)參。

在這里插入圖片描述

可以看到,沒(méi)有獲取到參數(shù)!

3.2.4 (error)接口定義方式4:用Map接收參數(shù)

提前說(shuō)明:這是一種錯(cuò)誤的定義方式,這種方式,無(wú)論是否在map前面添加RequestParam還是RequestBody, 后端代碼都獲取不到 Content-Type=application/x-www-form-urlencoded類(lèi)型請(qǐng)求的入?yún)ⅲ。。?/p>

  • 定義方式: 用Map接收參數(shù)

代碼

package com.su.demo.controller.param_type;

import cn.hutool.core.io.IoUtil;
import com.su.demo.bean.dto.TeacherDTO;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.Map;

@RestController
@RequestMapping(value = "/param_type/body_form_urlencoded")
public class TestFormUrlEncodeController {

    /**
     * <p>這是一種錯(cuò)誤的定義方式,這種方式,無(wú)論是否在map前面添加{@link RequestParam}還是{@link RequestBody}, 代碼都獲取不到 Content-Type=application/x-www-form-urlencoded類(lèi)型請(qǐng)求的入?yún)ⅲ。。?lt;/p>
     * <ul>
     *     <li><b>入?yún)㈩?lèi)別</b>:表單參數(shù)方式,Content-Type=application/x-www-form-urlencoded
     *     <li><b>定義方式</b>: 在方法形參的位置,用Map來(lái)接收入?yún)?lt;/li>
     *     <li><b>調(diào)用方式</b>: 入?yún)⒎旁诒韱沃?,且Content-Type=application/x-www-form-urlencoded</li>
     * </ul>
     */
    @RequestMapping(value = "/test4_map")
    public String test4(Map<String, String> paramMap, HttpServletRequest request) {
        // 從request中獲取一些接口請(qǐng)求時(shí)的元數(shù)據(jù)信息,包括請(qǐng)求方式,Content-type等
        String requestMetaInfo = String.format("method: [%s], uri: [%s], Content-Type: [%s] ", request.getMethod(), request.getRequestURI(),  request.getHeader("Content-Type"));

        String name = paramMap.get("name");
        // 判斷:如果paramMap.get("age")為null,則age賦默認(rèn)值0;否則進(jìn)行入?yún)㈩?lèi)型的轉(zhuǎn)換
        Integer age = null == paramMap.get("age") ? 0: Integer.parseInt(paramMap.get("age"));

        return requestMetaInfo + " ---> SUCCESS! name = " + name + ", age = " + age;
    }

}

調(diào)用case

無(wú)論哪種請(qǐng)求方式,后端獲取入?yún)⒍际。∠旅嬉?code>PUT請(qǐng)求方式作為示例
下面是示例

PUT,傳參失敗

在這里插入圖片描述

可以看到,獲取不到入?yún)ⅲ?/p>

3.2.5 (error)接口定義方式5:每個(gè)參數(shù)都平鋪開(kāi)來(lái),并嘗試獲取File文件入?yún)?/h4>

先說(shuō)結(jié)論,雖然在下面方法定義的,=形參中添加了MultipartFile,但是如果調(diào)用接口的時(shí)候入?yún)㈩?lèi)型是Content-Type=application/x-www-form-urlencoded, 那由于Content-Type=application/x-www-form-urlencoded入?yún)㈩?lèi)型限制了入?yún)⒕蜔o(wú)法將【文件】傳過(guò)來(lái),所以該方法的MultipartFile對(duì)象始終為空!

  • 定義方式: 方法形參的位置,把每個(gè)參數(shù)都平鋪開(kāi)來(lái),也可以使用@RequestParam注解,是時(shí)嘗試使用MultipartFile類(lèi)型入?yún)?,去接收文?/li>

代碼

package com.su.demo.controller.param_type;

import cn.hutool.core.io.IoUtil;
import com.su.demo.bean.dto.TeacherDTO;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.Map;

@RestController
@RequestMapping(value = "/param_type/body_form_urlencoded")
public class TestFormUrlEncodeController {

    /**
     * <p>
     *     雖然在方法定義這里,形參中添加了MultipartFile,但是如果調(diào)用接口的時(shí)候入?yún)㈩?lèi)型是Content-Type=application/x-www-form-urlencoded,
     *     那由于Content-Type=application/x-www-form-urlencoded入?yún)㈩?lèi)型限制了入?yún)⒕蜔o(wú)法將【文件】傳過(guò)來(lái),所以該方法的MultipartFile對(duì)象始終為空!
     * </p>
     * <ul>
     *     <li><b>入?yún)㈩?lèi)別</b>:表單參數(shù)方式,Content-Type=application/x-www-form-urlencoded
     *     <li><b>定義方式</b>: 在方法形參的位置,把每個(gè)參數(shù)都平鋪開(kāi)來(lái)</li>
     *     <li><b>調(diào)用方式</b>: 入?yún)⒎旁诒韱沃?,且Content-Type=application/x-www-form-urlencoded</li>
     * </ul>
     */
    @RequestMapping(value = "/test5_requestparam_file")
    public String test5(String name, Integer age, Boolean enable, MultipartFile myfile, HttpServletRequest request) throws IOException {
        // 從request中獲取一些接口請(qǐng)求時(shí)的元數(shù)據(jù)信息,包括請(qǐng)求方式,Content-type等
        String requestMetaInfo = String.format("method: [%s], uri: [%s], Content-Type: [%s] ", request.getMethod(), request.getRequestURI(),  request.getHeader("Content-Type"));
        String fileName = null;
        if (null != myfile) {
            fileName = myfile.getOriginalFilename();
        }

        return requestMetaInfo + " ---> SUCCESS! name = " + name + ", age = " + age + ", enable = " + enable + ", fileName = " + fileName;
    }

}

調(diào)用case

實(shí)測(cè)發(fā)現(xiàn),不管是哪種請(qǐng)求方式,只要請(qǐng)求的時(shí)候Content-Type=application/x-www-form-urlencoded,那都無(wú)法將文件傳給后端!
下面是用POST請(qǐng)求方式作示例:

在這里插入圖片描述

以上就是SpringBoot接收接口入?yún)⒌姆绞叫〗Y(jié)的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot接收接口入?yún)⒌馁Y料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論