Mar*_*rco 15 logging soap cxf interceptor
我一直在摆弄CXF上的服务器端拦截器.但似乎实现简单的传入和传出拦截器并不是一项简单的任务,这些拦截器为我提供了包含SOAP XML的纯字符串.
我需要在拦截器中使用纯XML,以便我可以将它们用于特定的日志记录任务.标准的LogIn和LogOut拦截器不能胜任任务.是否有人愿意分享一些关于如何实现一个简单的传入拦截器的例子,它能够获取传入的SOAP XML和一个传出的拦截器来再次获取SOAP XML?
ann*_*rin 18
在这里找到传入拦截器的代码: 使用Apache CXF以XML格式记录请求/响应
我的传出拦截器:
import java.io.OutputStream;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.io.CacheAndWriteOutputStream;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.io.CachedOutputStreamCallback;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.Phase;
public class MyLogInterceptor extends LoggingOutInterceptor {
public MyLogInterceptor() {
super(Phase.PRE_STREAM);
}
@Override
public void handleMessage(Message message) throws Fault {
OutputStream out = message.getContent(OutputStream.class);
final CacheAndWriteOutputStream newOut = new CacheAndWriteOutputStream(out);
message.setContent(OutputStream.class, newOut);
newOut.registerCallback(new LoggingCallback());
}
public class LoggingCallback implements CachedOutputStreamCallback {
public void onFlush(CachedOutputStream cos) {
}
public void onClose(CachedOutputStream cos) {
try {
StringBuilder builder = new StringBuilder();
cos.writeCacheTo(builder, limit);
// here comes my xml:
String soapXml = builder.toString();
} catch (Exception e) {
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我无法让上述解决方案为我工作.这是我开发的,希望它可以帮助其他人:
我的"传入"拦截器:
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingMessage;
public class MyCxfSoapInInterceptor extends LoggingInInterceptor {
public MyCxfSoapInInterceptor() {
super();
}
@Override
protected String formatLoggingMessage(LoggingMessage loggingMessage) {
String soapXmlPayload = loggingMessage.getPayload() != null ? loggingMessage.getPayload().toString() : null;
// do what you want with the payload... in my case, I stuck it in a JMS Queue
return super.formatLoggingMessage(loggingMessage);
}
}
Run Code Online (Sandbox Code Playgroud)
我的"外向"拦截器:
import org.apache.cxf.interceptor.LoggingMessage;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
public class MyCxfSoapOutInterceptor extends LoggingOutInterceptor {
public MyCxfSoapOutInterceptor() {
super();
}
@Override
protected String formatLoggingMessage(LoggingMessage loggingMessage) {
String soapXmlPayload = loggingMessage.getPayload() != null ? loggingMessage.getPayload().toString() : null;
// do what you want with the payload... in my case, I stuck it in a JMS Queue
return super.formatLoggingMessage(loggingMessage);
}
}
Run Code Online (Sandbox Code Playgroud)
我添加到spring框架应用程序上下文XML中的东西(记得在XML文件中定义两个拦截器)...
...
<cxf:bus>
<cxf:inInterceptors>
<ref bean="myCxfSoapInInterceptor"/>
</cxf:inInterceptors>
<cxf:inFaultInterceptors>
<ref bean="myCxfSoapInInterceptor"/>
</cxf:inFaultInterceptors>
<cxf:outInterceptors>
<ref bean="myCxfSoapOutInterceptor"/>
</cxf:outInterceptors>
<cxf:outFaultInterceptors>
<ref bean="myCxfSoapOutInterceptor"/>
</cxf:outFaultInterceptors>
</cxf:bus>
...
Run Code Online (Sandbox Code Playgroud)
注意,还有其他方法可以添加拦截器,例如通过注释,这将允许您只拦截特定的soap服务.上面添加拦截器的方法是"公共汽车"将拦截你所有的肥皂服务.
我只想再分享一个选项,如何同时将传入和传出消息组合在一起以进行某些日志记录,例如日志请求和对数据库的相应响应.
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.io.StringWriter;
import java.util.Collections;
import java.util.Set;
public class CxfLoggingHandler implements SOAPHandler<SOAPMessageContext> {
private static final String SOAP_REQUEST_MSG_KEY = "REQ_MSG";
public Set<QName> getHeaders() {
return Collections.EMPTY_SET;
}
public boolean handleMessage(SOAPMessageContext context) {
Boolean outgoingMessage = (Boolean) context.get (MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outgoingMessage) {
// it is outgoing message. let's work
SOAPPart request = (SOAPPart)context.get(SOAP_REQUEST_MSG_KEY);
String requestString = convertDomToString(request);
String responseString = convertDomToString(context.getMessage().getSOAPPart());
String soapActionURI = ((QName)context.get(MessageContext.WSDL_OPERATION)).getLocalPart();
// now you can output your request, response, and ws-operation
} else {
// it is incoming message, saving it for future
context.put(SOAP_REQUEST_MSG_KEY, context.getMessage().getSOAPPart());
}
return true;
}
public boolean handleFault(SOAPMessageContext context) {
return handleMessage(context);
}
private String convertDomToString(SOAPPart soap){
final StringWriter sw = new StringWriter();
try {
TransformerFactory.newInstance().newTransformer().transform(
new DOMSource(soap),
new StreamResult(sw));
} catch (TransformerException e) {
// do something
}
return sw.toString();
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用webservice连接该处理程序
<jaxws:endpoint id="wsEndpoint" implementor="#myWS" address="/myWS" >
<jaxws:handlers>
<bean class="com.package.handlers.CxfLoggingHandler"/>
</jaxws:handlers>
</jaxws:endpoint>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
51982 次 |
| 最近记录: |