94 votes

Client de Jersey : Comment ajouter une liste comme paramètre de requête

Je suis en train de créer un client Jersey pour un service GET qui a une liste comme paramètre de requête. D'après le documentation il est possible d'avoir une liste comme paramètre de requête (cette information est également disponible à l'adresse suivante @QueryParam javadoc), consultez-le :

En général, le type Java du paramètre de la méthode peut :

  1. Soyez un type primitif ;
  2. Avoir un constructeur qui accepte un seul argument de type String ;
  3. avoir une méthode statique nommée valueOf ou fromString qui accepte un seul argument de type String (voir, par exemple, Integer.valueOf(String) et java.util.UUID.fromString(String)) ; ou
  4. Être une liste, un ensemble ou un ensemble trié, où T satisfait aux critères 2 ou 3 ci-dessus. La collection résultante est en lecture seule.

Parfois, les paramètres peuvent contenir plus d'une valeur pour le même nom. Si c'est le cas, les types indiqués en 4) peuvent être utilisés pour obtenir toutes les valeurs.

Cependant, je n'arrive pas à trouver comment ajouter un paramètre de requête de type liste en utilisant le client Jersey.

Je comprends que des solutions alternatives existent :

  1. Utilisez POST au lieu de GET ;
  2. Transformer la liste en une chaîne JSON et la transmettre au service.

La première n'est pas bonne, car le verbe HTTP approprié pour le service est GET. Il s'agit d'une opération de récupération de données.

La seconde sera mon option si vous ne pouvez pas m'aider. :)

Je suis également en train de développer le service, donc je peux le modifier si nécessaire.

Merci !

Mise à jour

Code client (utilisant 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>() {});

130voto

Dharmi Points 71

@GET ne prend pas en charge les listes de chaînes de caractères

Configuration :
Java : 1.7
Version de Jersey : 1.9

Ressources

@Path("/v1/test")

Sous-ressource :

// 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();
}

Testcase 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());
}

31voto

Perception Points 42290

Si vous envoyez autre chose que de simples chaînes, je vous recommande d'utiliser un POST avec un corps de requête approprié, ou de transmettre la liste entière sous forme de chaîne JSON codée de manière appropriée. Cependant, avec de simples chaînes de caractères, il suffit d'ajouter chaque valeur à l'URL de la requête de manière appropriée et Jersey la désérialisera pour vous. Donc avec l'exemple suivant endpoint :

@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();
    }
}

Votre client enverrait une requête correspondant à :

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

Ce qui aurait pour conséquence inputList qui est désérialisée pour contenir les valeurs "Hello", "Stay" et "Goodbye".

5voto

yogesh prajapati Points 1729

Je suis d'accord avec vous sur les solutions alternatives que vous avez mentionnées ci-dessus.

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

et il est vrai que vous ne pouvez pas ajouter List a MultiValuedMap en raison de sa classe impl MultivaluedMapImpl ont la capacité d'accepter une clé et une valeur de type chaîne. comme le montre la figure suivante

enter image description here

Si vous voulez toujours faire ces choses, essayez le code suivant.

Classe de contrôleur

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) ;
       }
}

Classe de clients

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;
    }
}

J'espère que cela vous aidera.

5voto

Andriy Points 161

On peut utiliser la méthode queryParam, en lui passant le nom du paramètre et un tableau de valeurs :

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

Exemple (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();

Cela va envoyer une requête à l'URL suivante :

    http://localhost/path?param_name=paramVal1&param_name=paramVal2

3voto

vaquar khan Points 2622

Demande GET avec paramètre de requête JSON

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();    
        }    
    }    
}

Demande de poste :

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();

        }    
    }    
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X