Ответ 1
Мне нужно подключиться к плохо реализованному серверу, который понимает только Content-Type (capital-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
Вы заметили разницу: только первый char заголовка X-Client-Version
хранится в верхней части, остальные опускаются!
И действительно, если вы проверите класс c.s.x.w.t.Headers
, который используется для представления заголовков 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) {
...
}
Итак, в то время как класс c.s.x.w.t.h.c.HttpTransportPipe
(я понимаю, что здесь создается HTTP-запрос, это также где ранее добавлено заголовки будут добавлены в заголовки запросов HTTP) на самом деле добавляет "Content-Type"
в качестве ключа в экземпляре c.s.x.w.t.Headers
, ключ будет изменен из-за ранее упомянутой детали реализации.
Возможно, я ошибаюсь, но я не вижу, как это можно было бы изменить без исправления кода. И странная часть заключается в том, что я не думаю, что этот "нормализующий" материал действительно совместим с RFC (не проверял, что говорят RFC о случае с заголовками). Я удивлен. На самом деле, вы должны поднять вопрос.
Итак, я вижу три параметра здесь (так как ожидание исправления может не быть опцией):
- Исправьте код самостоятельно и перестройте JAX-WS RI (со всеми недостатками этого подхода).
- Попробуйте выполнить другую реализацию JAX-WS, например CFX для вашего клиента.
- Пусть запрос проходит через какой-то пользовательский прокси для изменения заголовка на лету.