CXF-контекст сообщения вне перехватчиков - PullRequest
0 голосов
/ 01 ноября 2018

Я отправляю сообщение SOAP, используя apache cxf, и я хочу получить полезные данные как запроса, так и ответа после завершения вызова. В настоящее время я использую два перехватчика и помещаю полезные данные в контекст сообщений вот так message.getExchange().put(ExchangeContextEnum.RESPONSE_PAYLOAD.toString(), new String(payload, Charset.forName(StandardCharsets.UTF_8.name())));.

Я не хочу обрабатывать их сразу в самом перехватчике, потому что мне нужны запросы и ответы для серии вызовов. Кроме того, я хотел бы избежать создания какого-либо хранилища для простоты и отсутствия необходимости решать возможные проблемы параллелизма.

Могу ли я получить эти значения после завершения вызова или в этот момент контекст полностью потерян?

Код:

webService.call(object)
//here i'd like to get payloads

Перехватчик для ответа:

public class LogInInterceptor extends AbstractPhaseInterceptor<Message> {

public LogInInterceptor() {
    super(Phase.RECEIVE);
}

@Override
public void handleMessage(Message message) throws Fault {
    InputStream in = message.getContent(InputStream.class);
    byte payload[] = new byte[0];
    try {
        payload = IOUtils.readBytesFromStream(in);
    } catch (IOException e) {
        e.printStackTrace();
    }
    ByteArrayInputStream bin = new ByteArrayInputStream(payload);
    message.setContent(InputStream.class, bin);

    message.getExchange().put(ExchangeContextEnum.RESPONSE_PAYLOAD.toString(), new String(payload, Charset.forName(StandardCharsets.UTF_8.name())));
}
}

Перехватчик для запроса:

public class WSSLogOutInterceptor extends AbstractSoapInterceptor {

public WSSLogOutInterceptor() {
    super(Phase.USER_PROTOCOL);
}

@Override
public void handleMessage(SoapMessage message) throws Fault {
    try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
        SOAPMessage messageContent = message.getContent(SOAPMessage.class);

        messageContent.writeTo(baos);
        message.getExchange().put(ExchangeContextEnum.REQUEST_PAYLOAD.toString(), baos.toString());

    } catch (SOAPException | IOException e) {
        throw new Fault(e);
    }
}
}

1 Ответ

0 голосов
/ 13 ноября 2018

Я получил следующее решение:

Вместо ввода значений в обмен сообщениями я просто делаю message.put(key, value) в перехватчике. Чтобы получить эти значения после звонка вам нужно получить контекст ответа, подобный этому (String) ((BindingProvider) webService).getResponseContext().get(key), где key - это то же самое значение, которое вы использовали прежде, чтобы поместить полезную нагрузку в сообщение. Теперь вот проблема - вы не найдете значений, которые вы помещаете в исходящую цепочку в контексте ответа. Вы можете использовать простой обходной путь и поставить значение при обмене сообщениями, а затем, во входящей цепочке, получить его и поместить в сообщение. Обратите внимание на фазу, которую я использовал (POST_PROTOCOL), было бы полезно, если вы используете WSS.

Вот код:

public class LoggingOutPayloadInterceptor extends AbstractSoapInterceptor {

public static final String OUT_PAYLOAD_KEY = "use.your.package.name.OUT_PAYLOAD_KEY";

public LoggingOutPayloadInterceptor() {
    super(Phase.POST_PROTOCOL);
}

@Override
public void handleMessage(SoapMessage soapMessage) throws Fault {

    Document document = soapMessage.getContent(SOAPMessage.class).getSOAPPart();
    StringWriter stringWriter = new StringWriter();
    try {
        TransformerFactory.newInstance().newTransformer().transform(new DOMSource(document), new StreamResult(stringWriter));
    } catch (TransformerException e) {
        e.printStackTrace();
    }

    soapMessage.getExchange().put(OUT_PAYLOAD_KEY, stringWriter.toString());
}

}

public class LoggingInPayloadInterceptor extends AbstractSoapInterceptor {

public static final String IN_PAYLOAD_KEY = "use.your.package.name.IN_PAYLOAD";

public LoggingInPayloadInterceptor() {
    super(Phase.POST_PROTOCOL);
    addAfter(SAAJInInterceptor.class.getName());
}

@Override
public void handleMessage(SoapMessage message) throws Fault {
    Document document = message.getContent(SOAPMessage.class).getSOAPPart();
    StringWriter stringWriter = new StringWriter();
    try {
        TransformerFactory.newInstance().newTransformer().transform(new DOMSource(document), new StreamResult(stringWriter));
    } catch (TransformerException e) {
        e.printStackTrace();
    }

    message.put(IN_PAYLOAD_KEY, stringWriter.toString());
    message.put(LoggingOutPayloadInterceptor.OUT_PAYLOAD_KEY, message.getExchange().get(LoggingOutPayloadInterceptor.OUT_PAYLOAD_KEY));
}

}

webService.call(...);
String inPayload = (String)((BindingProvider)webService).getResponseContext().get(LoggingInPayloadInterceptor.IN_PAYLOAD_KEY);
String outPayload = (String) ((BindingProvider) webService).getResponseContext().get(LoggingOutPayloadInterceptor.OUT_PAYLOAD_KEY);
...