使用Apache CXF以XML格式记录请求/响应

iri*_*guy 25 xml cxf webservice-client

是否可以使用CXF将请求/响应记录为XML,理想情况下是单独的文件,以便我可以监视应用程序正在做什么?

Ast*_*rio 28

所以,我尝试了一下这个.要记录XML请求和回复,并且如果您使用的是Log4J,则需要在log4j.xml文件中设置CXF的日志级别,如下所示(> = INFO):

<logger name="org.apache.cxf" >
    <level value="INFO" />
</logger>
Run Code Online (Sandbox Code Playgroud)

并且cxf.xml文件应包含以下内容:

<cxf:bus>
    <cxf:features>
        <cxf:logging/>
    </cxf:features>
</cxf:bus> 
Run Code Online (Sandbox Code Playgroud)

这两个文件都应该在CLASSPATH中.

要显示soap消息,请将其添加到您的代码中:

Client client = ClientProxy.getClient(service);
client.getInInterceptors().add(new LoggingInInterceptor());
client.getOutInterceptors().add(new LoggingOutInterceptor());
Run Code Online (Sandbox Code Playgroud)


Asr*_*que 22

请求soap xml可以通过自定义In拦截器轻松记录.比方说,我们有一个名为"wsLoggingInInterceptor"的拦截器,所以在上下文文件中它将如下所示:

<bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<bean id="logOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
<bean id="wsLoggingInInterceptor" class="org.jinouts.webservice.logging.WSLoggingInInterceptor"/>


   <cxf:bus>
        <cxf:inInterceptors>
            <ref bean="loggingInInterceptor"/>
            <ref bean="wsLoggingInInterceptor"/>
        </cxf:inInterceptors>
        <cxf:outInterceptors>
            <ref bean="logOutInterceptor"/>            
       </cxf:outInterceptors>
    </cxf:bus>
Run Code Online (Sandbox Code Playgroud)

在类中,我们可以获得请求xml,如下所示:

public class WSLoggingInInterceptor extends AbstractSoapInterceptor
{

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

    @Override
    public void handleMessage ( SoapMessage message ) throws Fault
    {
        //get the remote address
        HttpServletRequest httpRequest = (HttpServletRequest) message.get ( AbstractHTTPDestination.HTTP_REQUEST );
        System.out.println ("Request From the address : " + httpRequest.getRemoteAddr ( ) );

        try
        {
            // now get the request xml
            InputStream is = message.getContent ( InputStream.class );
            CachedOutputStream os = new CachedOutputStream ( );
            IOUtils.copy ( is, os );
            os.flush ( );
            message.setContent (  InputStream.class, os.getInputStream ( ) );
            is.close ( );

            System.out.println ("The request is: " + IOUtils.toString ( os.getInputStream ( ) ));
            os.close ( );
        }

        catch ( Exception ex )
        {
            ex.printStackTrace ( );
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

看,这里我还记录了请求来自的地址.您还可以从"HttpServletRequest"对象获取更多信息.你可以从http://cxf.apache.org/docs/interceptors.html获得更多

要记录响应xml,您可以查看 此线程


BPS*_*BPS 17

将以下内容添加到您的端点和客户端:

<jaxws:features>
    <bean class="org.apache.cxf.feature.LoggingFeature" />
</jaxws:features>
Run Code Online (Sandbox Code Playgroud)

这会将所有内容记录到服务器日志中.

如果要将它们记录到别处,请查看内置CXF LoggingInInterceptor和LoggingOutInterceptor的源代码.您可以按照他们使用的模式来获取进出的消息,并根据您的喜好进行操作.

使用以下内容将您自己的拦截器添加到链中:

<jaxws:inInterceptors>
    <ref bean="myLoggingInInterceptor" />
</jaxws:inInterceptors>
Run Code Online (Sandbox Code Playgroud)


jon*_*ckt 8

如果您使用Spring作为Java配置,有两种简单的方法可以使用Apache CXF激活SOAP消息的日志记录:

  1. 直接在SpringBus上 - 如果要记录所有CXF端点的消息,这很有用:

    @Bean(name=Bus.DEFAULT_BUS_ID) public SpringBus springBus() { SpringBus springBus = new SpringBus(); LoggingFeature logFeature = new LoggingFeature(); logFeature.setPrettyLogging(true); logFeature.initialize(springBus); springBus.getFeatures().add(logFeature); return springBus; }

  2. 在每个暴露的CXF端点上单独激活日志记录

    @Bean public Endpoint endpoint() { EndpointImpl endpoint = new EndpointImpl(springBus(), weatherService()); endpoint.publish(SERVICE_NAME_URL_PATH); endpoint.setWsdlLocation("Weather1.0.wsdl"); LoggingFeature logFeature = new LoggingFeature(); logFeature.setPrettyLogging(true); logFeature.initialize(springBus()); endpoint.getFeatures().add(logFeature); return endpoint; }

提醒LoggingFeature.setPrettyLogging(true); 查看漂亮的打印SOAP-Messages和LoggingFeature.initialize的方法(springBus()); - 没有后者,魔法就不会发生.为了更清晰的代码,您还可以将LoggingFeature分离为单独的Bean,并将其注入SpringBus或Endpoint-Bean.