ジャージークライアント:クエリパラメータとしてリストを追加する方法


81

クエリパラメータとしてリストを持つGETサービス用のJerseyクライアントを作成しています。ドキュメントによると、クエリパラメータとしてリストを持つことが可能です(この情報は@QueryParam javadocにもあります)、それをチェックしてください:

一般に、メソッドパラメータのJavaタイプは次のようになります。

  1. プリミティブ型であること。
  2. 単一のString引数を受け入れるコンストラクターがあります。
  3. 単一のString引数を受け入れるvalueOfまたはfromStringという名前の静的メソッドがあります(たとえば、Integer.valueOf(String)およびjava.util.UUID.fromString(String)を参照)。または
  4. List、Set、またはSortedSetであり、Tは上記の2または3を満たします。結果のコレクションは読み取り専用です。

パラメータに同じ名前の値が複数含まれている場合があります。この場合、4)のタイプを使用してすべての値を取得できます。

ただし、Jerseyクライアントを使用してリストクエリパラメータを追加する方法がわかりません。

代替ソリューションは次のとおりです。

  1. GETの代わりにPOSTを使用します。
  2. リストをJSON文字列に変換し、サービスに渡します。

サービスの適切なHTTP動詞はGETであるため、最初のものは適切ではありません。データ取得操作です。

あなたが私を助けることができないならば、2番目は私のオプションになります。:)

私もサービスを開発しているので、必要に応じて変更する場合があります。

ありがとう!

更新

クライアントコード(jsonを使用)

Client client = Client.create();

WebResource webResource = client.resource(uri.toString());

SearchWrapper sw = new SearchWrapper(termo, pagina, ordenacao, hits, SEARCH_VIEW, navegadores);

MultivaluedMap<String, String> params = new MultivaluedMapImpl();
params.add("user", user.toUpperCase()); 
params.add("searchWrapperAsJSON", (new Gson()).toJson(sw));

ClientResponse clientResponse = webResource .path("/listar")
                                            .queryParams(params)
                                            .header(HttpHeaders.AUTHORIZATION, AuthenticationHelper.getBasicAuthHeader())
                                            .get(ClientResponse.class);

SearchResultWrapper busca = clientResponse.getEntity(new GenericType<SearchResultWrapper>() {});

1
あなたは...ここジャージのクライアントコードを与えることができます
ヨーゲッシュプラジャーパティ

1
yogesh、クライアントコードを追加しました。
lsborg 2012

2
問題の説明を理解している場合は、同じキーに複数の値を追加することで、値のリストをクエリパラメーターとして渡すことができます。「searchWrapper」がキーであり、それに複数の値を渡したい場合:次のようなURLを作成します:// YourURL?searchWrapper = value1&searchWrapper = value2&searchWrapper = value3 MultivaluedMapがサポートしている場合は、同じキーに値を複数回挿入する必要があります。
Thamme Gowda 2013

1
ありがとう、@ ThammeGowda!私はそれをテストしていませんが、メソッドの状態を追加するためのMultivaluedMapjavadocとしてトリックを実行しているようです。指定されたキーの現在の値のリストに値を追加します
lsborg 2014年

回答:


119

@GET 文字列のリストをサポートします

セットアップ
Java:1.7
ジャージーバージョン:1.9

資源

@Path("/v1/test")

サブリソース

// receive List of Strings
@GET
@Path("/receiveListOfStrings")
public Response receiveListOfStrings(@QueryParam("list") final List<String> list){
    log.info("receieved list of size="+list.size());
    return Response.ok().build();
}

ジャージーテストケース

@Test
public void testReceiveListOfStrings() throws Exception {
    WebResource webResource = resource();
    ClientResponse responseMsg = webResource.path("/v1/test/receiveListOfStrings")
            .queryParam("list", "one")
            .queryParam("list", "two")
            .queryParam("list", "three")
            .get(ClientResponse.class);
    Assert.assertEquals(200, responseMsg.getStatus());
}

1
ありがとうございます。それはわたしを助ける。
Sapikelio 2015

62
他の人へのメモと同じように、ブラウザで直接URLを書き込む場合は、パラメータ名を繰り返す必要があります。..?list = one&list = two&list = three
エンディアン

2
これは本当にリストですか/順序は尊重されることが保証されていますか?ジャージーがリストとして返すのは多値マップのように思われるので、順序が保持されないという問題があるのではないかと思います
hayduke 2017

ええ。?list = one&list = two&list = threeはそれほど役に立ちません。リストとして= 1、2、3 -私は、文字列からリストに手動でParesにおけるなぜ...だとList<String> argList = List.of(argString.split("\\s*,\\s*"))
SES

30

単純な文字列以外のものを送信する場合は、適切なリクエスト本文を含むPOSTを使用するか、リスト全体を適切にエンコードされたJSON文字列として渡すことをお勧めします。ただし、単純な文字列では、各値をリクエストURLに適切に追加するだけで、Jerseyがそれを逆シリアル化します。したがって、次のエンドポイントの例を考えます。

@Path("/service/echo") public class MyServiceImpl {
    public MyServiceImpl() {
        super();
    }

    @GET
    @Path("/withlist")
    @Produces(MediaType.TEXT_PLAIN)
    public Response echoInputList(@QueryParam("list") final List<String> inputList) {
        return Response.ok(inputList).build();
    }
}

クライアントは、以下に対応するリクエストを送信します。

