如何使用Log4j记录Apache CXF Soap请求和Soap响应?

时间:2011-11-09 13:31:29

标签: log4j cxf

我使用的是Apache CXF Framework。 在我的客户端程序中,我需要记录CXF SOAP请求和SOAP响应。 我用的时候

JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setAddress(host);
factory.setServiceClass(MyService.class);
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());

我在控制台中获得了这些SOAP请求和SOAP响应:

Nov 9, 2011 6:48:01 PM org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback onClose
INFO: Outbound Message
---------------------------
ID: 2
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns4:MYResponse
--------------------------------------

但我的实际要求是,我需要将它们放在日志文件中,而不是将它们打印到服务器控制台。

当我直接使用log4j时如图所示

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

只在日志文件中打印truetrue

有人可以让我知道如何配置吗?

10 个答案:

答案 0 :(得分:66)

您需要在org.apache.cxf.Logger下创建一个名为org.apache.cxf的文件(即Logger文件,其中包含/META-INF/cxf/扩展名),其中包含以下内容:

org.apache.cxf.common.logging.Log4jLogger

参考:Using Log4j Instead of java.util.logging

此外,如果您更换标准:

<cxf:bus>
  <cxf:features>
    <cxf:logging/>
  </cxf:features>
</cxf:bus>

更冗长:

<bean id="abstractLoggingInterceptor" abstract="true">
    <property name="prettyLogging" value="true"/>
</bean>
<bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" parent="abstractLoggingInterceptor"/>
<bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" parent="abstractLoggingInterceptor"/>

<cxf:bus>
    <cxf:inInterceptors>
        <ref bean="loggingInInterceptor"/>
    </cxf:inInterceptors>
    <cxf:outInterceptors>
        <ref bean="loggingOutInterceptor"/>
    </cxf:outInterceptors>
    <cxf:outFaultInterceptors>
        <ref bean="loggingOutInterceptor"/>
    </cxf:outFaultInterceptors>
    <cxf:inFaultInterceptors>
        <ref bean="loggingInInterceptor"/>
    </cxf:inFaultInterceptors>
</cxf:bus>

Apache CXF将使用适当的缩进和换行符打印格式化XML消息。很有用。关于它的更多信息here

答案 1 :(得分:13)

另一种简单的方法是像这样设置记录器 - 确保在加载与cxf Web服务相关的类之前执行此操作。您可以在一些静态块中使用它。

YourClientConstructor() {

  LogUtils.setLoggerClass(org.apache.cxf.common.logging.Log4jLogger.class);

  URL wsdlURL = YOurURL;//

  //create the service
  YourService = new YourService(wsdlURL, SERVICE_NAME);
  port = yourService.getServicePort(); 

  Client client = ClientProxy.getClient(port);
  client.getInInterceptors().add(new LoggingInInterceptor());
  client.getOutInterceptors().add(new LoggingOutInterceptor());
}

然后,入站和出站消息将打印到Log4j文件而不是控制台。确保您的log4j配置正确

答案 2 :(得分:11)

在Preethi Jain szenario中实现漂亮记录的最简单方法:

LoggingInInterceptor loggingInInterceptor = new LoggingInInterceptor();
loggingInInterceptor.setPrettyLogging(true);
LoggingOutInterceptor loggingOutInterceptor = new LoggingOutInterceptor();
loggingOutInterceptor.setPrettyLogging(true);
factory.getInInterceptors().add(loggingInInterceptor);
factory.getOutInterceptors().add(loggingOutInterceptor);

答案 3 :(得分:2)

在您的春季环境中,下面的配置会记录请求和响应soap messsage。

<bean id="loggingFeature" class="org.apache.cxf.feature.LoggingFeature">
    <property name="prettyLogging" value="true" />
</bean>

<cxf:bus>
    <cxf:features>
        <ref bean="loggingFeature" />
    </cxf:features>
</cxf:bus>

答案 4 :(得分:2)

这对我有用。

正常设置log4j。然后使用此代码:

    // LOGGING 
    LoggingOutInterceptor loi = new LoggingOutInterceptor(); 
    loi.setPrettyLogging(true); 
    LoggingInInterceptor lii = new LoggingInInterceptor(); 
    lii.setPrettyLogging(true); 

    org.apache.cxf.endpoint.Client client = org.apache.cxf.frontend.ClientProxy.getClient(isalesService); 
    org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint(); 

    cxfEndpoint.getOutInterceptors().add(loi); 
    cxfEndpoint.getInInterceptors().add(lii);

