Я должен соединиться с плохо реализованным сервером, который только понимает Content-Type
(капитал-T) и нет Content-type
. Как я могу попросить, чтобы мой клиент JAX-WS отправил Content-Type
?
Я попробовал:
Map<String, List<String>> headers = (Map<String, List<String>>)
((BindingProvider)port).getRequestContext().get(MessageContext.HTTP_REQUEST_HEADERS);
Но headers
null
. Что я делаю неправильно?
Мне нужно подключиться к плохо реализованному серверу, который понимает только Content-Type (заглавная T), но не Content-type. Как я могу попросить мой клиент jax-ws отправить Content-Type?
Я раскопал этот вопрос еще немного и, к сожалению, боюсь, что ответ: вы не можете. Позвольте мне поделиться своими выводами.
Во-первых, код, который вы найдете в https://jax-ws.dev.java.net/guide/HTTP_headers.html , не дает вам доступа к заголовкам HTTP. будущего HTTP-запроса (который еще не был создан), он позволяет вам установить дополнительных HTTP-заголовков для выполнения запроса (которые будут добавлены к HTTP-запросу позже).
Поэтому не ожидайте, что следующий код не вернет null
, если вы не ничего не поставили
раньше (и на самом деле вы получите только то, что поместите туда
):
((BindingProvider)port).getRequestContext().get(MessageContext.HTTP_REQUEST_HEADERS);
Затем я провел небольшой тест на основе кода, приведенного в той же ссылке:
AddNumbersImplService service = new AddNumbersImplService();
AddNumbersImpl port = service.getAddNumbersImplPort();
((BindingProvider)port).getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS,
Collections.singletonMap("X-Client-Version",Collections.singletonList("1.0-RC")));
port.addNumbers(3, 5);
И вот что я вижу в HTTP-запросе при запуске клиентского кода:
POST /q2372336/addnumbers HTTP/1.1 Content-type: text/xml;charset="utf-8" X-client-version: 1.0-RC Soapaction: "" Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 User-Agent: JAX-WS RI 2.1.6 in JDK 6 Host: localhost:8080 Connection: keep-alive Content-Length: 249
Вы заметили разницу: только первый символ заголовка X-Client-Version
сохраняется в верхнем регистре, остальные - в нижнем!
И действительно, если вы проверите класс csxwtHeaders
, который используется для представления заголовков HTTP-запросов (и ответов), вы увидите, что он «нормализует» ключи при их добавлении (в normalize (String)
):
/* Normalize the key by converting to following form.
* First char upper case, rest lower case.
* key is presumed to be ASCII
*/
private String normalize (String key) {
...
}
Итак, хотя класс csxwthcHttpTransportPipe
(насколько я понимаю, именно здесь создается HTTP-запрос, сюда также будут добавлены ранее добавленные заголовки к заголовкам HTTP-запроса) фактически добавляет «Content-Type»
в качестве ключа в экземпляре csxwtHeaders
, ключ будет изменен из-за ранее упомянутой детали реализации.
Я могу ошибаться, но я не понимаю, как это можно изменить, не исправляя код. И странно то, что я не думаю, что этот «нормализующий» материал действительно соответствует RFC (хотя я не проверял, что RFC говорят о регистре заголовков). Я удивлен. Фактически, вы должны поднять вопрос .
Итак, я вижу здесь три варианта (поскольку ожидание исправления может быть недопустимым):
Вы можете изменить заголовки HTTP из RequestContext. Если у вас есть доступ к объекту порта, вы можете преобразовать его в javax.xml.ws.BindingProvider, который предоставит вам доступ к RequestContext.
Вы также можете удалить непринятый заголовок Content-type.
На этой странице более подробно показано, как это сделать: https://jax-ws.dev.java.net/guide/HTTP_headers.html
Дайте мне знать, если вам нужны дополнительные образцы кода , или если вы вставите часть своего кода, я могу показать вам, как его изменить.