我编写了一个自定义的CXF拦截器来将所有SOAP请求和响应记录到数据库中,它似乎在正面测试用例和服务器错误的情况下正常工作。
但是当发生SOAP Fault时,它只是忽略了我的拦截器而没有记录任何内容。
自定义CXF拦截器。
public class DbLogOutInterceptor extends AbstractSoapInterceptor {
public void handleMessage(SoapMessage message) {
logger.info("Handling outbound request");
String transaction = MDC.get(mdcKey);
logger.info("OutBound Transaction ID : {} ", transaction);
//code to log the SOAP message in database
.......
}
}
我没有看到此方法的日志语句,而是看到
11:56:34,102 INFO [Soap12FaultOutInterceptor] class org.apache.cxf.binding.soap.interceptor.Soap12FaultOutInterceptor$Soap12FaultOutInterceptor Internalapplication/soap+xml
11:56:34,103 INFO [EligibilityInfo] Outbound Message
---------------------------
ID: 2
Response-Code: 500
Encoding: UTF-8
Content-Type: application/soap+xml
Headers: {}
Payload :
为了捕获自定义拦截器中的SOAP错误错误,我必须做些什么。
答案 0 :(得分:3)
要捕获故障,您需要将拦截器注册为故障拦截器。例如
<cxf:outFaultInterceptors>
<bean class="DbLogOutInterceptor" />
</cxf:outFaultInterceptors>
有关使用CXF日志拦截器捕获输入/输出消息和输入/输出故障的示例,请参阅“使用自定义CXF bean元素启用消息日志记录”下的CXF Configuration页面。
答案 1 :(得分:3)
所以在我的自定义拦截器中,我编写了以下代码:
Fault fault = new Fault(message.getContent(Exception.class));
现在,这是一些遗留代码,它从Java中抛出异常并让框架将其转换为错误。我不会对此感到兴奋,但这会让你产生错误。
现在,如果您从服务方法中抛出错误,请执行
Fault fault = message.getContect(Fault.class);
希望这可以帮助您获得所需的答案。确保你注册拦截器如下
<jaxws:endpoint
id="fooService" implementor="com.bar.FooService" address="/FooServices">
<jaxws:outFaultInterceptors>
<ref class="com.bar.interceptor.DbLogOutInterceptor"/>
</jaxws:outFaultInterceptors>
</jaxws:endpoint>
<jaxws:endpoint
答案 2 :(得分:3)
最好的方法是实现Fault侦听器并使用org.slf4j.Logger来记录错误消息,而不是使用java日志记录。
最好是覆盖LoggingInInterceptor并编写ur custome拦截器来获取请求的有效负载。
public class CxfInputFaultInterceptor extends AbstractLoggingInterceptor {
private static final Logger LOG = LogUtils.getLogger(CxfInputFaultInterceptor.class);
public CxfInputFaultInterceptor() {
super(Phase.RECEIVE);
}
第1步:cxf-beans.xml
<cxf:bus>
<cxf:inInterceptors>
<ref bean="cxfInputFaultInterceptor"/>
</cxf:inInterceptors>
<cxf:inFaultInterceptors>
<ref bean="cxfInputFaultInterceptor"/>
</cxf:inFaultInterceptors>
<cxf:properties>
<entry key="org.apache.cxf.logging.FaultListener">
<bean id="cxfFaultListener" class="pkg.common.ws.interceptor.CxfFaultListenerImpl" >
<property name="loggedUser" ref="loggedUser"/>
</bean>
</entry>
</cxf:properties>
</cxf:bus>
第2步:你的监听器应该实现org.apache.cxf.logging.FaultListener
import java.io.InputStream;
import org.apache.cxf.interceptor.LoggingMessage;
import org.apache.cxf.logging.FaultListener;
import org.apache.cxf.message.Message;
import org.apache.cxf.service.model.EndpointInfo;
import org.apache.cxf.service.model.InterfaceInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*
* Listener to faults on the processing of messages by CXF intercepter chain. Here we override
* java.util.logging.Logger and use org.slf4j.Logger to print error to console.
*/
public class CxfFaultListenerImpl implements FaultListener{
private static final Logger logger = LoggerFactory.getLogger(CxfFaultListenerImpl.class);
private static final String NEWLINE="\n";
public boolean faultOccurred(final Exception exception,final String description,final Message message) {
createErrorLog(message);
logger.error(" --------------------------------------------------------------------------------------------------");
logger.error(" Stack Trace : ");
logger.error(" --------------------------------------------------------------------------------------------------");
logger.error(NEWLINE,exception);
logger.error(" --------------------------------------------------------------------------------------------------");
return true;
}
private void createErrorLog(final Message message){
final Message inMessage = message.getExchange().getInMessage();
final InputStream is = inMessage.getContent(InputStream.class);
final EndpointInfo endpoint = message.getExchange().getEndpoint().getEndpointInfo();
String logName=null;
if(endpoint!=null && endpoint.getService()!=null){
final String serviceName = endpoint.getService().getName().getLocalPart();
final InterfaceInfo iface = endpoint.getService().getInterface();
final String portName = endpoint.getName().getLocalPart();
final String portTypeName = iface.getName().getLocalPart();
logName = serviceName + "." + portName + "." + portTypeName;
}
final LoggingMessage buffer
= new LoggingMessage("Error occured on Service Call : "+NEWLINE +"----------------------------", logName);
final Integer responseCode = (Integer)message.get(Message.RESPONSE_CODE);
if (responseCode != null) {
buffer.getResponseCode().append(responseCode);
}
final String encoding = (String)message.get(Message.ENCODING);
if (encoding != null) {
buffer.getEncoding().append(encoding);
}
final String httpMethod = (String)message.get(Message.HTTP_REQUEST_METHOD);
if (httpMethod != null) {
buffer.getHttpMethod().append(httpMethod);
}
final String ct = (String)message.get(Message.CONTENT_TYPE);
if (ct != null) {
buffer.getContentType().append(ct);
}
final Object headers = message.get(Message.PROTOCOL_HEADERS);
if (headers != null) {
buffer.getHeader().append(headers);
}
final String uri = (String)message.get(Message.REQUEST_URL);
if (uri != null) {
buffer.getAddress().append(uri);
final String query = (String)message.get(Message.QUERY_STRING);
if (query != null) {
buffer.getAddress().append("?").append(query);
}
}
final String requestXml= is.toString();
if(requestXml !=null){
buffer.getMessage().append("LoggedIn User: ");
buffer.getMessage().append(getCurrentUsername()+NEWLINE);
buffer.getMessage().append("Request payload : "+NEWLINE);
buffer.getMessage().append(requestXml);
}else{
buffer.getMessage().append("LoggedIn User: ");
buffer.getMessage().append(getCurrentUsername()+NEWLINE);
buffer.getMessage().append("No inbound request message to append.");
}
logger.error(buffer.toString());
}
}
希望只在服务调用发生错误时帮助那些只想要堆栈跟踪和有效负载的人,从而避免大量日志文件。