#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, может быть полезно)
Комментарии:
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. Спасибо за ваш вклад