答案 5 :(得分:1)

配置log4j.properties时,将org.apache.cxf日志记录级别设置为INFO就足以看到普通的SOAP消息:

log4j.logger.org.apache.cxf=INFO

DEBUG太冗长了。

答案 6 :(得分:1)

<强> cxf.xml

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

<强> org.apache.cxf.Logger

org.apache.cxf.common.logging.Log4jLogger

请检查屏幕截图here

答案 7 :(得分:1)

试试这段代码:

EndpointImpl impl = (EndpointImpl)Endpoint.publish(address, implementor);
    impl.getServer().getEndpoint().getInInterceptors().add(new LoggingInInterceptor());
    impl.getServer().getEndpoint().getOutInterceptors().add(new LoggingOutInterceptor());

logback.xml内,你需要为webservice设置接口名称:

<appender name="FILE" class="ch.qos.logback.classic.sift.SiftingAppender">
    <discriminator
        class="com.progressoft.ecc.integration.logging.ThreadNameDiscriminator">
        <key>threadName</key>
        <defaultValue>unknown</defaultValue>
    </discriminator>
    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
        <evaluator>
            <expression>logger.contains("InterfaceWebServiceSoap")</expression>
        </evaluator>
        <OnMismatch>DENY</OnMismatch>
        <OnMatch>NEUTRAL</OnMatch>
    </filter>
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>TRACE</level>
    </filter>
    <sift>
        <appender name="FILE-${threadName}"
            class="ch.qos.logback.core.rolling.RollingFileAppender">
            <File>${LOGGING_PATH}/${threadName}.log</File>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <FileNamePattern>${ARCHIVING_PATH}/%d{yyyy-MM-dd}.${threadName}%i.log.zip
                </FileNamePattern>
                <MaxHistory>30</MaxHistory>
                <TimeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <MaxFileSize>50MB</MaxFileSize>
                </TimeBasedFileNamingAndTriggeringPolicy>
            </rollingPolicy>
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <Pattern>%date{dd-MM-yyyy HH:mm:ss.SSS} | %5level | %-60([%logger{53}:%line]): %msg %ex{full} %n</Pattern>
            </encoder>
        </appender>
    </sift>
</appender>

<root>
    <level value="ALL" />
    <appender-ref ref="FILE" />
</root>

答案 8 :(得分:0)

如果有人想要这样做,使用Play Framework(并使用LogBack http://logback.qos.ch/),那么您可以使用以下行配置application-logger.xml:

 <logger name="org.apache.cxf" level="DEBUG"/>

对我而言,它就是诀窍;)

答案 9 :(得分:0)

使用log4j记录器对SOAP / REST请求/响应的客户机/服务器记录进行全局设置的过程。 这样,您无需更改代码,war,jar文件等即可为整个应用程序设置日志记录。

  1. 将文件cxf-rt-features-logging-X.Y.Z.jar安装到您的CLASS_PATH

  2. 创建文件(例如路径:/opt/cxf/cxf-logging.xml):

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://cxf.apache.org/core" 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-2.0.xsd">
    <cxf:bus>
     <cxf:features>
     <bean class="org.apache.cxf.ext.logging.LoggingFeature">
     <property name="prettyLogging" value="true"/>
     </bean>
     </cxf:features>
     </cxf:bus>
     </beans>
    
  3. 设置org.apache.cxf的日志记录(log4j 1.x)log4j.logger.org.apache.cxf=INFO,YOUR_APPENDER

  4. 在Java启动时设置这些属性

java ... -Dcxf.config.file.url=file:///opt/cxf/cxf-logging.xml -Dorg.apache.cxf.Logger=org.apache.cxf.common.logging.Log4jLogger -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true -Dcom.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump=true -Dcom.sun.xml.ws.transport.http.HttpAdapter.dump=true -Dcom.sun.xml.internal.ws.transport.http.HttpAdapter.dump=true ...

我不知道为什么,但是也必须设置变量com.sun.xml.*