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



我正在使用apachecxf发送一条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);
}
}
}

我最终得到了以下解决方案:

我只是在拦截器中执行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);

最新更新