Как зарегистрировать Apache CXF Soap Request и Soap Response, используя Log4j? - PullRequest
39 голосов
/ 09 ноября 2011

Я использую 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()));

Это только печать true и true внутри файла журнала.

Может кто-нибудь, пожалуйста, дайте мне знать, как настроить это?

Ответы [ 9 ]

66 голосов
/ 09 ноября 2011

Вам необходимо создать файл с именем org.apache.cxf.Logger (то есть: org.apache.cxf файл с расширением Logger) в /META-INF/cxf/ со следующим содержимым:

org.apache.cxf.common.logging.Log4jLogger

Ссылка: Использование Log4j вместо 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-сообщения, форматируя их с правильными отступами и переносами строк.Очень полезно.Подробнее об этом здесь .

13 голосов
/ 02 февраля 2012

Другой простой способ - настроить регистратор следующим образом: убедитесь, что вы делаете это перед загрузкой классов, связанных с веб-сервисом cxf. Вы можете использовать его в некоторых статических блоках.

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 настроен правильно

11 голосов
/ 16 ноября 2012

Самый простой способ добиться красивой регистрации в 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);
2 голосов
/ 08 февраля 2018

Это сработало для меня.

Настройте 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);
2 голосов
/ 25 июня 2015

В вашем весеннем контексте настройка ниже запишет мыльный запрос запроса и ответа.

<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>
1 голос
/ 01 декабря 2015

Попробуйте этот код:

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

Внутри logback.xml необходимо указать имя интерфейса для веб-службы:

<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>
1 голос
/ 15 февраля 2014

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

Пожалуйста, проверьте скриншот здесь

1 голос
/ 23 июля 2013

При настройке log4j.properties достаточно установить org.apache.cxf уровень ведения журнала на INFO, чтобы увидеть простые SOAP-сообщения:

log4j.logger.org.apache.cxf=INFO

Слишком подробный отладчик.

0 голосов
/ 14 апреля 2017

Если кто-то захочет сделать это, используя Play Framework (и используя LogBack http://logback.qos.ch/),, тогда вы можете настроить application-logger.xml с помощью следующей строки:

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

Для меня это сработало;)

...