2016-11-24 1 views
1

Je cherche un moyen de passer une carte qui contient les noms et les valeurs de param à une cible Web GET. Je m'attends à ce que RESTEasy convertisse ma carte en une liste de paramètres de requête d'URL; Cependant, RESTEasy lève une exception en disant Caused by: javax.ws.rs.ProcessingException: RESTEASY004565: A GET request cannot have a body. . Comment puis-je demander à RESTEasy de convertir cette carte en paramètres de requête d'URL?Comment envoyer une carte params requête en utilisant le client proxy RESTEasy

Ceci est l'interface proxy:

@Path("/") 
@Consumes(MediaType.APPLICATION_JSON) 
public interface ExampleClient { 

    @GET 
    @Path("/example/{name}") 
    @Produces(MediaType.APPLICATION_JSON) 
    Object getObject(@PathParam("name") String name, MultivaluedMap<String, String> multiValueMap); 

} 

Ceci est l'utilisation:

@Controller 
public class ExampleController { 

    @Inject 
    ExampleClient exampleClient; // injected correctly by spring DI 

    // this runs inside a spring controller 
    public String action(String objectName) { 
     MultivaluedMap<String, String> params = new MultivaluedHashMap<>(); 

     // in the real code I get the params and values from a DB 
     params.add("foo", "bar") 
     params.add("jar", "car") 
     //.. keep adding 

     exampleClient.getObject(objectName, params); // throws exception 
    } 

} 

Répondre

1

Après des heures à creuser dans le code source RESTEasy, je trouve qu'il n'y a aucun moyen de le faire si annotation d'interface. En bref, RESTEasy crée quelque chose appelé un «processeur» de org.jboss.resteasy.client.jaxrs.internal.proxy.processors.ProcessorFactory pour mapper l'annotation à l'URI cible.

Cependant, il est très simple de résoudre ce problème en créant un ClientRequestFilter qui extrait la carte du corps de la requête (avant d'exécuter la requête bien sûr) et de la placer dans le paramètre de requête URI. Vérifiez le code ci-dessous:

Le filtre:

@Provider 
@Component // because I'm using spring boot 
public class GetMessageBodyFilter implements ClientRequestFilter { 
    @Override 
    public void filter(ClientRequestContext requestContext) throws IOException { 
     if (requestContext.getEntity() instanceof Map && requestContext.getMethod().equals(HttpMethod.GET)) { 
      UriBuilder uriBuilder = UriBuilder.fromUri(requestContext.getUri()); 
      Map allParam = (Map)requestContext.getEntity(); 
      for (Object key : allParam.keySet()) { 
       uriBuilder.queryParam(key.toString(), allParam.get(key)); 
      } 
      requestContext.setUri(uriBuilder.build()); 
      requestContext.setEntity(null); 
     } 
    } 
} 

PS: Je l'ai utilisé Map au lieu de MultivaluedMap pour la simplicité