jax-ws меняет Content-type на Content-Type, потому что сервер гиперчувствителен

Мне нужно подключиться к плохо реализованному серверу, который понимает только 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. Что я делаю неправильно?


person Esben Skov Pedersen    schedule 03.03.2010    source источник


Ответы (2)


Мне нужно подключиться к плохо реализованному серверу, который понимает только Content-Type (заглавная-T), но не Content-type. Как я могу попросить мой клиент jax-ws отправить Content-Type?

Я раскопал этот вопрос еще немного, и, к сожалению, я боюсь, что ответ таков: вы не можете. Позвольте мне поделиться своими выводами.

Во-первых, код, который вы найдете в https://jax-ws.dev.java.net/guide/HTTP_headers.html не предоставляет вам доступ к HTTP-заголовкам будущего HTTP-запроса (который еще не был создан), он позволяет вам чтобы установить дополнительные заголовки HTTP для отправки запроса (которые будут добавлены в запрос HTTP позже).

Так что не ждите, что следующий код не вернет null, если вы ничего не put ранее (и на самом деле вы получите только то, что put там):

((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 сохраняется в верхнем регистре, остальные - в нижнем!

И действительно, если вы проверите класс _ 7_, который используется для представления заголовков 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) {
     ...
 }

Итак, пока _ 10_ class (я понимаю, что именно здесь создается HTTP-запрос, а также там, где ранее добавленные заголовки будут добавлены к заголовкам HTTP-запроса) на самом деле добавляет "Content-Type" в качестве ключа в _ 12_, ключ будет изменен из-за ранее упомянутой реализации деталь.

Я могу ошибаться, но я не понимаю, как это можно изменить, не исправляя код. И странно то, что я не думаю, что этот «нормализующий» материал действительно совместим с RFC (хотя я не проверял, что RFC говорят о регистре заголовков). Я удивлен. На самом деле вам следует поднять вопрос.

Итак, я вижу здесь три варианта (поскольку ждать исправления может быть не вариант):

  • Исправьте код самостоятельно и перестройте JAX-WS RI (со всеми недостатками этого подхода).
  • Попробуйте другую реализацию JAX-WS, например CFX, для своего клиента.
  • Пусть запрос проходит через какой-то настраиваемый прокси-сервер, чтобы изменять заголовок на лету.
person Pascal Thivent    schedule 14.03.2010
comment
Я пока использовал собственный прокси ... Урод, как черт, и хотел бы удалить эту уродливую болтовню из своего кода. Ну что ж. C'est la via - person Esben Skov Pedersen; 15.03.2010
comment
@EsbenP Если вы поднимете вопрос по этому поводу, обновите вопрос, добавив ссылку. Я бы очень хотел получить отзывы от разработчиков JAX-WS RI по этому поводу. - person Pascal Thivent; 15.03.2010

Вы можете изменить заголовки HTTP из RequestContext. Если у вас есть доступ к объекту порта, вы можете преобразовать его в javax.xml.ws.BindingProvider, который предоставит вам доступ к RequestContext.

Вы также можете удалить неподтвержденный заголовок Content-type.

На этой странице более подробно показано, как это сделать: https://jax-ws.dev.java.net/guide/HTTP_headers.html

Сообщите мне, если вам понадобится больше примеров кода, или если вы вставите часть кода, я могу показать вам, как его изменить.

person Mark Pope    schedule 11.03.2010
comment
ссылка не работает, также я пробовал msg.getMimeHeaders (), затем removeHeader или addHeader, даже removeAllHeaders ничего не работает, вектор поддерживает заголовки, кажется неизменным - person Junchen Liu; 06.06.2017