La journalisation des requêtes/réponses avec Apache CXF XML
est-il possible d'enregistrer la requête/réponse en XML à L'aide de CXF, idéalement dans un fichier séparé afin que je puisse surveiller ce qu'une application fait?
5 réponses
ajouter ce qui suit à vos paramètres et clients:
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature" />
</jaxws:features>
cela va tout enregistrer dans le journal du serveur.
si vous voulez les Logger ailleurs, alors regardez le code source de la CXF loggingininterceptor et LoggingOutInterceptor. Vous pouvez suivre le modèle qu'ils utilisent pour attirer les messages sur leur chemin et en faire ce que vous aimez.
Ajoutez vos propres intercepteurs à la chaîne avec quelque chose comme ceci:
<jaxws:inInterceptors>
<ref bean="myLoggingInInterceptor" />
</jaxws:inInterceptors>
Donc, j'ai essayé un peu plus avec cette. Pour obtenir la requête XML et les réponses journalisées, et si vous utilisez Log4J, vous devez définir le niveau de Log de CXF dans le log4j.xml fichier comme ceci (>=INFO):
<logger name="org.apache.cxf" >
<level value="INFO" />
</logger>
et le cxf.le fichier xml devrait contenir ceci:
<cxf:bus>
<cxf:features>
<cxf:logging/>
</cxf:features>
</cxf:bus>
les deux fichiers doivent être dans CLASSPATH.
pour afficher le message soap ajoutez ceci à votre code:
Client client = ClientProxy.getClient(service);
client.getInInterceptors().add(new LoggingInInterceptor());
client.getOutInterceptors().add(new LoggingOutInterceptor());
la requête SOAP xml peut être enregistrée facilement par un client dans interceptor. Disons que nous avons un intercepteur nommé "wsLoggingInInterceptor", donc dans le fichier de contexte, ce sera comme ceci:
<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>
dans la classe, nous pouvons obtenir la requête xml comme suit:
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 ( );
}
}
}
Regardez, ici j'ai aussi enregistrer l'adresse d'où la demande vient. Vous pouvez également obtenir plus d'informations à partir de L'objet "HttpServletRequest". vous pouvez avoir plus de : http://cxf.apache.org/docs/interceptors.html
pour enregistrer la réponse xml, vous pouvez avoir un regard sur ce fil
si vous utilisez Spring avec sa Configuration Java, il y a 2 façons faciles d'activer la journalisation des messages SOAP avec Apache CXF:
-
directement sur le SpringBus - qui est utile, si vous voulez enregistrer les Messages de tous vos CXF-Endpoints:
@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; }
-
Activer la Journalisation séparément sur chaque exposé CXF-Endpoint
@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; }
rappeler le LoggingFeature.setPrettyLogging (true); méthode pour voir de jolis SOAP-Messages imprimés et LoggingFeature.initialiser (springBus ()); - sans cette dernière, la magie ne se produit pas. Pour le code cleaner, vous pouvez également séparer le LoggingFeature en haricots séparés et l'injecter soit dans votre SpringBus ou Endpoint-Bean.
il est beaucoup plus facile d'ajouter votre propre logger aux propriétés des paramètres. Dans ce cas, l'intercepteur de journalisation par défaut recherchera votre logger dans les propriétés de finpoint et s'il en trouve un, il l'utilisera sinon il créera la valeur par défaut. Voici mon exemple d'utilisation:
<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>