我在MULE中使用WSS4j CXF输出拦截器来签署SOAP响应,但如果此拦截器中存在错误,则无法正确生成SOAPFault。事实上,结果是一个状态为200的空白主体。
问题:
如果用于签名的out拦截器( WSS4JOutInterceptor )失败,则它不会生成正确的SOAPFault(状态代码为400/500),因为它在PRE_PROTOCOL和http.status和响应中执行标题已经写在HttpResponse中。
原因 SOAPFault 是在拦截器链(interceptor chain)的最后一个阶段生成的,所以HttpConnection已经打开并且正在编写HttpResponse,设置了标题和状态。
详细
Mule版本:3.6.1 CE CXF版本:2.5.9 WSS4j:1.6.9
JVM:JDK7
mule中的CXF入站连接调用 CxfInboundMessageProcessor 。这个类创建Exchange来执行输入拦截器链,骡子流以及最后输出拦截器链。
导致此错误的最重要阶段如下:
输出拦截器链分两个阶段执行,mule拦截器MuleProtocolHeadersOutInterceptor(PRE_STREAM)暂停它。当完全创建HttpResponse时,将执行输出拦截器链的其余部分。
当暂停时,执行返回到第一个类 CxfInboundMessageProcessor 。
在此之后,将创建响应:
MuleMessage muleResMsg = responseEvent.getMessage(); muleResMsg.setPayload(getResponseOutputHandler(M));
接口 org.mule.api.transport.OutputHandler 用于委派SOAP对象创建,直到执行 org.mule.transport.http.ResponseWriter 为止:
OutputHandler: 在这里,它可以看到方法写入如何继续输出链:
public void write(MuleEvent event, OutputStream out) throws IOException
{
Message outFaultMessage = m.getExchange().getOutFaultMessage();
Message outMessage = m.getExchange().getOutMessage();
Message contentMsg = null;
if (outFaultMessage != null && outFaultMessage.getContent(OutputStream.class) != null)
{
contentMsg = outFaultMessage;
}
else if (outMessage != null)
{
contentMsg = outMessage;
}
if (contentMsg == null)
{
return;
}
DelegatingOutputStream delegate = contentMsg.getContent(DelegatingOutputStream.class);
if (delegate.getOutputStream() instanceof ByteArrayOutputStream)
{
out.write(((ByteArrayOutputStream) delegate.getOutputStream()).toByteArray());
}
delegate.setOutputStream(out);
out.flush();
contentMsg.getInterceptorChain().resume();
}
org.mule.transport.http.HttpServerConnection
public void writeResponse(final HttpResponse response, Map<String,String> headers) throws IOException
{
if (response == null)
{
return;
}
if (!response.isKeepAlive())
{
Header header = new Header(HttpConstants.HEADER_CONNECTION, "close");
response.setHeader(header);
}
setKeepAlive(response.isKeepAlive());
addHeadersToHttpResponse(response, headers);
ResponseWriter writer = new ResponseWriter(this.out, encoding);
OutputStream outstream = this.out;
writer.println(response.getStatusLine());
Iterator item = response.getHeaderIterator();
while (item.hasNext())
{
Header header = (Header) item.next();
writer.print(header.toExternalForm());
}
writer.println();
writer.flush();
OutputHandler content = response.getBody();
if (content != null)
{
Header transferenc = response.getFirstHeader(HttpConstants.HEADER_TRANSFER_ENCODING);
if (transferenc != null)
{
response.removeHeaders(HttpConstants.HEADER_CONTENT_LENGTH);
if (transferenc.getValue().indexOf(HttpConstants.TRANSFER_ENCODING_CHUNKED) != -1)
{
outstream = new ChunkedOutputStream(outstream);
}
}
content.write(RequestContext.getEvent(), outstream);
if (outstream instanceof ChunkedOutputStream)
{
((ChunkedOutputStream) outstream).finish();
}
}
outstream.flush();
}
此后在httpResponse创建并设置标题后是&#34; body&#34;生成: