两种不同的POJO封送为一种XML

时间:2020-01-31 13:05:15

标签: xml soap jaxb spring-ws

我需要像这样发送SOAP请求

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
xmlns:ser="foo.com/Public/Services" 
xmlns:typ="foo.com/Public/Types">
   <soap:Header/>
   <soap:Body>
      <ser:InputParms>
         <!--some parameters:-->
      </ser:InputParms>
      <ser:Metadata>
         <!--some parameters:-->
      </ser:Metadata>
   </soap:Body>
</soap:Envelope>

如何看到XML包含两个对象:InputParms和元数据。

jaxb插件从WSDL生成两个相应的POJO。 我尝试使用spring ws发送SOAP请求。 可以使用以下方法

public Object marshalSendAndReceive(String uri,
                                        final Object requestPayload,
                                        final WebServiceMessageCallback requestCallback)

该方法仅接受一个对象作为有效负载。 但是我需要发送两个对象。我不知道该怎么做? 或者如何将这两个POJO编组到XML?

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。 我编写了两种不同的SOAP消息,并将两个信封合并为一个。

public class ClientImpl extends WebServiceGatewaySupport {

private static final String ACTION = "foo.com/services";

@Value("${uri}")
private String uri;

public Response sendRequest(ManualRequest request) {
    WebServiceTemplate template = getWebServiceTemplate();

    Response response = (Response) template.marshalSendAndReceive(
            uri,
            request.getSecondPayloadObject(),
            new SoapPayloadMergeCallback(request.getFirstPayloadObject(),
                    ACTION,
                    getMarshaller())
    );

    return response;
}

private static final class SoapPayloadMergeCallback implements WebServiceMessageCallback {

    public SoapPayloadMergeCallback(Object additionalPayloadObject, String soapAction, Marshaller marshaller) {
        this.additionalPayloadObject = additionalPayloadObject;
        this.soapAction = soapAction;
        this.marshaller = marshaller;
    }

    private final Object additionalPayloadObject;
    private final String soapAction;
    private final Marshaller marshaller;

    @Override
    public void doWithMessage(WebServiceMessage message) throws IOException {
        SoapMessage soapMessage = (SoapMessage) message;
        soapMessage.setSoapAction(soapAction);

        Node additional = soapMessage.getDocument().cloneNode(true);

        MarshallingUtils.marshal(marshaller, additionalPayloadObject, message);
        soapMessage = (SoapMessage) message;
        Document target = soapMessage.getDocument();

        merge(target, (Document) additional);
    }

    private void merge(Document target, Document additional) {
        Element envelopeElementAdditional = additional.getDocumentElement();
        Node bodyNodeAdditional = envelopeElementAdditional.getChildNodes().item(1);
        Node elementToMove = bodyNodeAdditional.getFirstChild();

        Node importedNode = target.adoptNode(elementToMove);

        Element envelopeElementTarget = target.getDocumentElement();
        Node bodyNodeTarget = envelopeElementTarget.getChildNodes().item(1);
        bodyNodeTarget.appendChild(importedNode);
    }
}

}