2017-06-27 3 views
1

J'utilise Feindre avec le Apache Http Client et je voudrais soutenir l'interface JAX-RS suivant:Comment faire une demande Feindre POST sans corps de demande et avec paramètres de requête?

@POST 
@Path("/do_something") 
void doSomething(@QueryParam("arg") String arg); 

Mais, ApacheHttpClient utilise un RequestBuilder, qui convertit les paramètres de requête pour les requêtes sans corps/entité dans un UrlEncodedFormEntity .

Je suis mes API pour convertissent JAX-rs, et je ne veux pas briser la rétrocompatibilité. Existe-t-il un moyen d'utiliser Feign sans ajuster mon API? Les clients OkHttp ou Ribbon prendront-ils en charge les POST avec des paramètres de requête et aucun corps/entité? Y a-t-il un autre client java-js qui supportera cela?

Aussi, est-il une raison pour laquelle RequestBuilder se params de la requête dans un UrlEncodedFormEntity? Existe-t-il un autre générateur HttpUriRequest dans la bibliothèque apache-httpclient qui ne le fait pas? La méthode de construction de RequestBuilder a les lignes de code suivantes:

if (entity == null && (HttpPost.METHOD_NAME.equalsIgnoreCase(method) || HttpPut.METHOD_NAME.equalsIgnoreCase(method))) { 
    entity = new UrlEncodedFormEntity(parameters, HTTP.DEF_CONTENT_CHARSET); 
} else { 
    // omitted expected behavior 
} 

Avant de passer à Simulez, mon code construit un HttpUriRequest avec quelque chose de semblable à ce qui suit:

URI uri = new URIBuilder() 
     .setScheme("https") 
     .setHost("localhost") 
     .setPath("service/do_something") 
     .addParameter("arg", "value") 
     .build(); 
HttpUriRequest request = new HttpPost(uri); 

Répondre

0

Si vous êtes prêt à briser l'API légèrement et maintenir le soutien à la @QueryParam, vous pouvez définir un intercepteur de demande sur le client qui ajoute feindre une entité texte brut/corps à la demande:

.requestInterceptor(template -> { 
    if (template.method().equals(HttpPost.METHOD_NAME) && template.queries().keySet().size() > 0 && template.body() == null) { 
    template.body(" "); 
    } 
}) 

Ensuite, votre API changerait avec les éléments suivants:

@POST 
@Consumes(MediaType.TEXT_PLAIN) 
@Path("/do_something") 
void doSomething(@QueryParam("arg") String arg); 

Mais, ce casse l'API depuis le serveur attend maintenant/consomme un message POST avec une entité/corps de texte brut.

Je pense que la même chose pourrait être accompli sans requestInterceptor et avec le modèle @Body de Feindre:

@POST 
@Consumes(MediaType.TEXT_PLAIN) 
@Body(" ") 
@Path("/do_something") 
void doSomething(@QueryParam("arg") String arg); 

Mais, cela signifie que votre API devrait inclure Feindre plutôt que pures annotations JAX-RS.