在 spring 中使用 Apache cxf 拦截器和 log4j 记录完整的请求和响应

logging full request and response using Apache cxf interceptor and log4j in spring

我正在尝试在 spring

中使用 Apache cxf、Log4j 记录 soap 网络服务的请求和响应

以下是我的项目结构

我的 cxf.xml 是

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:cxf="http://cxf.apache.org/core" 
xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemalocation="http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

   <bean class="org.apache.cxf.interceptor.LoggingInInterceptor" id="loggingInInterceptor" />
   <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" id="logOutInterceptor" />

    <cxf:bus>
        <cxf:ininterceptors>
            <ref bean="loggingInInterceptor" />
        </cxf:ininterceptors>
        <cxf:outinterceptors>
            <ref bean="logOutInterceptor" />
        </cxf:outinterceptors>
    </cxf:bus>



</beans>

我的bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:cxf="http://cxf.apache.org/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
    xsi:schemaLocation="http://cxf.apache.org/core 
                         http://cxf.apache.org/schemas/core.xsd
                         http://www.springframework.org/schema/beans 
                         http://www.springframework.org/schema/beans/spring-beans.xsd
                         http://cxf.apache.org/jaxws  
                         http://cxf.apache.org/schemas/jaxws.xsd">

    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

    <jaxws:endpoint id="bookShelfService"
        implementor="com.test.services.BookShelfServiceImpl" address="/bookshelfservice" />

</beans>

log4j.properties

# Root logger option
log4j.rootLogger=INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=C:\wsimport\log.txt
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

我的org.apache.cxf.Logger

org.apache.cxf.common.logging.Log4jLogger

和web.xml

<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >

  <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/beans.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener> 

    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>

我已经完成了以上所有事情,但我仍然没有通过 headers

获取服务请求和响应的日志

我正在使用 tomcat 部署我的应用程序并使用 soapui 来执行服务。

我做错了什么?

请多多指教。

但是当我执行下面的代码时,我在 eclipse 控制台中得到了预期的结果

JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setServiceClass(BookShelfService.class); //the service SEI
        factory.setAddress("http://localhost:8080/springapp/bookshelfservice");

        factory.getInInterceptors().add(new LoggingInInterceptor());
        factory.getOutInterceptors().add(new LoggingOutInterceptor());

        BookShelfService client = (BookShelfService) factory.create();

        BookVO reply = client.getBook("b1");
        System.out.println("Server said: " + reply.getAuthor());

我很确定您不需要创建自己的 cxf.xml 它已经由 cxf-core jar 提供。所以我认为你不应该覆盖它。因为它会创建一个新的 Spring 总线,可能无法使用 cxf 方式正确配置。删除 cxf.xml 以避免冲突,只需将 cxf.xml 导入 bean.xml 并将 cxf.xml 代码放入 bean.xml。试试这个更新后的 bean.xml.

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:cxf="http://cxf.apache.org/core" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:jaxws="http://cxf.apache.org/jaxws" 
       xmlns:jaxrs="http://cxf.apache.org/jaxrs" 
       xsi:schemaLocation="http://cxf.apache.org/core 
                           http://cxf.apache.org/schemas/core.xsd
                           http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://cxf.apache.org/jaxws  
                           http://cxf.apache.org/schemas/jaxws.xsd">

    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

    <bean class="org.apache.cxf.interceptor.LoggingInInterceptor" id="loggingInInterceptor" />
    <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" id="logOutInterceptor" />

    <cxf:bus>
        <cxf:ininterceptors>
            <ref bean="loggingInInterceptor" />
        </cxf:ininterceptors>
        <cxf:outinterceptors>
            <ref bean="logOutInterceptor" />
        </cxf:outinterceptors>
    </cxf:bus>


    <jaxws:endpoint id="bookShelfService" implementor="com.test.services.BookShelfServiceImpl" address="/bookshelfservice" />

</beans>