我试图将自定义头附加到cxf Message中,它可以工作,但我有一些消息有效载荷问题。
public HttpHeaderInterceptor() {
super(Phase.USER_PROTOCOL);
}
public void handleMessage(Message message) throws Fault {
try {
Map<String, List<String>> headers = (HashMap<String, List<String>>) message.get(Message.PROTOCOL_HEADERS);
if(validationFlag){
headerInfo = new ArrayList<String>();
String messageContent="empty";
OutputStream os = message.getContent(OutputStream.class);
StringBuilder responsePayload = new StringBuilder();
CachedOutputStream cos = (CachedOutputStream) os;
try {
cos.writeCacheTo(responsePayload);
messageContent = IOUtils.toString(cos.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
//here im getting hashCode of message payload and add to header
byte[] messageByte = messageContent.getBytes("UTF-8");
byte[] doFinal = mac.doFinal(messageByte);
StringBuilder sb = new StringBuilder();
sb.append(" Checksum:");
sb.append(Hex.encodeHex(doFinal));
headerInfo.add(scValidationCode);
headerInfo.add(sb.toString());
headers.put("Warning", headerInfo);
}
} catch ( Exception e) {
throw new Fault(e);
}
}
在此片段中:
messageContent = IOUtils.toString(cos.getInputStream());
messageContent是相等的,例如:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:someNamespace xmlns:ns2="http://something.com>some Soap request body</ns2:someNamespace>
但是原始的完整请求负载是相等的:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:someNamespace xmlns:ns2="http://something.com>some Soap request body</ns2:someNamespace></soap:Body></soap:Envelope>
在我的messageContent中,我得到了lost </soap:Body></soap:Envelope>
。我已经尝试改变org.apache.cxf.phase Phase,但仍然我的有效载荷从消息是没有soap信封关闭。
我不知道为什么当我试图获得message.getContent(OutputStream.class)时,我只会失去soap关闭。其他的都很好。HTTP报头正在附加新值。
ok,我已经通过了几乎所有的CXF链,我找到了解决方案。
soap信封和体闭包,被添加到soap SoapOutInterceptor中,但在子类中恰好是SoapOutEndingInterceptor,来自ENDING链。
所以如果你想要soap闭包有完整的有效载荷,你必须用两种方式放置你的自定义拦截器:
super(Phase.PRE_STREAM_ENDING);
addBefore(StaxOutInterceptor.StaxOutEndingInterceptor.class.getName());
或第二种方式:
super(Phase.WRITE_ENDING);
addAfter(SoapOutInterceptor.SoapOutEndingInterceptor.class.getName());
玩得开心!