1. 程式人生 > >Restful介面傳入多引數的問題和解決方案

Restful介面傳入多引數的問題和解決方案

結論:

restful風格的介面不支援多個引數

注:本文指的是通過json序列化引數的情況

1. 前置

一個定義用來測試的MyParam類

public class MyParam {
    private String str;
    private Integer integer;
    // 省略 getter和setter……
    }

我在做測試的是用了Chrome的外掛Advanced REST client,可以模擬瀏覽器傳送各種請求,並自定義header和body。
測試的時候需要使用post方式,並在http請求header中加入

accept
: application/json content-type: application/json

然後在htpp請求的Body中,輸入json格式的引數,如{"str":"bb","integer":3}

以下是幾種多引數介面的形式,以及輸入引數,以及解析結果。

2. 第一種:兩個String引數

@POST
@Path("demo")
public Result function(String param1, String param2);

傳入的引數:
{"param1":"bb","param2":"cc"}
解析出來的引數:

param1: "{"param1":"
bb","param2":"cc"}" param2: ""

這樣的風格,傳輸過來的引數,讀取的時候會讀取request body中的inputStream,然後兩個引數迴圈解析,解析完第一個引數的時候,會關閉inputStream,第二個引數再去讀取inputStream的時候,讀取到的就是空。
這樣的話,傳入的引數全部會賦值給第一個String物件,而第二個String解析出來後就是空字串。

3. 第二種:一個物件引數,一個String引數

對於 第一個引數是封裝物件的情況,能解析出來第一個物件,而第二個引數也是拿不到。
這種情況下不會報錯,只是解析第一個物件的時候沒有問題,解析第二個String拿到的就是空字串。

@POST
@Path("demo")
@Consumes({MediaType.JSON})
public Result function(MyParam myParam, String param);

傳入的引數:
{"str":"helo","integer":2},"string":"test"
解析出來的引數:

param1: 能正確解析物件myParam,其兩個屬效能正確賦值。
param2: ""

4. 第三種:一個String引數,一個物件引數

如果把兩個引數的位置交換,則會把傳入的引數全部解析給第一個String,而解析第二個物件的時候,由於拿到的資料是空,所以會報錯。如下:

@POST
@Path("demo")
public Result function(String param, MyParam myParam);

傳入的引數:
{"str":"helo","integer":2},"string":"test"
解析出來的引數:

param1: "{"str":"helo","integer":2},"string":"test""
param2: 會報錯

5.解決方法

要解決傳入多個引數的問題,有幾個思路:
1. 封裝物件,把要傳的多個引數封裝成一個物件傳入
2. 在訪問路徑中嵌入變數,使用@PathVariable註解,在請求路徑中寫 “/demo/{1}/{2}”,然後在請求路徑中相應的位置替換為要穿的引數即可,這種也只適用於包裝類,如String。
3. 改變請求的content type,使用content-type: application/x-www-form-urlencoded,這種使用form表單提交的形式,可以傳入兩個引數,要結合使用@FormParam註解

6.關於使用form形式傳入引數

介面的定義形式要修改

@POST
@Path("demo")
@Consumes({MediaType.APPLICATION_FORM_URLENCODED})
public Result function(@FormParam(value="string1")String string1, @FormParam(value="string2")String string2);

請求時,header引數要修改

accept: application/json
content-type: application/x-www-form-urlencoded

請求Body中使用form形式

string1=wo&string2=kan

然後就可以正確解析到兩個引數的值
解析出來的引數:

string1: wo
string2: kan