Java:有没有办法更改收到的HTTP响应头?

时间:2011-04-13 09:08:31

标签: java iis-6 gzip jax-ws

我正在使用JAX-WS生成的客户端(使用与Glassfish 2.1.1捆绑的wsimport)连接到IIS 6中运行的ASP.NET生成的WebService。 当我在响应中请求压缩时(通过包含HTTP标头接受编码:gzip 通过JAX-WS SOAP处理程序),IIS 6以压缩响应回答,但不是t包含 Content-Encoding:gzip HTTP响应标头,因此我收到以下异常:

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)

2011年4月17日编辑

  

我也尝试过,使用相同的   我用于请求的SOAPHandler   压缩响应,修改   响应标头,但例外   在调用Handler之前发生。

结束编辑2011年4月17日

此外,当我通过soapUI 3.6.1使用首选项“接受来自主机的压缩响应”向WebService发出相同的请求时,我可以看到我所说的内容: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

如果--with soapUI-我不请求压缩响应,我得到下一个响应大小:

Content-Length: 2665

所以,正如我所说的那样,问题是IIS6没有在响应中添加Contend-Encoding标头。 我的问题是:是否有可能以编程方式添加Content-Encoding标头?或者,它也可能是:是否可以要求IIS6包含Content-Encoding标头?

更新
使用Charles Web Debugging Proxy 3.5.2我已经确认IIS6的响应不包括 Content-Encoding 标题:

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

我猜这可能是一个与WebService相关的问题,而不是与IIS 6相关的问题

4 个答案:

答案 0 :(得分:1)

基本上你需要两个组件。首先,您必须创建一个filter并将其添加到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>

接下来,您可能需要创建一个wrapper of the response,在其中添加缺少的标头。

实际上你根本不需要包装器,只需在你在web.xml中配置的过滤器中直接设置缺少的标头

希望这会有所帮助......

答案 1 :(得分:0)

特定于JAX-WS的解决方法是尝试将处理程序放入客户端的输入链中。处理程序将访问servlet上下文,获取请求对象,查看有效负载以及是否以GZ特定序列开始,将HTTP标头添加到现有列表中。

下行:可能行不通。我希望HTTP标头列表是一个不可变的集合。此外,内容的解析(和失败)可能比第一个处理程序获得控件更早发生。

(我在这里有另一个建议 - 使用HTTP过滤器 - 但后来我意识到JAX-WS是一个客户端,并且不使用web.xml。)

答案 2 :(得分:0)

您是否尝试过添加

  

Accept-Encoding:gzip,deflate

请求标题?

是否与此错误有关? (尽管你不使用IE浏览器,可能会有所帮助)

Internet Explorer Loses the First 2048 Bytes of Data That Are Sent Back by Web Servers That Use HTTP Compression

答案 3 :(得分:0)

我不太确定你的客户如何处理响应。但是,如果您可以拦截HttpResponse programmaticaly,您可以尝试类似于使用servlet过滤器来包装HttpResponse并扩充标题。


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

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