ur-type使用JAX-RPC或XSLT通过Handler进行响应

时间:2011-11-02 19:41:17

标签: java xslt xsd jax-rpc

因此,我们已经拥有了一个可爱的复古PHP WS,我们必须通过JAX-RPC进行集成,这个WS提供了如下响应:

 <return SOAP-ENC:arrayType="SOAP-ENC:Array[1]" xsi:type="SOAP-ENC:Array">
    <item SOAP-ENC:arrayType="xsd:ur-type[3]" xsi:type="SOAP-ENC:Array">
       <item xsi:type="xsd:string">...</item>
       <item xsi:type="xsd:float">...</item>
       <item xsi:type="xsd:int">...</item>
    </item>
 </return>

现在的问题是,JAX-RPC似乎不了解ur-type

我们考虑使用Handler进行搜索并替换响应的XML或通过XSLT转换它,以便ur-type =&gt; anyType但我们似乎无法弄明白该怎么做。具体来说,我们可以使用OutputStream / StreamResult进行转换吗?

任何其他建议都非常受欢迎:)

1 个答案:

答案 0 :(得分:0)

因此,如果最终我们放弃了使用XSLT或在原始XML上进行搜索和替换的想法。

我们正在使用SOAPBody来操纵回复“DOM并将ur-type替换为anyType,一切正常。尽管如此,如果您有任何更好的想法,请发布它。

编辑:这是我们基本上如何做到的。

这是在您获得端口的类中,您需要在搜索和替换的位置注册处理程序:

private TestSOAPPort getPort() {
    TestSOAPService service = new TestSOAPServiceImpl();
    try {
        registerResponseHandler(service);
        TestSOAPPort port = service.getTestSOAPPort();
        ((TestSOAPPortStub) port)._setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY, TestConstants.ENDPOINT_URL);
        return port;
    } catch (Exception e) {
        // ...
    }

    return null;
}

private void registerResponseHandler(TestSOAPService service) {
    HandlerRegistry hr = service.getHandlerRegistry();
    QName portName = new QName(TestConstants.NAMESPACE_URI, TestConstants.PORT_NAME);
    List handlerChain = hr.getHandlerChain(portName);
    HandlerInfo hi = new HandlerInfo();
    hi.setHandlerClass(TestResponseHandler.class);
    handlerChain.add(hi);
}

这就是处理程序的样子:

import javax.xml.rpc.handler.GenericHandler;

public class TestResponseHandler extends GenericHandler {
    private static final String XSD_UR_TYPE = "xsd:ur-type";
    private static final String XSD_ANY_TYPE = "xsd:anyType";
    private static final String XSD_INT_ARRAY = "xsd:int[";
    private static final String XSD_ANY_TYPE_ARRAY = "xsd:anyType[";

    @Override
    public boolean handleResponse(MessageContext context) {
        SOAPMessageContext smc = (SOAPMessageContext) context;
        SOAPMessage sm = smc.getMessage();
        try {
            SOAPBody sb = sm.getSOAPBody();
            handleNodes(sb.getElementsByTagName("problemTag"));
            sm.saveChanges();
        } catch (Exception e) {
            // ...
        }

        return super.handleResponse(context);
    }

    private void handleNodes(NodeList nodes) {
        // do your search and replace here
        if (nodes == null) {
            return;
        }
        for (int i = 0; i < nodes.getLength(); i++) {
            Node node = nodes.item(i);
            NamedNodeMap attributes = node.getAttributes();
            for (int j = 0; j < attributes.getLength(); j++) {
                Node attribute = attributes.item(j);
                if (attribute.getNodeValue().startsWith(XSD_UR_TYPE)) {
                    attribute.setNodeValue(attribute.getNodeValue().replace(XSD_UR_TYPE, XSD_ANY_TYPE));
                } else if (attribute.getNodeValue().startsWith(XSD_INT_ARRAY)) {
                    attribute.setNodeValue(attribute.getNodeValue().replace(XSD_INT_ARRAY, XSD_ANY_TYPE_ARRAY));
                }
            }
        }
    }

}