如何将数据从SOAP处理程序传递回Web服务客户端?

时间:2012-08-17 21:34:23

标签: java xml web-services soaphandler

(关注这个问题:Getting raw XML response from Java web service client

我有一个SOAP消息处理程序,它能够获取Web服务响应的原始XML。我需要将这个XML放到webservice客户端中,这样我就可以在响应之前对响应执行一些XSL转换。我无法找到一种从捕获传入消息的SOAP处理程序中获取数据的好方法,并使原始XML可用于生成(来自WSDL)Web服务客户端。任何想法,如果这是可行的吗?


我想出了类似的东西:

public class CustomSOAPHandler implements javax.xml.ws.handler.soap.SOAPHandler<javax.xml.ws.handler.soap.SOAPMessageContext>
{
    private String myXML;
    public String getMyXML()
    {
        return myXML;
    }
    ...
    public boolean handleMessage(SOAPMessageContext context)
    {
        ...
        myXML = this.getRawXML(context.getMessage());
    }

    //elsewhere in the application:
    ...
    myService.doSomething(someRequest);
    for (Handler h: ((BindingProvider)myService).getBinding().getHandlerChain())
    {
        if (h instanceof CustomSOAPHandler )
        {
            System.out.println("HandlerResult: "+ ((CustomSOAPHandler )h).getMyXML());
        }
    }

在非常简单的测试中,这似乎有效。但这个解决方案感觉有点像廉价黑客。我不喜欢将原始XML设置为链处理程序的成员,我有一种直觉,这违反了许多其他最佳实践。有没有人有更优雅的方式这样做?

3 个答案:

答案 0 :(得分:4)

似乎对我有用的两个选择都记录在案here。我还没有收到关于使用ThreadLocal是否合适的回复,但我不明白为什么不应该这样做。

我在原始问题中添加的secoond方法是走处理程序的路径。在调试WS标注时,我注意到invocationProperties映射将SOAP响应作为responseContext对象内部数据包结构的一部分,但似乎没有办法实现它。 ResponseContext是一组名称值对。但是,当我在this location读取ResponseContext的源代码时,我看到get方法的代码有一个关于返回null的注释,如果它找不到Application Scoped属性,否则,它将从packet invocationProperties,这似乎是我想要的。所以我谈到了如何在键/值对上设置范围(Google:为jaxws设置应用程序范围属性)上下文引入它的内容很低,这是我在jax-ws规范中引用的另一个线程。

我还对数据包https://jax-ws.java.net/nonav/jax-ws-20-fcs/arch/com/sun/xml/ws/api/message/Packet.html进行了一些阅读。

我希望这对你有用。我担心如果Web服务调用导致Soap FAULT,三个不会使用JAXB,我真的想记录这个数据包,因为它是从支付网关返回的,直到今天还有一个数字未记录的结果。

祝你好运。

答案 1 :(得分:1)

解决方案是使用JAXB将对象转换回XML。我真的不想这样做,因为让webservice客户端接收XML,将其转换为POJO似乎是多余的,只是将POJO转换回XML,但它可以工作。

答案 2 :(得分:1)

作为替代方法,您可以将其放入ThreadLocal中,而不是将请求/响应详细信息放入soap上下文中(在我的情况下,它不起作用)。因此,您需要使用@gavenkoa描述的SOAPHandler(类型),但是将其添加到ThreadLocal实例中,而不是添加到soap上下文中。