Est-il possible de consigner la demande/réponse au format XML à l'aide de CXF, idéalement dans un fichier séparé afin que je puisse surveiller ce qu'une application fait?
Ajoutez les éléments suivants à vos points de terminaison et clients:
<jaxws:features>
<bean class="org.Apache.cxf.feature.LoggingFeature" />
</jaxws:features>
Cela enregistrera tout dans le journal du serveur.
Si vous souhaitez les enregistrer ailleurs, consultez le code source des CXF LoggingInInterceptor et LoggingOutInterceptor intégrés. Vous pouvez suivre le modèle qu'ils utilisent pour saisir les messages lors de leur entrée/sortie et faire avec eux ce que vous aimez.
Ajoutez vos propres intercepteurs à la chaîne avec quelque chose comme ceci:
<jaxws:inInterceptors>
<ref bean="myLoggingInInterceptor" />
</jaxws:inInterceptors>
J'ai donc essayé un peu plus avec ça. Pour obtenir la demande XML et les réponses enregistrées, et si vous utilisez Log4J, vous devez définir le niveau de journalisation de CXF dans le fichier log4j.xml comme ceci (> = INFO):
<logger name="org.Apache.cxf" >
<level value="INFO" />
</logger>
Et le fichier cxf.xml devrait contenir ceci:
<cxf:bus>
<cxf:features>
<cxf:logging/>
</cxf:features>
</cxf:bus>
Les deux fichiers doivent être dans le 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 demande soap xml peut être facilement enregistrée par un intercepteur In personnalisé. Disons, nous avons un intercepteur nommé "wsLoggingInInterceptor", donc dans le fichier de contexte, ce sera comme suit:
<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 le xml de demande 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 également enregistrer l'adresse d'où provient la demande. Vous pouvez également obtenir plus d'informations à partir de l'objet "HttpServletRequest". vous pouvez en avoir plus de: http://cxf.Apache.org/docs/interceptors.html
Pour enregistrer le XML de réponse, vous pouvez consulter ce fil
Si vous utilisez Spring avec sa configuration Java, il existe 2 façons simples d'activer la journalisation des messages SOAP avec Apache CXF:
Directement sur le SpringBus - c'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; }
Activez la journalisation séparément sur chaque CXF-Endpoint exposé
@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; }
Rappelez LoggingFeature.setPrettyLogging (true); Méthode pour voir les messages SOAP et LoggingFeature.initialize (springBus ()); - sans ce dernier, la magie ne se produit pas. Pour un code plus propre, vous pouvez également séparer la fonction LoggingFeature en tant que bean distinct et l'injecter dans votre SpringBus ou Endpoint-Bean.
Il est beaucoup plus facile d'ajouter votre propre enregistreur aux propriétés du noeud final. Dans ce cas, l'intercepteur de journalisation par défaut recherchera votre enregistreur dans les propriétés du noeud final et s'il en trouve un, il l'utilisera sinon il créera une 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>