【问题标题】:Java: Is there a way of changing the received HTTP Response headers?Java:有没有办法更改接收到的 HTTP 响应标头?
【发布时间】:2011-08-04 13:08:12
【问题描述】:

我正在使用 JAX-WS 生成的客户端(使用 wsimport,与 Glassfish 2.1.1 捆绑的客户端)连接到在 IIS 6 中运行的 ASP.NET 生成的 WebService。
当我在响应中请求压缩时(通过包含 HTTP 标头 Accept-Encoding: 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 相关的问题

【问题讨论】:

  • 您是否查找过错误报告?这似乎是 IIS 中的一个严重错误,因为它明显违反了 HTTP 1.1 规范。我认为不可能从客户端破解标头,因为一旦控制到达您的代码,所有 HTTP 处理就完成了。
  • 嗨@musiKk,我在最后一条评论中看到了here:“我已经注意到在响应标头中缺少两个实体:Vary Accept-Encoding 和 Content-Encoding gzip”
  • 您可以使用 Apache CXF 作为您的 JAX-WS 提供程序吗?使用 CXF 可能是可行的,但如果您被 RI 卡住,我不会费心调查。
  • 嗨@mtpettyp,是的,我想我可以使用 CXF 作为 JAX-WS 提供程序。我会推迟“改变和尝试”,直到我完成其他事情。供您输入的Tnanks

标签: java iis-6 gzip jax-ws


【解决方案1】:

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

缺点:可能不起作用。我希望 HTTP 标头列表是一个不可变的集合。此外,内容的解析(和失败)可能发生在第一个处理程序获得控制权之前。

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

【讨论】:

  • 嗨,我已经尝试将“Content-Encoding”添加到 SOAPHandler 中的响应标头(与我用来请求压缩响应的相同),但似乎甚至在调用 Handler 之前发生异常。感谢您的意见。
【解决方案2】:

你试过添加吗

接受编码:gzip,deflate

请求标头?

它与这个错误有关吗? (虽然你不使用 IE,但可能会有所帮助)

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

【讨论】:

  • 嗨,是的,我尝试将“gzip,defalte”设置为 Accept-Encoding。此外,当我尝试“放气”或“压缩”时,WebService 并没有压缩响应。当我在寻找与此相关的错误时,我发现了那个错误,但我认为它与它无关;感谢您的意见。
【解决方案3】:

我不太确定您的客户如何处理响应。但是,如果您可以通过编程方式拦截 HttpResponse,则可以尝试类似于使用 servlet 过滤器来包装 HttpResponse 并增加标头。


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

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

【讨论】:

  • 嗨,据我所知不可能使用 JAX-WS 拦截 HttResponse。感谢您的意见
【解决方案4】:

基本上你需要两个组件。首先,您必须创建一个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 中配置的过滤器中直接设置缺少的标头即可

希望这会有所帮助...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多