Как зарегистрировать Apache CXF Soap Request и Soap Response, используя Log4j?
Я использую Apache CXF Framework.
Внутри моей клиентской программы мне нужно регистрировать запросы CAPF 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
внутри файла журнала.
Может кто-нибудь, пожалуйста, дайте мне знать, как настроить это?
Ответы
Ответ 1
Вам необходимо создать файл с именем 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-сообщения, форматируя их с правильными отступами и переносами строк. Очень полезно. Подробнее об этом здесь.
Ответ 2
Еще один простой способ - установить регистратор следующим образом: убедитесь, что вы делаете это, прежде чем загружать связанные с 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 настроен правильно
Ответ 3
Простейший способ добиться хорошей регистрации в 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);
Ответ 4
В вашей конфигурации spring контекст ниже будет записываться сообщение с сообщением о запросах и ответах.
<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>
Ответ 5
Это сработало для меня.
Настройте 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);
Ответ 6
При настройке log4j.properties
достаточно установить уровень журналирования org.apache.cxf
на INFO
, чтобы увидеть обычные сообщения SOAP:
log4j.logger.org.apache.cxf=INFO
DEBUG слишком многословно.
Ответ 7
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
Проверьте скриншот здесь
Ответ 8
Попробуйте этот код:
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>
Ответ 9
Если кто-то захочет это сделать, используя Play Framework (и используя LogBack http://logback.qos.ch/), вы можете настроить приложение- logger.xml с этой строкой:
<logger name="org.apache.cxf" level="DEBUG"/>
Для меня это сделал трюк;)