Два разных POJO маршала к одному XML - PullRequest
0 голосов
/ 31 января 2020

Мне нужно отправить 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 и Metadata.

Плагин jaxb генерирует два соответствующих POJO из WSDL. Я пытаюсь отправить SOAP запрос, используя spring ws. Можно использовать следующий метод

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

Метод принимает в качестве полезной нагрузки только один объект. Но мне нужно отправить два объекта. Я не могу понять, как это сделать? Или как мне собрать эти два POJO на XML?

1 Ответ

0 голосов
/ 05 февраля 2020

Я нашел решение. Я составляю два разных сообщения 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);
    }
}

}

...