Протоколирование запроса / ответа с помощью Apache CXF в формате XML
можно ли зарегистрировать запрос / ответ как XML с помощью CXF, в идеале в отдельный файл, чтобы я мог контролировать, что делает приложение?
5 ответов
добавьте в конечные точки и клиенты следующее:
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature" />
</jaxws:features>
это будет регистрировать все в журнале сервера.
Если вы хотите зарегистрировать их в другом месте, то посмотрите на исходный код встроенного CXF LoggingInInterceptor и LoggingOutInterceptor. Вы можете следовать шаблону, который они используют, чтобы захватить сообщения на своем пути в / ИЗ и делать с ними то, что вам нравится.
добавьте свои собственные перехватчики в цепочку с чем-то вроде этого:
<jaxws:inInterceptors>
<ref bean="myLoggingInInterceptor" />
</jaxws:inInterceptors>
Итак, я попробовал немного с этим. Чтобы получить XML-запрос и ответы, зарегистрированные, и если вы используете Log4J, вам нужно установить уровень журнала CXF в log4j.xml файл, подобный этому (>= INFO):
<logger name="org.apache.cxf" >
<level value="INFO" />
</logger>
и в CXF.в XML должны содержащего это:
<cxf:bus>
<cxf:features>
<cxf:logging/>
</cxf:features>
</cxf:bus>
оба файла должны находиться в пути к классам.
чтобы отобразить сообщение soap, добавьте это в свой код:
Client client = ClientProxy.getClient(service);
client.getInInterceptors().add(new LoggingInInterceptor());
client.getOutInterceptors().add(new LoggingOutInterceptor());
запрос soap xml может быть легко зарегистрирован Пользователем в перехватчике. Скажем, у нас есть перехватчик с именем "wslogginginininterceptor", поэтому в контекстном файле он будет выглядеть следующим образом :
<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>
в классе мы можем получить запрос 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 ( );
}
}
}
смотрите, здесь я также регистрирую адрес, откуда поступает запрос. Вы также можете получить дополнительную информацию из объекта "HttpServletRequest". вы можете иметь больше из : http://cxf.apache.org/docs/interceptors.html
для регистрации ответа xml вы можете посмотреть на этой теме
Если вы используете Spring с его Java-конфигурацией, есть 2 простых способа активировать ведение журнала SOAP-сообщений с Apache CXF:
-
непосредственно на 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; }
-
активируйте ведение журнала отдельно на каждой открытой конечной точке 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-сообщений и LoggingFeature.инициализировать (springBus ()); - без последнего магия не происходит. Для более чистого кода Вы также можете отделить LoggingFeature как отдельный Боб и ввести его либо в SpringBus, либо в Endpoint-Bean.
гораздо проще добавить свой собственный регистратор в свойства конечной точки. В этом случае перехватчик журналов по умолчанию будет искать ваш регистратор в свойствах конечной точки, и если он найдет его, он будет использовать его, иначе он создаст default. Вот мой пример использования:
<jaxws:endpoint
xmlns:client="http://service.info.client.diasoft.services.stream.integration.cib.sberbank.ru"
address="/diasoft/clientInfoWS"
serviceName="client:ClientWS"
implementor="#clientServiceImpl">
<jaxws:properties>
<entry key="MessageLogger" value-ref="logger"/>
</jaxws:properties>
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature"/>
</jaxws:features>
</jaxws:endpoint>
<bean id="logger" class="org.apache.cxf.common.logging.LogUtils" factory-method="getLogger">
<constructor-arg value="ru.sberbank.cib.integration.stream.services.diasoft.client.info.service.ClientWSImpl"/>
</bean>