GET http://example.com/services/echo?list=Hello&list=Stay&list=Goodbye

これによりinputList、値「Hello」、「Stay」、および「Goodbye」を含むように逆シリアル化されます。


2
あなたの答えをありがとう知覚!しかし、Jerseyクライアントを使用してクエリパラメータとしてリストを使用してGETを実行できるかどうかを確認したいと思います。
lsborg 2012

1
私のクライアントはandroidとiosなので、クライアント側でそのようなリストを作成する方法を教えてください。明らかに、key = value&key = valuemanuallを作成したくない
nilesh

送信したらどうなりますlist[0]=Hello&list[1]=Stayか?それを管理する方法は?
user1735921 2018年

6

私はあなたが上で言及した代替ソリューションについてあなたに同意します

1. Use POST instead of GET;
2. Transform the List into a JSON string and pass it to the service.

あなたが追加できないことに、その真ListMultiValuedMap理由は、その独自の実装クラスでは、MultivaluedMapImpl文字列のキーと文字列値を受け入れる能力を有しています。次の図に示されています

ここに画像の説明を入力してください

それでも、次のコードを試すよりも、そういうことをしたいのです。

コントローラクラス

package net.yogesh.test;

import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

import com.google.gson.Gson;

@Path("test")
public class TestController {
       @Path("testMethod")
       @GET
       @Produces("application/text")
       public String save(
               @QueryParam("list") List<String> list) {

           return  new Gson().toJson(list) ;
       }
}

クライアントクラス

package net.yogesh.test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.ws.rs.core.MultivaluedMap;

import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.core.util.MultivaluedMapImpl;

public class Client {
    public static void main(String[] args) {
        String op = doGet("http://localhost:8080/JerseyTest/rest/test/testMethod");
        System.out.println(op);
    }

    private static String doGet(String url){
        List<String> list = new ArrayList<String>();
        list = Arrays.asList(new String[]{"string1,string2,string3"});

        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
        String lst = (list.toString()).substring(1, list.toString().length()-1);
        params.add("list", lst);

        ClientConfig config = new DefaultClientConfig();
        com.sun.jersey.api.client.Client client = com.sun.jersey.api.client.Client.create(config);
        WebResource resource = client.resource(url);

        ClientResponse response = resource.queryParams(params).type("application/x-www-form-urlencoded").get(ClientResponse.class);
        String en = response.getEntity(String.class);
        return en;
    }
}

これがお役に立てば幸いです。


ここでのベストアンサー!ありがとう+ 1
Haramoz19年

3

JSONクエリパラメータを使用したGETリクエスト

package com.rest.jersey.jerseyclient;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;

public class JerseyClientGET {

    public static void main(String[] args) {
        try {               

            String BASE_URI="http://vaquarkhan.net:8080/khanWeb";               
            Client client = Client.create();    
            WebResource webResource = client.resource(BASE_URI);

            ClientResponse response = webResource.accept("application/json").get(ClientResponse.class);

            /*if (response.getStatus() != 200) {
               throw new RuntimeException("Failed : HTTP error code : "
                + response.getStatus());
            }
*/
            String output = webResource.path("/msg/sms").queryParam("search","{\"name\":\"vaquar\",\"surname\":\"khan\",\"ext\":\"2020\",\"age\":\"34\""}").get(String.class);
            //String output = response.getEntity(String.class);

            System.out.println("Output from Server .... \n");
            System.out.println(output);                         

        } catch (Exception e) {

            e.printStackTrace();    
        }    
    }    
}

ポストリクエスト:

package com.rest.jersey.jerseyclient;

import com.rest.jersey.dto.KhanDTOInput;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.json.JSONConfiguration;

public class JerseyClientPOST {

    public static void main(String[] args) {
        try {

            KhanDTOInput khanDTOInput = new KhanDTOInput("vaquar", "khan", "20", "E", null, "2222", "8308511500");                      

            ClientConfig clientConfig = new DefaultClientConfig();

            clientConfig.getFeatures().put( JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);

            Client client = Client.create(clientConfig);

               // final HTTPBasicAuthFilter authFilter = new HTTPBasicAuthFilter(username, password);
               // client.addFilter(authFilter);
               // client.addFilter(new LoggingFilter());

            //
            WebResource webResource = client
                    .resource("http://vaquarkhan.net:12221/khanWeb/messages/sms/api/v1/userapi");

              ClientResponse response = webResource.accept("application/json")
                .type("application/json").put(ClientResponse.class, khanDTOInput);


            if (response.getStatus() != 200) {
                throw new RuntimeException("Failed : HTTP error code :" + response.getStatus());
            }

            String output = response.getEntity(String.class);

            System.out.println("Server response .... \n");
            System.out.println(output);

        } catch (Exception e) {

            e.printStackTrace();

        }    
    }    
}

クライアントリソースの例を見て、私は:)おかげで必要なものだった
Mobigitalを

0

queryParamメソッドを使用して、パラメーター名と値の配列を渡すことができます。

    public WebTarget queryParam(String name, Object... values);

例(jersey-client 2.23.2):

    WebTarget target = ClientBuilder.newClient().target(URI.create("http://localhost"));
    target.path("path")
            .queryParam("param_name", Arrays.asList("paramVal1", "paramVal2").toArray())
            .request().get();

これにより、次のURLにリクエストが発行されます。

    http://localhost/path?param_name=paramVal1&param_name=paramVal2
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.