java 在自定义拦截器中捕获 SOAP 错误错误 (Soap12FaultOutInterceptor)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16526506/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 23:13:13  来源:igfitidea点击:

Catching the SOAP Fault error in custom interceptor (Soap12FaultOutInterceptor)

javasoapcxfinterceptorsoapfault

提问by NullPointerException

I wrote a custom CXF interceptor to log all the SOAP request and responses into the database and it seems to be working fine with positive test cases and server errors.

我编写了一个自定义 CXF 拦截器来将所有 SOAP 请求和响应记录到数据库中,它似乎在正面测试用例和服务器错误的情况下工作正常。

But when a SOAP Fault occurs it just neglects my interceptor and nothing is logged.

但是当发生 SOAP 错误时,它只是忽略了我的拦截器并且没有记录任何内容。

Custom CXF interceptors.

自定义 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
    .......

     }
   }

I am not seeing the log statements from this method instead I see

我没有看到此方法的日志语句,而是看到

 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 :  

What I have to do in order to capture the SOAP fault erros in my custom interceptors.

为了在我的自定义拦截器中捕获 SOAP 错误错误,我必须做什么。

采纳答案by fpmoles

So in my custom interceptor I write the following code:

所以在我的自定义拦截器中,我编写了以下代码:

Fault fault = new Fault(message.getContent(Exception.class));

Now this is in some legacy code that was throwing exceptions from Java and letting the framework convert it to a fault. I won't get into my feelings on that, but this will get you the fault that is generated.

现在这是在一些遗留代码中,这些代码从 Java 中抛出异常并让框架将其转换为错误。我不会对此深有感触,但这会让你承担由此产生的错误。

Now if you are throwing a fault from your service method, do

现在,如果您从服务方法中抛出错误,请执行

Fault fault = message.getContect(Fault.class);

Hopefully this will help you get the answer to what you want. Make sure you register the interceptor like below

希望这会帮助你得到你想要的答案。确保像下面这样注册拦截器

<jaxws:endpoint
  id="fooService" implementor="com.bar.FooService" address="/FooServices">
  <jaxws:outFaultInterceptors>
        <ref class="com.bar.interceptor.DbLogOutInterceptor"/>
  </jaxws:outFaultInterceptors>
</jaxws:endpoint>
<jaxws:endpoint

回答by Patrick

To capture faults, you need to register the interceptor as a fault interceptor. For example

要捕获故障,您需要将拦截器注册为故障拦截器。例如

<cxf:outFaultInterceptors>
   <bean class="DbLogOutInterceptor" />
</cxf:outFaultInterceptors>

See the CXF Configurationpage under "Enabling message logging using custom CXF bean elements" for an example using the CXF logging interceptors to capture in/out messages and in/out faults.

有关使用 CXF 日志拦截器捕获输入/输出消息和输入/输出故障的示例,请参阅“使用自定义 CXF bean 元素启用消息日志记录”下的CXF 配置页面。

回答by kumarn

The Best way is to implement the Fault listener and use org.slf4j.Logger to log the error message instead of using java logging.

最好的方法是实现故障侦听器并使用 org.slf4j.Logger 来记录错误消息,而不是使用 java 日志记录。

It would be wise to override the LoggingInInterceptor and write ur custome interceptor to get the request payload.

覆盖 LoggingInInterceptor 并编写您的自定义拦截器以获取请求有效负载是明智的。

public class CxfInputFaultInterceptor extends AbstractLoggingInterceptor {
private static final Logger LOG = LogUtils.getLogger(CxfInputFaultInterceptor.class);

public CxfInputFaultInterceptor() {
    super(Phase.RECEIVE);
}

Step 1: cxf-beans.xml

第 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>

Step 2 : your listener which should implements org.apache.cxf.logging.FaultListener

第 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());
}

}

}

Hope that helps someone who just wants the stack trace and payload only when an error occurs on the service call and thus avoid huge log files.

希望能帮助那些只在服务调用发生错误时才想要堆栈跟踪和有效负载的人,从而避免巨大的日志文件。