如何使JAXWS在SOAP响应中发送content-length头信息

4

基本上,我使用JAXWS创建了一个Web服务。它使用SOAP并且工作正常。然而,在某些请求中,一些客户端会崩溃/出错,似乎与JAXWS Web服务没有发送content-length头有关。有没有办法添加它?

使用的是:openjdk-6 (6b20)

我的类看起来像这样:

import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.xml.ws.Endpoint;

@WebService
public class SOAP {
public static void main(String[] args) {
    try {
        SOAP server = new SOAP();
        Endpoint endpoint = Endpoint.publish('localhost:1234', server);
    } catch (Exception e) {
                Utils.getLog("SOAP").fatal("General Error", e);
    }
}
}

使用tcpdump可以确认响应中没有content-length字段:
0x0000:  4500 00b0 4da5 4000 4006 20d5 5cf3 1021  E...M.@.@...\..!
0x0010:  5cf3 01c7 13b2 bcea a9be 716e 14c3 16a1  \.........qn....
0x0020:  8018 006c cc70 0000 0101 080a 2e1b 3ccc  ...l.p........<.
0x0030:  2e18 23a2 4854 5450 2f31 2e31 2032 3030  ..#.HTTP/1.1.200
0x0040:  204f 4b0d 0a54 7261 6e73 6665 722d 656e  .OK..Transfer-en
0x0050:  636f 6469 6e67 3a20 6368 756e 6b65 640d  coding:.chunked.
0x0060:  0a43 6f6e 7465 6e74 2d74 7970 653a 2074  .Content-type:.t
0x0070:  6578 742f 786d 6c3b 6368 6172 7365 743d  ext/xml;charset=
0x0080:  2275 7466 2d38 220d 0a44 6174 653a 2053  "utf-8"..Date:.S
0x0090:  6174 2c20 3137 2053 6570 2032 3031 3120  at,.17.Sep.2011.
0x00a0:  3134 3a31 393a 3337 2047 4d54 0d0a 0d0a  14:19:37.GMT....

我的问题是:有没有办法告诉WebService在回复中发送Content-Length?或者在发送回复之前附加它?


1
“Transfer-encoding chunked”没有“content-length”头。请参考http://en.wikipedia.org/wiki/Chunked_transfer_encoding - 我怀疑问题出在其他地方。 - Brian Roach
不错的观点... 是时候深入挖掘,找出为什么有些请求似乎并不“完整”,尽管所有数据都已发送。 - Neck
你应该想知道客户端为什么有问题。所有的HTTP/1.1客户端都必须支持Transfer-encoding: chunked,而不需要内容长度才能工作。如果客户端不支持此功能,则该客户端必须使用HTTP/1.0。 - Mark Rotteveel
这也是我最终得出的结论。看起来是客户端(在这种情况下是php)存在一个bug。由于另一个bug,如果启用了wsdl缓存,它会忽略强制使用http 1.0。我现在只能尝试在JAXWS中禁用分块...如果有人有线索,请告诉我。 - Neck
在响应头中设置content-length标头应该可以解决问题。另外,客户端或响应头中的connection=close也可以。请参见http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html。无论哪种方式,下面我的答案都应该有所帮助。 - Simeon G
经过更深入的挖掘,似乎这是JAXWS的一个错误,可以查看使用curl获取相同回复的输出:%总计%接收%Xferd平均速度时间时间时间当前 Dload上传总计花费剩余速度 106 4190 0 4190 0 260 25 1-: - : - 0:02:43-: - : - 0106%? - Neck
2个回答

3
您可以编写一个处理程序来向传出响应添加HTTP标头。 您的处理程序将扩展标准的JAX-WS处理程序,并在handleMessage(C context)方法中使用MessageContext来修改HTTP_RESPONSE_HEADER属性(实际上是映射中的一个键)。 因此,例如,您的处理程序将是:
public class MyHandler<SOAPMessageContext> implements Handler {

    public boolean handleMessage(SOAPMessageContext c) {
        if((Boolean)c.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)) {
            c.put(SOAPMessageContext.HTTP_RESPONSE_HEADERS,"your header stuff here");
            return true;
        }
    }
 }

您需要创建一个处理程序链文件,并在端点类中添加指向该文件的注释。注释为 @HandlerChain(file="...");

这样一来,您就能够修改进出站的HTTP标头。希望这能帮到您。


1
我遇到了一个类似的问题,其中一个提供程序不接受分块消息... 它也不会在头部设置Content-length,并且实际上将消息分成块,Web服务提供程序会拒绝我的调用... 这是使用JAX-WS和Axis2 1.6作为JAX-WS运行时所发生的。
我尝试手动添加HTTP标头以添加Content-length,但这会引起其他问题。 最终,我通过在处理程序中将SOAPMessageContext上的HTTPConstants.CHUNKED设置为false来使其正常工作。
我在这里发表了博客:http://btarlton.blogspot.com/2013/03/jax-ws-with-axis2-how-to-disable.html#!/2013/03/jax-ws-with-axis2-how-to-disable.html 在使用Axis2作为JAX-WS运行时时,这是我能找到的唯一解决方法。

你应该在回答中添加你链接的主要部分。这样,如果以后你的博客失效了,回答仍将包含重要信息。 - SztupY

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接