Java: Есть ли способ изменить заголовки полученных HTTP-ответов?

#java #iis-6 #gzip #jax-ws

#java #iis-6 #gzip #jax-ws

Вопрос:

Я использую клиент, созданный на JAX-WS (с использованием wsimport, который поставляется в комплекте с Glassfish 2.1.1), для подключения к ASP.NET созданный веб-сервис, запущенный в IIS 6.
Когда я запрашиваю сжатие в ответе (путем включения HTTP-заголовка Accept-Encoding: gzip через обработчики SOAP JAX-WS), IIS 6 отвечает сжатым ответом, но не включает заголовок HTTP-ответа Content-Encoding: gzip, поэтому я получаю следующее исключение:

 com.sun.xml.ws.protocol.soap.MessageCreationException: Couldn't create SOAP message due to exception: XML reader error: com.sun.xml.stream.XMLStreamException2: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.
at com.sun.xml.ws.encoding.SOAPBindingCodec.decode(SOAPBindingCodec.java:361) at com.sun.xml.ws.transport.http.client.HttpTransportPipe.process(HttpTransportPipe.java:173)
at com.sun.xml.xwss.XWSSClientPipe.process(XWSSClientPipe.java:160)
at com.sun.xml.ws.api.pipe.helper.PipeAdapter.processRequest(PipeAdapter.java:115)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:595)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:554)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:539)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:436)
at com.sun.xml.ws.client.Stub.process(Stub.java:248)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:135)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:109)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:89)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:118)
  

Отредактировано 17 апреля 2011 г.

Я также пытался, используя тот же SOAPHandler, который я использую для запроса сжатого ответа, изменить заголовки ответов, но исключение возникает до вызова обработчика.

Окончательная правка 17 апреля 2011 г.

Кроме того, когда я делаю тот же запрос к веб-сервису через SoapUI 3.6.1 с предпочтением «Принимать сжатые ответы от хостов», я вижу, что я сказал: сервер IIS 6 не включает заголовок HTTP-ответа для сжатия, и SoapUI отображает ответ как «двоичные данные» и показывает эти заголовки ответа:

 HTTP/1.1 200 OK
Date: Wed, 13 Apr 2011 08:50:55 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Content-Length: 1104
  

Если — с SoapUI — я не запрашиваю сжатый ответ, я получаю следующий размер ответа:

 Content-Length: 2665
  

Итак, вопрос здесь в том, как я уже сказал, что IIS6 не добавляет заголовок Contend-Encoding в ответ.
Мой вопрос: возможно ли — программно- добавить заголовок Content-Encoding? Или это также может быть: можно ли попросить IIS6 включить заголовок Content-Encoding?

Обновить
Используя Charles Web Debugging Proxy 3.5.2, я подтвердил, что ответ от IIS6 не включает заголовок с кодировкой содержимого:

 HTTP/1.1 200 OK
Date    Wed, 13 Apr 2011 10:51:53 GMT
Server  Microsoft-IIS/6.0
X-Powered-By    ASP.NET
X-AspNet-Version    2.0.50727
Cache-Control   private, max-age=0
Content-Type    text/xml; charset=utf-8
Content-Length  1110
  

Я предполагаю, что это может быть проблемой, больше связанной с веб-сервисом, чем с IIS 6

Комментарии:

1. Вы искали сообщения об ошибках? Это похоже на серьезную ошибку в IIS, поскольку она явно нарушает спецификацию HTTP 1.1. Я не думаю, что возможно взломать заголовок со стороны клиента, поскольку вся обработка HTTP выполняется, как только управление достигает вашего кода.

2. Привет @musiKk, я видел здесь в последнем комментарии: «Я заметил, что в заголовке ответа отсутствуют две сущности: gzip с изменяемой кодировкой принятия и с кодировкой содержимого»

3. Можете ли вы использовать Apache CXF в качестве вашего поставщика JAX-WS? Это может быть возможно с помощью CXF, но если вы застряли с RI, я не буду утруждать себя расследованием.

4. Привет @mtpettyp, да, я думаю, я мог бы использовать CXF в качестве поставщика JAX-WS. Я отложу это «изменить и попробовать», пока не закончу другие действия. Tnanks для вашего ввода

Ответ №1:

В основном вам нужны два компонента. Сначала вы должны создать фильтр и добавить его в web.xml поскольку это:

 <filter>
  <filter-name>yourFilter</filter-name>
  <filter-class>yourFilterClassWhichAddsTheCorrectHeader</filter-class>
</filter>
<filter-mapping>
  <filter-name>yourFilter</filter-name>
  <url-pattern>theServletUrlMappedToJaxWS</url-pattern>
</filter-mapping>
  

Затем вам может потребоваться создать оболочку ответа, куда вы добавляете отсутствующий заголовок.

На самом деле вам может вообще не понадобиться оболочка, просто установите отсутствующий заголовок непосредственно в фильтре, который вы настроили в web.xml

Надеюсь, это поможет…

Ответ №2:

Специфичный для JAX-WS обходной путь заключается в попытке поместить обработчик во входную цепочку клиента. Обработчик получит доступ к контексту сервлета, получит объект запроса, посмотрит полезную нагрузку и, если она начинается с последовательности, специфичной для GZ, добавит HTTP-заголовок в список существующих.

Недостатки: может не работать. Я ожидаю, что список HTTP-заголовков будет неизменяемой коллекцией. Кроме того, синтаксический анализ содержимого (и сбой) может произойти раньше, чем первый обработчик получит управление.

(Здесь у меня было другое предложение — использовать HTTP-фильтр, но затем я понял, что JAX-WS является клиентом и не использует web.xml ).

Комментарии:

1. Привет, я попытался добавить «Content-Encoding» к заголовкам ответов в SOAPHandler (тот же, который я использую для запроса сжатого ответа), но, похоже, исключение возникает даже до вызова обработчика. Спасибо за ваш вклад.

Ответ №3:

вы пробовали добавлять

Принять-Кодирование: gzip, deflate

для заголовка запроса?

связано ли это с этой ошибкой? (хотя вы не используете IE, может быть полезно)

Internet Explorer теряет первые 2048 байт данных, которые отправляются обратно веб-серверами, использующими сжатие HTTP

Комментарии:

1. Привет, да, я попытался установить «gzip, defalte» в качестве Accept-Encoding. Также, когда я пытался просто «выкачать» или «сжать», веб-сервис не сжимал ответ. Когда я искал ошибки, связанные с этим, я обнаружил эту ошибку, но я не думаю, что это связано с ней; спасибо за ваш вклад.

Ответ №4:

Я не слишком уверен, как ваш клиент обрабатывает ответ. Однако, если вы можете перехватить HttpResponse программно, вы могли бы попробовать что-то похожее на использование фильтра сервлета для переноса HttpResponse и увеличения заголовков.

 
public class HttpReponseWrapper extends HttpReponse 
{
   HttpResponse reponse;
   public HttpResponseWrapper(HttpResponse response)
   {
     this.response = response;
   }

   public String getContentEncoding()
  {
      return "Content-Encoding=gzip";
  }
}
  

Комментарии:

1. Привет, насколько я знаю , невозможно перехватить HttResponse с помощью JAX-WS. Спасибо за ваш вклад