Jersey Restful接口如何獲取參數(shù)的問題
緣起
工作時(shí)使用java開發(fā)服務(wù)器后臺(tái),用Jersey寫Restful接口,發(fā)現(xiàn)有一個(gè)Post方法始終獲取不到參數(shù),查了半天,發(fā)現(xiàn)時(shí)獲取參數(shù)的注釋不太對,將@formparam寫成了@queryparam,發(fā)現(xiàn)了這個(gè)改過來就好了,順便整理了一下不同參數(shù)的作用。
簡述
獲取URI的參數(shù)
獲取Get請求的參數(shù)
獲取Post類型的參數(shù)
添加參數(shù)默認(rèn)值
獲取Map參數(shù)
1.@PathParam
使用該注釋獲取參數(shù)時(shí)可以獲取URI中制定規(guī)則的參數(shù)
例如:
//該類的路徑為/user
@GET
@Path("{username"})
@Produces(MediaType.APPLICATION_JSON)
public User getUser(@PathParam("username") String userName) {
...}
當(dāng)瀏覽器請求
http://localhost:8080/user/jack
時(shí),username的值就是jack。請注意,這里的username并不是說key的值就是username,value是jack,而是說/user/后面就跟著username,這里的username只是一個(gè)變量。
2.@QueryParam
該參數(shù)用于獲取Get請求中的查詢參數(shù),他和上一個(gè)的區(qū)別是它是通過URI中的?符號(hào)來實(shí)現(xiàn)的。
比如:
@GET
@Path("/user")
@Produces("text/plain")
public User getUser(@QueryParam("name") String name, @QueryParam("age") int age) {
...}
當(dāng)url的請求是
http://localhost:8080/user?name=cesar&age=21
時(shí),此時(shí)函數(shù)獲取的參數(shù)就是name=cesar而age=21;
3.@FormPara
顧名思義,是從Post請求的表單中獲取數(shù)據(jù)。
@POST
@Consumes("application/x-www-form-urlencoded")
publicvoid post(@FormParam("name") String name) {
// Store the message
}
4.默認(rèn)參數(shù)值DefaultValue
當(dāng)你希望在函數(shù)獲取參數(shù)時(shí)參數(shù)有一個(gè)默認(rèn)值,那么就可以使用該注釋,它的使用方法如下
@GET
@Path("/user")
@Produces("text/plain")
public User getUser(@QueryParam("name") String name, @DefaultValue("26") @QueryParam("age") int age) {
...}
那么當(dāng)請求age參數(shù)時(shí)如果age沒有賦值,就會(huì)默認(rèn)為26.
5.使用Map的參數(shù)@Context
在一個(gè)大型的server中,由于參數(shù)的多變,參數(shù)結(jié)構(gòu)的調(diào)整很容易遇到問題,這時(shí)候就可以考慮使用@Context來進(jìn)行注釋了。例子如下:
@GET
public String get(@Context UriInfo ui) {
MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
MultivaluedMap<String, String> pathParams = ui.getPathParameters();
}
從例子中我們可以看出,其實(shí)Context就是其他幾個(gè)參數(shù)的集合而已,只要熟練掌握了這幾種參數(shù)以及他們代表的意義,你就可以熟練的操作Jersey了!
Restful接口傳入多參數(shù)的問題及解決方案
結(jié)論:
restful風(fēng)格的接口不支持多個(gè)參數(shù)
注:本文指的是通過json序列化參數(shù)的情況
1. 前置
一個(gè)定義用來測試的MyParam類
public class MyParam {
private String str;
private Integer integer;
// 省略 getter和setter……
}
我在做測試的是用了Chrome的插件Advanced REST client,可以模擬瀏覽器發(fā)送各種請求,并自定義header和body。
測試的時(shí)候需要使用post方式,并在http請求header中加入
accept: application/json content-type: application/json
然后在htpp請求的Body中,輸入json格式的參數(shù),如{"str":"bb","integer":3}。
以下是幾種多參數(shù)接口的形式,以及輸入?yún)?shù),以及解析結(jié)果。
2. 第一種:兩個(gè)String參數(shù)
@POST
@Path("demo")
public Result function(String param1, String param2);
傳入的參數(shù):
{"param1":"bb","param2":"cc"}
解析出來的參數(shù):
param1: "{"param1":"bb","param2":"cc"}"
param2: ""
這樣的風(fēng)格,傳輸過來的參數(shù),讀取的時(shí)候會(huì)讀取request body中的inputStream,然后兩個(gè)參數(shù)循環(huán)解析,解析完第一個(gè)參數(shù)的時(shí)候,會(huì)關(guān)閉inputStream,第二個(gè)參數(shù)再去讀取inputStream的時(shí)候,讀取到的就是空。
這樣的話,傳入的參數(shù)全部會(huì)賦值給第一個(gè)String對象,而第二個(gè)String解析出來后就是空字符串。
3. 第二種:一個(gè)對象參數(shù),一個(gè)String參數(shù)
對于 第一個(gè)參數(shù)是封裝對象的情況,能解析出來第一個(gè)對象,而第二個(gè)參數(shù)也是拿不到。
這種情況下不會(huì)報(bào)錯(cuò),只是解析第一個(gè)對象的時(shí)候沒有問題,解析第二個(gè)String拿到的就是空字符串。
@POST
@Path("demo")
@Consumes({MediaType.JSON})
public Result function(MyParam myParam, String param);
傳入的參數(shù):
{"str":"helo","integer":2},"string":"test"
解析出來的參數(shù):
param1: 能正確解析對象myParam,其兩個(gè)屬性能正確賦值。
param2: ""
4. 第三種:一個(gè)String參數(shù),一個(gè)對象參數(shù)
如果把兩個(gè)參數(shù)的位置交換,則會(huì)把傳入的參數(shù)全部解析給第一個(gè)String,而解析第二個(gè)對象的時(shí)候,由于拿到的數(shù)據(jù)是空,所以會(huì)報(bào)錯(cuò)。如下:
@POST
@Path("demo")
public Result function(String param, MyParam myParam);
傳入的參數(shù):
{"str":"helo","integer":2},"string":"test"
解析出來的參數(shù):
param1: "{"str":"helo","integer":2},"string":"test""
param2: 會(huì)報(bào)錯(cuò)
5.解決方法
要解決傳入多個(gè)參數(shù)的問題,有幾個(gè)思路:
1. 封裝對象,把要傳的多個(gè)參數(shù)封裝成一個(gè)對象傳入
2. 在訪問路徑中嵌入變量,使用@PathVariable注解,在請求路徑中寫 “/demo/{1}/{2}”,然后在請求路徑中相應(yīng)的位置替換為要穿的參數(shù)即可,這種也只適用于包裝類,如String。
3. 改變請求的content type,使用content-type: application/x-www-form-urlencoded,這種使用form表單提交的形式,可以傳入兩個(gè)參數(shù),要結(jié)合使用@FormParam注解
6.關(guān)于使用form形式傳入?yún)?shù)
接口的定義形式要修改
@POST
@Path("demo")
@Consumes({MediaType.APPLICATION_FORM_URLENCODED})
public Result function(@FormParam(value="string1")String string1, @FormParam(value="string2")String string2);
請求時(shí),header參數(shù)要修改
accept: application/json content-type: application/x-www-form-urlencoded
請求Body中使用form形式
string1=wo&string2=kan
然后就可以正確解析到兩個(gè)參數(shù)的值
解析出來的參數(shù):
string1: wo
string2: kan
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
如何解決SpringBoot集成百度UEditor圖片上傳后直接訪問404
在本篇文章里小編給大家整理的是一篇關(guān)于如何解決SpringBoot集成百度UEditor圖片上傳后直接訪問404相關(guān)文章,需要的朋友們學(xué)習(xí)下。2019-11-11
Java生產(chǎn)者消費(fèi)者模式實(shí)例分析
這篇文章主要介紹了Java生產(chǎn)者消費(fèi)者模式,結(jié)合實(shí)例形式分析了java生產(chǎn)者消費(fèi)者模式的相關(guān)組成、原理及實(shí)現(xiàn)方法,需要的朋友可以參考下2019-03-03
關(guān)于java.lang.IncompatibleClassChangeError錯(cuò)誤解決方案
最近開發(fā)中遇到類沖突報(bào)錯(cuò) java.lang.IncompatibleClassChangeError,所以下面這篇文章主要給大家介紹了關(guān)于java.lang.IncompatibleClassChangeError錯(cuò)誤的解決方案,需要的朋友可以參考下2024-02-02
Hadoop 使用IntelliJ IDEA 進(jìn)行遠(yuǎn)程調(diào)試代碼的配置方法
這篇文章主要介紹了Hadoop 使用IntelliJ IDEA 進(jìn)行遠(yuǎn)程調(diào)試代碼的配置方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04
Java面向?qū)ο蠡A(chǔ)知識(shí)之封裝,繼承,多態(tài)和抽象
這篇文章主要介紹了Java面向?qū)ο蟮姆庋b,繼承,多態(tài)和抽象,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有很好的幫助,需要的朋友可以參考下2021-11-11
List對象去重和按照某個(gè)字段排序的實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄狶ist對象去重和按照某個(gè)字段排序的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05
關(guān)于spring.factories的常用配置項(xiàng)說明
這篇文章主要介紹了關(guān)于spring.factories的常用配置項(xiàng)說明,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
Java底層基于鏈表實(shí)現(xiàn)集合和映射--集合Set操作詳解
這篇文章主要介紹了Java底層基于鏈表實(shí)現(xiàn)集合和映射集合Set操作,結(jié)合實(shí)例形式詳細(xì)分析了Java使用鏈表實(shí)現(xiàn)集合和映射相關(guān)原理、操作技巧與注意事項(xiàng),需要的朋友可以參考下2020-03-03

