您好,登錄后才能下訂單哦!
本篇內容介紹了“SpringBoo中Get請求參數有哪些”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
首先得搭建一個web應用才有可能繼續后續的測試,借助SpringBoot搭建一個web應用屬于比較簡單的活;
創建一個maven項目,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>
添加項目啟動類Application.cass
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class); } }
在演示請求參數的解析實例中,我們使用終端的curl命令來發起http請求(主要原因是截圖上傳太麻煩,還是終端的文本輸出比較方便;缺點是不太直觀)
接下來我們正式進入參數解析的妖嬈姿勢篇,會介紹一下常見的一些case(并不能說包含了所有的使用case)
下面所有的方法都放在 ParamGetRest
這個Controller中
@RestController @RequestMapping(path = "get") public class ParamGetRest { }
直接使用HttpServletRequest
來獲取請求參數,屬于比較原始,但是靈活性最高的使用方法了。
常規使用姿勢是方法的請求參數中有一個HttpServletRequest
,我們通過ServletRequest#getParameter(參數名)
來獲取具體的請求參數,下面演示返回所有請求參數的case
@GetMapping(path = "req") public String requestParam(HttpServletRequest httpRequest) { Map<String, String[]> ans = httpRequest.getParameterMap(); return JSON.toJSONString(ans); }
測試case,注意下使用curl請求參數中有中文時,進行了url編碼(后續會針對這個問題進行說明)
? ~ curl 'http://127.0.0.1:8080/get/req?name=yihuihiu&age=19' {"name":["yihuihiu"],"age":["19"]}% ? ~ curl 'http://127.0.0.1:8080/get/req?name=%E4%B8%80%E7%81%B0%E7%81%B0&age=19' {"name":["一灰灰"],"age":["19"]}%
使用HttpServletRequest獲取請求參數,還有另外一種使用case,不通過參數傳遞的方式獲取Request實例,而是借助RequestContextHolder
;這樣的一個好處就是,假設我們想寫一個AOP,攔截GET請求并輸出請求參數時,可以通過下面這種方式來處理
@GetMapping(path = "req2") public String requestParam2() { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); String name = request.getParameter("name"); return "param Name=" + name; }
測試case
? ~ curl 'http://127.0.0.1:8080/get/req2?name=%E4%B8%80%E7%81%B0%E7%81%B0&age=19' param Name=一灰灰%
這種解析方式比較厲害了,將GET參數與方法的參數根據參數名進行映射,從感官上來看,就像是直接調用這個一樣
@GetMapping(path = "arg") public String argParam(String name, Integer age) { return "name: " + name + " age: " + age; }
針對上面提供的方式,我們的測試自然會區分為下面幾種,看下會怎樣
正好兩個參數,與定義一直
缺少一個請求參數
多一個請求參數
參數類型不一致
# 參數解析正常 ? ~ curl 'http://127.0.0.1:8080/get/arg?name=%E4%B8%80%E7%81%B0%E7%81%B0&age=19' name: 一灰灰 age: 19% # 缺少一個參數時,為null ? ~ curl 'http://127.0.0.1:8080/get/arg?name=%E4%B8%80%E7%81%B0%E7%81%B0' name: 一灰灰 age: null% # 多了一個參數,無法被解析 ? ~ curl 'http://127.0.0.1:8080/get/arg?name=%E4%B8%80%E7%81%B0%E7%81%B0&age=19&id=10' name: 一灰灰 age: 19% # 類型不一致,500 ? ~ curl 'http://127.0.0.1:8080/get/arg?name=%E4%B8%80%E7%81%B0%E7%81%B0&age=haha' -i HTTP/1.1 500 Content-Length: 0 Date: Sat, 24 Aug 2019 01:45:14 GMT Connection: close
從上面實際的case可以看出,利用方法參數解析GET傳參時,實際效果是:
方法參數與GET傳參,通過參數簽名進行綁定
方法參數類型,需要與接收的GET傳參類型一致
方法參數非基本類型時,若傳參沒有,則為null;(也就是說如果為基本類型,無法轉null,拋異常)
實際的GET傳參可以多于方法定義的參數
接下來給一個數組傳參解析的實例
@GetMapping(path = "arg2") public String argParam2(String[] names, int size) { return "name: " + (names != null ? Arrays.asList(names) : "null") + " size: " + size; }
測試case如下,傳數組時參數值用逗號分隔;基本類型,必須傳參,否則解析異常
? ~ curl 'http://127.0.0.1:8080/get/arg2?name=yihui,erhui&size=2' name: null size: 2% ? ~ curl 'http://127.0.0.1:8080/get/arg2?name=yihui,erhui' -i HTTP/1.1 500 Content-Length: 0 Date: Sat, 24 Aug 2019 01:53:30 GMT Connection: close
這種方式看起來和前面有些相似,但更加靈活,我們先看一下注解
@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RequestParam { // 指定請求參數名 String value() default ""; // 指定請求參數名 String name() default ""; // true表示發起請求時這個參數必須存在 boolean required() default true; String defaultValue() default ValueConstants.DEFAULT_NONE; }
有兩個參數需要注意,一個是name表示這個參數與GET傳參的哪個關聯;required表示這個參數是否可選
下面是一個簡單的使用方式
@GetMapping(path = "ano") public String anoParam(@RequestParam(name = "name") String uname, @RequestParam(name = "age", required = false) Integer age, @RequestParam(name = "uids", required = false) Integer[] uids) { return "name: " + uname + " age: " + age + " uids: " + (uids != null ? Arrays.asList(uids) : "null"); }
測試如下:
# 三個參數全在 ? ~ curl 'http://localhost:8080/get/ano?name=%E4%B8%80%E7%81%B0%E7%81%B0blog&age=18&uids=1,3,4' name: 一灰灰blog age: 18 uids: [1, 3, 4]% # age不傳 ? ~ curl 'http://localhost:8080/get/ano?name=%E4%B8%80%E7%81%B0%E7%81%B0blog&uids=1,3,4' name: 一灰灰blog age: null uids: [1, 3, 4]% # 必選參數name不傳時 ? ~ curl 'http://localhost:8080/get/ano?uids=1,3,4' -i HTTP/1.1 500 Content-Length: 0 Date: Sat, 24 Aug 2019 13:09:07 GMT Connection: close
使用RequestParam
注解時,如果指定了name/value
,這個參數就與指定的GETGET傳參關聯;如果不指定時,則根據參數簽名來關聯
下面給出兩個更有意思的使用方式,一個是枚舉參數解析,一個是Map容納參數,一個是數組參數解析
public enum TYPE { A, B, C; } @GetMapping(path = "enum") public String enumParam(TYPE type) { return type.name(); } @GetMapping(path = "enum2") public String enumParam2(@RequestParam TYPE type) { return type.name(); } @GetMapping(path = "mapper") public String mapperParam(@RequestParam Map<String, Object> params) { return params.toString(); } // 注意下面這個寫法,無法正常獲取請求參數,這里用來對比列出 @GetMapping(path = "mapper2") public String mapperParam2(Map<String, Object> params) { return params.toString(); } @GetMapping(path = "ano1") public String anoParam1(@RequestParam(name = "names") List<String> names) { return "name: " + names; } // 注意下面這個寫法無法正常解析數組 @GetMapping(path = "arg3") public String anoParam2(List<String> names) { return "names: " + names; }
測試case如下
? ~ curl 'http://localhost:8080/get/enum?type=A' A% ? ~ curl 'http://localhost:8080/get/enum2?type=A' A% ? ~ curl 'http://localhost:8080/get/mapper?type=A&age=3' {type=A, age=3}% ? ~ curl 'http://localhost:8080/get/mapper2?type=A&age=3' {}% ? ~ curl 'http://localhost:8080/get/ano1?names=yi,hui,ha' name: [yi, hui, ha]% ? ~ curl 'http://localhost:8080/get/arg3?names=yi,hui,ha' -i HTTP/1.1 500 Content-Length: 0 Date: Sat, 24 Aug 2019 13:50:55 GMT Connection: close
從測試結果可以知道:
GET傳參映射到枚舉時,根據enum.valueOf()
來實例的
如果希望使用Map來容納所有的傳參,需要加上注解@RequestParam
如果參數為List類型,必須添加注解@RequestParam
;否則用數組來接收
從請求的url路徑中解析參數,使用方法和前面的差別不大
@GetMapping(path = "url/{name}/{index}") public String urlParam(@PathVariable(name = "name") String name, @PathVariable(name = "index", required = false) Integer index) { return "name: " + name + " index: " + index; }
上面是一個常見的使用方式,對此我們帶著幾個疑問設計case
只有name沒有index,會怎樣?
有name,有index,后面還有路徑,會怎樣?
? ~ curl http://127.0.0.1:8080/get/url/yihhuihui/1 name: yihhuihui index: 1% ? ~ curl 'http://127.0.0.1:8080/get/url/yihhuihui' -i HTTP/1.1 500 Content-Length: 0 Date: Sat, 24 Aug 2019 13:27:08 GMT Connection: close ? ~ curl 'http://127.0.0.1:8080/get/url/yihhuihui/1/test' -i HTTP/1.1 500 Content-Length: 0 Date: Sat, 24 Aug 2019 13:27:12 GMT Connection: close
從path中獲取參數時,對url有相對嚴格的要求,注意使用
這種case,我個人用得比較多,特別是基于SpringCloud的生態下,借助Feign來調用第三方微服務,可以說是很舒爽了;下面看一下這種方式的使用姿勢
首先定義一個POJO
@Data public class BaseReqDO implements Serializable { private static final long serialVersionUID = 8706843673978981262L; private String name; private Integer age; private List<Integer> uIds; }
提供一個服務
@GetMapping(path = "bean") public String beanParam(BaseReqDO req) { return req.toString(); }
POJO中定義了三個參數,我們再測試的時候,看一下這些參數是否必選
# GET傳參與POJO中成員名進行關聯 ? ~ curl 'http://127.0.0.1:8080/get/bean?name=yihuihui&age=18&uIds=1,3,4' BaseReqDO(name=yihuihui, age=18, uIds=[1, 3, 4])% # 沒有傳參的屬性為null;因此如果POJO中成員為基本類型,則參數必傳 ? ~ curl 'http://127.0.0.1:8080/get/bean?name=yihuihui&age=18' BaseReqDO(name=yihuihui, age=18, uIds=null)%
“SpringBoo中Get請求參數有哪些”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。