ur-type с JAX-RPC или XSLT-ответом через обработчик - PullRequest
0 голосов
/ 02 ноября 2011

Итак, мы получили прекрасный старинный 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 => anyType, но мы не можем понять это как это сделать. В частности, что OutputStream / StreamResult мы могли бы использовать для преобразования?

Любое другое предложение более чем приветствуется:)

1 Ответ

0 голосов
/ 03 ноября 2011

Так что если в конце мы отказались от нашей идеи использовать 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));
                }
            }
        }
    }

}
...