Tworzę klienta Jersey dla usługi GET, która ma listę jako parametr zapytania. Zgodnie z dokumentacją możliwe jest posiadanie listy jako parametru zapytania (ta informacja jest również w @QueryParam javadoc), sprawdź to:
Ogólnie rzecz biorąc, typ Java parametru metody może:
- Bądź typem prymitywnym;
- Mieć konstruktora, który akceptuje pojedynczy argument typu String;
- Mieć statyczną metodę o nazwie valueOf lub fromString, która akceptuje pojedynczy argument typu String (patrz, na przykład, Integer.valueOf (String) i java.util.UUID.fromString (String)); lub
- Be List, Set lub SortedSet, gdzie T spełnia 2 lub 3 powyżej. Otrzymana kolekcja jest tylko do odczytu.
Czasami parametry mogą zawierać więcej niż jedną wartość dla tej samej nazwy. W takim przypadku można użyć typów 4) w celu uzyskania wszystkich wartości.
Jednak nie mogę dowiedzieć się, jak dodać parametr zapytania List przy użyciu klienta Jersey.
Rozumiem, że alternatywne rozwiązania to:
- Użyj POST zamiast GET;
- Przekształć listę w ciąg JSON i przekaż ją do usługi.
Pierwsza nie jest dobra, ponieważ właściwy czasownik HTTP dla usługi to GET. Jest to operacja odzyskiwania danych.
Druga będzie moją opcją, jeśli nie możesz mi pomóc. :)
Rozwijam też usługę, więc w razie potrzeby mogę ją zmienić.
Dzięki!
Aktualizacja
Kod klienta (przy użyciu 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>() {});
Odpowiedzi:
@GET
obsługuje listę ciągówInstalacja :
Java: 1.7
Wersja Jersey: 1.9
Ratunek
@Path("/v1/test")
Zasób podrzędny :
// 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(); }
Tester z Jersey
@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()); }
źródło
List<String> argList = List.of(argString.split("\\s*,\\s*"))
Jeśli wysyłasz coś innego niż proste ciągi znaków, polecam użycie POST z odpowiednią treścią żądania lub przekazanie całej listy jako odpowiednio zakodowanego ciągu JSON. Jednak w przypadku prostych ciągów wystarczy odpowiednio dołączyć każdą wartość do adresu URL żądania, a Jersey deserializuje ją za Ciebie. Biorąc więc pod uwagę następujący przykładowy punkt końcowy:
@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(); } }
Twój klient wysłałby żądanie odpowiadające:
Co spowodowałoby
inputList
deserializację, aby zawierała wartości „Hello”, „Stay” i „Goodbye”źródło
list[0]=Hello&list[1]=Stay
? jak sobie z tym poradzić?zgadzam się z tobą co do alternatywnych rozwiązań, o których wspomniałeś powyżej
1. Use POST instead of GET; 2. Transform the List into a JSON string and pass it to the service.
i to prawda, że nie można dodać
List
doMultiValuedMap
powodu jego IMPL klasyMultivaluedMapImpl
mają możliwość akceptowania string key i Wartość ciągu. co pokazano na poniższym rysunkunadal chcesz to zrobić, niż próbować śledzić kod.
Klasa kontrolera
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) ; } }
Klasa klienta
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; } }
mam nadzieję, że to ci pomoże.
źródło
GET Request with JSON Query Param
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(); } } }
Żądanie postu:
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(); } } }
źródło
Można by użyć metody queryParam, przekazując jej nazwę parametru i tablicę wartości:
public WebTarget queryParam(String name, Object... values);
Przykład (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();
Spowoduje to wysłanie żądania na następujący adres URL:
http://localhost/path?param_name=paramVal1¶m_name=paramVal2
źródło