猿问

CXF 消息在拦截器之外的上下文

我正在使用 apache cxf 发送 SOAP 消息,我想要的是在调用完成后获取请求和响应有效负载。目前我正在使用两个拦截器并将有效载荷放入消息的上下文中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);

    }

}

}


温温酱
浏览 158回答 1
1回答

慕虎7371278

我最终得到了以下解决方案:我只是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() {&nbsp; &nbsp; super(Phase.POST_PROTOCOL);}@Overridepublic void handleMessage(SoapMessage soapMessage) throws Fault {&nbsp; &nbsp; Document document = soapMessage.getContent(SOAPMessage.class).getSOAPPart();&nbsp; &nbsp; StringWriter stringWriter = new StringWriter();&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; TransformerFactory.newInstance().newTransformer().transform(new DOMSource(document), new StreamResult(stringWriter));&nbsp; &nbsp; } catch (TransformerException e) {&nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; }&nbsp; &nbsp; 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() {&nbsp; &nbsp; super(Phase.POST_PROTOCOL);&nbsp; &nbsp; addAfter(SAAJInInterceptor.class.getName());}@Overridepublic void handleMessage(SoapMessage message) throws Fault {&nbsp; &nbsp; Document document = message.getContent(SOAPMessage.class).getSOAPPart();&nbsp; &nbsp; StringWriter stringWriter = new StringWriter();&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; TransformerFactory.newInstance().newTransformer().transform(new DOMSource(document), new StreamResult(stringWriter));&nbsp; &nbsp; } catch (TransformerException e) {&nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; }&nbsp; &nbsp; message.put(IN_PAYLOAD_KEY, stringWriter.toString());&nbsp; &nbsp; 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);
随时随地看视频慕课网APP

相关分类

Java
我要回答