Как сделать Feign POST-запрос без тела запроса и с параметрами запроса?
Я использую Feign с Apache Http Client, и я хотел бы поддержать следующий интерфейс jax-rs:
@POST
@Path("/do_something")
void doSomething(@QueryParam("arg") String arg);
Но ApacheHttpClient использует RequestBuilder, который преобразует параметры запроса для запросов без тела / сущности в UrlEncodedFormEntity.
Я конвертирую свои API в jax-rs и не хочу нарушать обратную совместимость. Есть ли способ использовать Feign без настройки моего API? Будут ли клиенты OkHttp или Ribbon поддерживать POST с параметрами запроса и без тела / объекта? Есть ли другой Java-клиент Jax-RS, который будет поддерживать это?
Кроме того, есть ли причина, почему RequestBuilder превращает параметры запроса в UrlEncodedFormEntity? Есть ли в библиотеке apache-httpclient альтернативный конструктор HttpUriRequest, который этого не делает? Метод сборки RequestBuilder имеет следующие строки кода:
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
}
Перед переключением на Feign мой код создал запрос HttpUriRequest с чем-то похожим на следующее:
URI uri = new URIBuilder()
.setScheme("https")
.setHost("localhost")
.setPath("service/do_something")
.addParameter("arg", "value")
.build();
HttpUriRequest request = new HttpPost(uri);
1 ответ
Если вы хотите немного сломать API и поддерживать поддержку @QueryParam
Затем вы можете определить перехватчик запроса на клиенте, который добавляет текстовое тело / сущность к запросу:
.requestInterceptor(template -> {
if (template.method().equals(HttpPost.METHOD_NAME) && template.queries().keySet().size() > 0 && template.body() == null) {
template.body(" ");
}
})
Тогда ваш API изменится следующим образом:
@POST
@Consumes(MediaType.TEXT_PLAIN)
@Path("/do_something")
void doSomething(@QueryParam("arg") String arg);
Но это нарушает API, так как сервер теперь ожидает / использует сообщение POST с текстовым объектом / телом.
Я думаю, что то же самое может быть достигнуто без requestInterceptor и Feign's @Body
шаблон:
@POST
@Consumes(MediaType.TEXT_PLAIN)
@Body(" ")
@Path("/do_something")
void doSomething(@QueryParam("arg") String arg);
Но это означает, что ваш API должен включать в себя Feign, а не чисто jax-rs аннотации.