Jersey 클라이언트 : 목록을 쿼리 매개 변수로 추가하는 방법


81

List as query 매개 변수가있는 GET 서비스에 대해 Jersey 클라이언트를 만들고 있습니다. 문서 에 따르면 List를 쿼리 매개 변수로 사용할 수 있습니다 (이 정보는 @QueryParam javadoc에도 있음). 확인하십시오.

일반적으로 Java 유형의 메소드 매개 변수는 다음과 같습니다.

  1. 원시 유형이어야합니다.
  2. 단일 String 인수를 허용하는 생성자가 있어야합니다.
  3. 단일 문자열 인수를 허용하는 valueOf 또는 fromString이라는 정적 메소드가 있습니다 (예 : Integer.valueOf (String) 및 java.util.UUID.fromString (String)). 또는
  4. List, Set 또는 SortedSet이어야합니다. 여기서 T는 위의 2 또는 3을 충족합니다. 결과 컬렉션은 읽기 전용입니다.

때때로 매개 변수는 동일한 이름에 대해 둘 이상의 값을 포함 할 수 있습니다. 이 경우 4)의 유형을 사용하여 모든 값을 얻을 수 있습니다.

그러나 Jersey 클라이언트를 사용하여 List 쿼리 매개 변수를 추가하는 방법을 알 수 없습니다.

대체 솔루션은 다음과 같습니다.

  1. GET 대신 POST를 사용하십시오.
  2. 목록을 JSON 문자열로 변환하고 서비스에 전달합니다.

서비스에 대한 적절한 HTTP 동사가 GET이기 때문에 첫 번째는 좋지 않습니다. 데이터 검색 작업입니다.

두 번째는 당신이 나를 도울 수 없다면 나의 선택이 될 것입니다. :)

또한 서비스를 개발 중이므로 필요에 따라 변경할 수 있습니다.

감사!

최신 정보

클라이언트 코드 (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
당신은 ... 여기 저지 클라이언트 코드를 제공 할 수 있습니다
인 Yogesh Prajapati에게

1
yogesh, 클라이언트 코드를 추가했습니다.
lsborg 2012

2
문제 설명을 이해하면 동일한 키에 여러 값을 추가하여 값 목록을 Query 매개 변수로 전달할 수 있습니다. "searchWrapper"가 키이고 여기에 여러 값을 전달하려는 경우 : 다음과 같은 URL을 빌드합니다. // YourURL? searchWrapper = value1 & searchWrapper = value2 & searchWrapper = value3 MultivaluedMap에서 지원하는 경우 동일한 키에 값을 여러 번 삽입해야 할 수 있습니다. .
Thamme Gowda 2013 년

1
감사합니다, @ThammeGowda! 나는 그것을 테스트하지 않았지만 메서드 상태 추가에 대한 MultivaluedMap javadoc 로 트릭을 수행하는 것 같습니다 . 제공된 키의 현재 값 목록에 값을 추가하십시오 .
lsborg 2014

답변:


119

@GET 문자열 목록을 지원합니까

설정 :
Java : 1.7
Jersey 버전 : 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

62
다른 사용자를위한 참고 사항과 마찬가지로 브라우저에서 URL을 직접 작성하는 경우 매개 변수 이름을 반복해야합니다. ..? list = one & list = two & list = three
endian

2
이것은 진정으로 목록입니까 / 주문이 존중받을 수 있습니까? 이 목록 I 경이로 저지 반환에 문제가 될 수 있다면하는 다중지도처럼 감안할 보인다 순서는 보존되지 않는
hayduke

네. ? list = one & list = two & list = three는 그다지 유용하지 않습니다. as list = one, two, three-그래서 문자열에서 목록으로 수동으로 구문 분석합니다.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값 '안녕하세요', '스테이'와 '안녕'을 포함 직렬화 복원되는


2
답변 Perception에 감사드립니다! 하지만 Jersey 클라이언트를 사용하여 List를 쿼리 매개 변수로 사용하여 GET을 수행 할 수 있는지 알고 싶습니다.
lsborg

1
내 클라이언트는 안드로이드와 iOS이기 때문에 클라이언트 측에서 이러한 목록을 만드는 방법을 알려 주시겠습니까? 우리는 key = value & key = value를 만들고 싶지 않습니다. manuall
nilesh

보내면 list[0]=Hello&list[1]=Stay어떨까요? 그것을 관리하는 방법?
user1735921

6

위에서 언급 한 대체 솔루션에 대해 동의합니다.

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

당신이 추가 할 수 있다는 그 사실 ListMultiValuedMap때문에 IMPL 클래스는 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
Haramoz 19 년

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.