Apache CXF
Par PlaceOweb le dimanche, août 22 2010, 20:57 - JAVA - Lien permanent
Apache CXF : An Open-Source Services Framework
Apache CXF : Un Open-Source Services Framework
- CXF User's Guide
- Apache CXF JavaDoc
- Developing a Consumer with CXF Generating the Stub Code, Implementing a CXF Client, Setting Connection Properties with Contexts
- Apache CXF > Debugging and LoggingDebugging and Logging
- Apache CXF > Setting up Eclipse
- CXF : WSDL to Java
- Apache CXF > How-Tos > Defining Contract first webservices with wsdl generation from java
- Resources and Articles Il s'agit de la page des ressources et des articles en dehors du projet CXF qui peuvent aider votre développement.
- Apache CXF > Overview > How do I integrate my application with CXF Transports, Bindings (HTTP Binding), Message Interception and Modification (JAX-WS frontend, Interceptors for manipulating the raw bytes or XML of the message.), Transmitting Binary Data, WS-* (WS-Addressing, WS-Policy, WS-Security, WS-ReliableMessaging), Invokers
- Apache CXF > Transports > HTTP Transport > Servlet Transport Accessing the MessageContext and/or HTTP Request and Response
- Apache CXF > Transports > HTTP Transport > Client HTTP Transport (including SSL support) and Timeout
- Apache CXF > Overview > How do I develop a client?
- Apache CXF > Setting up Eclipse > cxf-m2eclipse (Maven) Les principaux développeurs Maven ont cessé de maintenir le maven-eclipse-plugin, et déplacé toute leur attention à m2eclipse. Il est possible d'obtenir Eclipse pour utiliser les paramètres standard CXF, avec checkstyle et PMD, si vous êtes prêt à installer et configurer :
- Apache CXF - Checkstyle - http://eclipse-cs.sourceforge.net/update
- Apache CXF - PMD - http://pmd.sourceforge.net/eclipse
- Apache CXF - Subversion plugins - http://subclipse.tigris.org/update_1.4.x
- Apache CXF > Source Repository
- Apache CXF Documentation > Index > Deployment > Application Server Specific Configuration Guide JBoss, WebLogic, Websphere, OC4J ...
Apache CXF et Eclipse
CXF : Générer le code source java depuis un WSDL avec Eclipse Helios (3.6.x) ou supérieur, afin de créer un client WebService (WS) qui consommera ce service web CXF
Commencer par téléchargez Apache CXF (actuellement c'est la version 2.3.2), que vous décompresser ou bon vous semble (F:\apache-cxf-2.3.2\ chez nous).
Ensuite consulter : Windows -> Preferences -> Web Services -> CXF 2.x Preferences
On constate qu'il manque la librairie CXF, que nous allons ajouter dans l'onglet CXF Runtime -> Add :
On n'oublie de cocher cette nouvelle CFX Runtime pour s'en servir :
Puis, on crée un projet pour convertir notre WSDL en Java. Contrairement à Axis, il faut impérativement faire cela sur un projet de type : Dynamic Web Project. Créons ce Dynamic Web Project :
Nous nommerons ce Dynamic Web Project : "TestCxf", et comme nous n'avons pas de serveur web ou J2EE, nous laissons le Target runtime vide.
Après avoir fait Next, Next, Next ... le projet est créé :
On peut enchainer sur la création du client WS : File -> New -> Other -> Web Services -> Web Service Client
On colle l'URL contenant le WSDL :
http://cxf.apache.org/docs/defining-contract-first-webservices-with-wsdl-generation-from-java.data/CustomerService.wsdl?version=2&modificationDate=1219340552000
Ce fichier WSDL provient de la page Defining Contract first webservices with wsdl generation from java
On change la Web Service runtime pour choisir CXF :
Et malheureusement on ne pas valider et continuer puisque qu'aucun Server runtime n'est installé. :(
Nous allons choisir Jboss comme serveur, télécharger Jboss (ou un quelconque serveur qui gère CXF en natif). Une fois décompressé (F:\jboss-6.0.0.Final pour nous), on ajoute ce serveur dans la liste des serveurs :
On rajoute un serveur de type Jboss v5.0 et optionnellement on le renomme "JBoss v5.0 at localhost (jboss-6.0.0.Final)", puis Next, Next Next ...
Ce nouveau serveur Jboss est présent dans la liste des serveur :
On peut reprendre la création de notre WS Client : File -> New -> Other -> Web Services -> Web Service Client
On recolle l'URL contenant le WSDL :
http://cxf.apache.org/docs/defining-contract-first-webservices-with-wsdl-generation-from-java.data/CustomerService.wsdl?version=2&modificationDate=1219340552000
Et on modifie le "Server runtime" et le "Web service runtime"
Mais quelle misère ! Il nous indique que le Jboss v5.0 ne supporte pas le projet client TestCxf :(
On doit activer le Facet de notre projet : Properties -> Project Facets et on active "CXF 2.x Web Services"
Et dommage, ce n'est pas suffisant, on a toujours la même erreur.
Nous allons donc créer un projet nommé "TestCxf2" avec l'environnement complet dès le départ :
- CXF installé
- Un serveur runtime installé : Jboss
N'oubliez pas de :
- choisir votre Target Runtime : Jboss v5.0
- ce qui impactera automatiquement le Dynamic web module version qui passera de 3.0 en 2.5
- modifier la Configuration de "Default configuration for JBoss v5.0" en "CXF Web Services Project v2.5"
Puis Next, Next, Next ...
Une fois ce nouveau projet crée, on recommence la création d'un service web client depuis le WSDL :
http://cxf.apache.org/docs/defining-contract-first-webservices-with-wsdl-generation-from-java.data/CustomerService.wsdl?version=2&modificationDate=1219340552000
Et, enfin ! il n'indique plus d'erreur d'incompatibilité. N'oubliez pas toute fois de changer le Web Service runtime en Apache CXF 2.x
Puis Next, Next, Next ...
Et victoire, vous avez votre code JAVA généré depuis le WSDL.
Avec comme log, la ligne de commande utilisée :
Loading FrontEnd jaxws ... Loading DataBinding jaxb ... wsdl2java -client -d F:\workspaceEclipseJavaHelios\TestCxf2\.cxftmp/src -classdir F:\workspaceEclipseJavaHelios\TestCxf2\build\classes -p http://customerservice.example.com/=com.example.customerservice -impl -validate -exsh false -dns true -dex true -wsdlLocation http://localhost:9090/CustomerServicePort?wsdl -verbose -defaultValues -fe jaxws -db jaxb -wv 1.1 http://cxf.apache.org/docs/defining-contract-first-webservices-with-wsdl-generation-from-java.data/CustomerService.wsdl?version=2&modificationDate=1219340552000 wsdl2java - Apache CXF 2.3.1 log4j:WARN No appenders could be found for logger (org.apache.cxf.common.logging.LogUtils). log4j:WARN Please initialize the log4j system properly.
Vous pourrez remarquez que malgrès que l'on ai télécharger Apache CXF 2.3.2 il utilise la version 2.3.1 (qui est inclue dans Eclipse)
Ce qui aurait donné en ligne de commandes avec wsdl2java WSDL to Java :
F:\apache-cxf-2.3.2\bin>wsdl2java ERROR: Set JAVA_HOME to the path where the JDK (5.0 or higher) is installed F:\apache-cxf-2.3.2\bin>wsdl2java ERROR: Set JAVA_HOME to the path where the JDK (5.0 or higher) is installed F:\apache-cxf-2.3.2\bin>SET JAVA_HOME=C:\Program Files\Java\jre6 F:\apache-cxf-2.3.2\bin>wsdl2java Missing argument: wsdlurl Usage : wsdl2java -fe <front-end-name> -db <data-binding-name> -wv <wsdl-version> -p <[wsdl-namespace =]package-name>* -sn <service-name> -b <binding-file-name> * -reserveClass <class-name>* -catalog <catalog-file-name> -d <output-directory> -compile -classdir <compile-classes-directory> -impl -server -client -all -auto NameResolution -allowElementReferences<=true> -defaultValues<=class-name-for-DefaultValueProvider> -ant -nexclude <schema-namespace [= java-package-name]>* -exs h <(true, false)> -dns <Default value is true> -dex <(true, false)> -validate -keep -wsdlLocation <wsdlLocation> -xjc<xjc-arguments>* -noAddressBinding -useFQCN ForFaultSerialVersionUID -mark-generated -h -v -verbose -quiet -wsdlList <wsdlurl> WSDLToJava Error: org.apache.cxf.tools.common.toolspec.parser.BadUsageException: Missing argument: wsdlurl F:\apache-cxf-2.3.2\bin>wsdl2java -client -d F:\workspaceEclipseJavaHelios\TestCxf2\.cxftmp/src -classdir F:\workspaceEclipseJavaHelios\TestCxf2\build\classes -p http://customerservice.example.com/=com.example.customerservice -impl -validate -exsh false -dns true -dex true -wsdlLocation http://localhost:9090/CustomerServicePort?wsdl -verbose -defaultValues -fe jaxws -db jaxb -wv 1.1 http://cxf.apache.org/docs/defining-contract-first-webservices-with-wsdl-generation-from-java.data/CustomerService.wsdl?version=2&modificationDate=1219340552000 Loading FrontEnd jaxws ... Loading DataBinding jaxb ... wsdl2java -client -d F:\workspaceEclipseJavaHelios\TestCxf2\.cxftmp/src -classdir F:\workspaceEclipseJavaHelios\TestCxf2\build\classes -p http://customerservice.example.com/=com.example.customerservice -impl -validate -exsh false -dns true -dex true -wsdlLocation http://localhost:9090/CustomerServicePort?wsdl -verbose-defaultValues -fe jaxws -db jaxb -wv 1.1 http://cxf.apache.org/docs/defining-contract-first-webservices-with-wsdl-generation-from-java.data/CustomerService.wsdl?version=2 wsdl2java - Apache CXF 2.3.2
Et le résumé sans incident par la documentation Eclipse :
- JAX-WS Tools User Guide > Tasks : Generate a JAX-WS Web Service Client from a WSDL document using Apache CXF Générer un JAX-WS Web Service Client à partir d'un document WSDL en utilisant Apache CXF
- JAX-WS Tools User Guide > Tasks : http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.jst.ws.cxf.doc.user/tasks/create_bottomup.html Créer un service Web à partir d'un bean Java en utilisant la mise en œuvre Apache CXF
Un problème de génération des setter sur les éléments de type tableaux ou liste (multiples/multiplicité)
- WSDL2Java does not generate the setter method of a List of objects C'est une spécification JAXB.
__La spécification JAXB indique qu'il n'y a pas de setter pour les éléments multiples <List>. La méthode à utiliser, est simplement l'utilisation des méthodes de liste sur l'attribut à travers le getter :__
ObjetDeTypeList obj = new ObjetDeTypeList("monAttributDeObjetTypeList"); monObjet.getAttributDeTypeList().add(obj);
Suivez l'attribut "address" pour voir la problématique !
Initialement avant la création du WSDL on avait la classe suivante :
package com.example.customerservice; @XmlAccessorType( XmlAccessType.FIELD ) public class Customer { String name; String[] address; int numOrders; double revenue; BigDecimal test; Date birthDate; CustomerType type; }
Une fois convertit en WSDL :
<xs:complexType name="customer"> <xs:sequence> <xs:element minOccurs="0" name="name" type="xs:string"/> <xs:element maxOccurs="unbounded" minOccurs="0" name="address" nillable="true" type="xs:string"/> <xs:element name="numOrders" type="xs:int"/> <xs:element name="revenue" type="xs:double"/> <xs:element minOccurs="0" name="test" type="xs:decimal"/> <xs:element minOccurs="0" name="birthDate" type="xs:dateTime"/> <xs:element minOccurs="0" name="type" type="tns:customerType"/> </xs:sequence> </xs:complexType>
Puis reconvertit en JAVA :
public class Customer { protected String name; @XmlElement(nillable = true) protected List<String> address; protected int numOrders; protected double revenue; protected BigDecimal test; @XmlSchemaType(name = "dateTime") protected XMLGregorianCalendar birthDate; protected CustomerType type;
Donc on est passé d'un String[] en List<String>, ok cela nous bouleverse pas trop. Par contre le getter pour address est bien généré : getAddress(), mais le setter est absent ! il n'y à pas de setAdress(List<String> address)
Comment générer automatique ces setter pour les éléments multiples ?...
- Wsdl2java : how to auto-generate field array/List ?
- Wsdl2java : how to auto-generate field array/List ?
- Wsdl2java : how to auto-generate field array/List ?
I follow "Defining Contract first webservices with wsdl generation from java" : http://cxf.apache.org/docs/defining-contract-first-webservices-with-wsdl-generation-from-java.html When i generate WSDL to Java, attribute "address[]" (List<String> address) is in my class. The getter is generated. But the setter is missing ... <xs:element maxOccurs="unbounded" minOccurs="0" name="address" nillable="true" type="xs:string"/> Only the setters on maxOccurs="unbounded" are missing. wsdl2java don't generate attributes[] ? Is a way to generate setters on array attributes ?
===>
That's per the JAXB specification - you don't set the list, rather, you get the list and then add whatever elements you want to it. There's a collection setter injector plugin, but the link is presently broken: http://java.net/projects/jaxb2-comm... (link 11). See here for more info on JAXB customizations: http://www.jroller.com/gmazza/entry...
===> "cxf Collection setter injector plugin"
- Using JAXB2 Basics Plugins with CXF
- Cxf-codegen-plugin and collection setter
- JAXB2 Basics : Collection assignment instead of addAll() method call
- Eclipse Projects » Web Tools Project (WTP) » problem generating CXF-Webservice Client
Per XSD defaults, minOccurs and maxOccurs are defaulted to 1 if they are not shown. http://www.w3schools.com/Schema/sch...
Defining Contract first webservices with wsdl generation from java
Each element has minOccurs="0" which marks it as optional. This is a good thing as you can add new optional elements and keep compatible. If you do not want this optionality you can use @XmlElement(required=true).
The array of Strings for address is described as maxOccurs="unbounded" so the element may be repeated in the later xml to form the array.
La version d'Eclipse utilisée
- Eclipse.ini (si vous avez besoin de paramétrer la version Java ou la mémoire disponible pour Eclipse)
Les versions d'Eclipse et CXF (Help -> About Eclipse) :
- Eclipse;org -> Eclipse Platform
- Version: 3.6.1.r361_v20100909-9gF78GrkFqw7GrsZnvz0JWNTeb6fue6896L (Helios)
- Build id: M20100909-0800
- (c) Copyright Eclipse contributors and others 2000, 2010. All rights reserved.
- Visit http://www.eclipse.org/platform
- WTP -> CXF Web Services
- Version: 1.0.2.v201008232129-7H777DFAKlRiOX8lGdRoz0878J
- Build id: 20100915173744
- (c) Copyright Eclipse contributors and others 2008, 2010. All rights reserved.
- Visit http://www.eclipse.org/webtools/
Ressources sur Apache CXF, les framework de Web Services
- OCTO talks ! » CXF ou Axis ? Quelques chiffres J'utilisais déjà CXF, il me faudra des raisons très convaincantes pour passer à Axis !
- le code généré est beaucoup, beaucoup plus petit avec CXF qu’avec les autres …
- le code à écrire pour utiliser le bouchon est beaucoup plus simple et joli avec CXF
- CXF est plus long à s’initialiser, mais va plus vite après
- Bench de framework web service java : Axis2 vs Cxf vs Spring ws
- C'est quoi un framework web service?
- Les frameworks testés :
- Apache Axis2
- Apache Cxf
- Spring ws
Jboss & CXF
- JBoss CXF Web services
- mastertheboss : JBoss application server tutorials
- JBossWS
- JBossWS - Installation
- JBossWS - Stack CXF User Guide
- JBossWS - CXF WS-ReliableMessaging tutorial
- JBossWS - CXF WS-Addressing tutorial
- Deploiement d'un Web Service CXF avec JBOSS
- JBoss WS CXF User Guide
- JBossWS - Stack CXF User Guide Cette page traite des fonctionnalités disponibles dans la pile JBossWS CXF seulement.
- Community > JBoss Web Services > JBoss Web Services CXF
Section Maven (Obsolète)
Maven
Créer un projet J2EE dans Eclipse avec Maven : 2ème partie
J’insiste bien sur les 2 lignes (la fusion en une ligne ne fonctionne pas). De même, il faut placer ces 2 lignes avant la ligne -vmargs.
Remplacez C:\java\jdk1.6.0_21\bin par l’adresse du répertoire bin de votre jdk (oui, je sais, je suis sous Windows. Et alors ? )
Il reste à terminer le paramétrage de m2eclipse. Pour cela, sélectionner Window->Preferences->Maven->Installations. Par défaut, m2eclipse utilise une version préliminaire de Maven 3. Rappelons que Maven 3 est encore en développement. Afin d’utiliser la version stable de Maven, il faut installer Apache Maven. Puis indiquez à m2eclipse le chemin où trouver Maven (version 2.2.1 à la date de rédaction de l’article).
-vm C:\Program Files (x86)\Java\jdk1.6.0_22\bin -vmargs
http://wiki.eclipse.org/Eclipse.ini
- http://maven.apache.org/download.html
- http://marketplace.eclipse.org/content/maven-integration-eclipse
- http://m2eclipse.sonatype.org/installing-m2eclipse.html
- http://maven.apache.org/eclipse-plugin.html
- http://maven.apache.org/plugins/maven-eclipse-plugin/
- http://help.eclipse.org/help33/index.jsp?topic=/org.eclipse.platform.doc.user/tasks/running_eclipse.htm
Autres ressources CXF
- Apache CXF 2.0 Documentation > Index > JAX-WS Configuration (Configuring an Endpoint, Configuring a Client Proxy)
- WS-Trust support in CXF builds upon the WS-SecurityPolicy implementation to handle the IssuedToken policy assertions that could be found in the WS-SecurityPolicy fragment.
- How to avoid the need to specify the WSDL location in a CXF or JAX-WS generated webservice client?
- How to specify wsdlLocation for wsdl bundled in jar? You can find the URL at runtime for a file in the classpath by using the classloader getResource(String name) method.
- Using CXF web service from java web start
- instanciation des web services à la volée
- Développement d'un client dynamique à l'aide d'API JAX-WS JAX-WS fournit une nouvelle API dynamique de client Dispatch plus générique et offrant davantage de flexibilité que l'interface existante DII (Dynamic Invocation Interface) basée JAX-RPC (Java API for XML-based RPC).
- Tutoriel web services : installation Apache CXF Identifiez le positionnement de CXF par rapport à Apache Axis, Metro et Jboss WS. Comprenez pourquoi CXF est utilisé par de nombreuses équipes de développement pour développer et déployer leur services web. Apache CXF est le fruit de la fusion entre Apache Celtix (Bus de service (ESB) Java sponsorisé par IONA et développé par le consortioum ObjectWeb) et Apache XFire (framework de développement de services web basé sur SOAP), d’où le nom CXF
- Apache CXF et Hibernate hbm2java
- CXF - Java server / C# client : RequestSecurityToken
- Java web services: Introducing CXF
- Cxf Client URL and Timeout via Java Configuration
- How to change the service URL at runtime?
CXF exemple d'implémentation d'un client WS CXF
Client WS CXF avec changement de l'adresse (endpoint) (méthode 1)
URL wsdlLocation = new URL("http://www.placeoweb.com//ServiceCalculator.wsdl"); ServiceCalculatorSoapBindingImplService service = new ServiceCalculatorSoapBindingImplService(wsdlLocation); ServiceCalculator port = service.getServiceCalculatorSoapBindingImplPort(); ( (BindingProvider) port ).getRequestContext().put( BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://www.cxf.service.provider.com/uri" ); System.out.println("ws.endpoint [" + ((BindingProvider)port).getEndpointReference() + "]"); ClassResponse reponse = port.add(2,3);
Client WS CXF avec changement de l'adresse (endpoint) (méthode 2)
package com.sample; import org.apache.cxf.interceptor.*; import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; public class Client { public static void main(String args[]) throws Exception { JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.getInInterceptors().add(new LoggingInInterceptor()); factory.getOutInterceptors().add(new LoggingOutInterceptor()); factory.setServiceClass(Math.class); // factory.setAddress("http://localhost:8080/Samplews"); // javax.xml.ws.WebServiceException: Could not send Message. Caused by: java.io.IOException: IOException invoking http://localhost:8080/Samplews: HTTP response '404: Introuvable' factory.setAddress("http://localhost:8080/MyCxfProject"); Math client = (Math) factory.create(); System.out.println("Server said: " + client.sum(2000, 11)); // Server said: 2011 // server log : 23:20:54,462 INFO [STDOUT] Summing 2000 + 11 } }
Client WS CXF avec changement de l'adresse (endpoint) + authentification HTTP (HTTP Basic Auth) + configuration du timeout
package com.sample; import org.apache.cxf.interceptor.*; import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; public class Client { public static void main(String args[]) throws Exception { JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.getInInterceptors().add(new LoggingInInterceptor()); factory.getOutInterceptors().add(new LoggingOutInterceptor()); factory.setServiceClass(Math.class); // factory.setAddress("http://localhost:8080/Samplews"); // javax.xml.ws.WebServiceException: Could not send Message. Caused by: java.io.IOException: IOException invoking http://localhost:8080/Samplews: HTTP response '404: Introuvable' factory.setAddress("http://localhost:8080/MyCxfProject"); Math client = (Math) factory.create(); // HttpBasicAuthSupplier httpBasicAuthSupplier = new HttpBasicAuthSupplier(); // httpBasicAuthSupplier. //org.apache.cxf.interceptor.Fault: Could not send Message. //Caused by: org.apache.cxf.transport.http.HTTPException: HTTP response '401: Non-Autorisé' when communicating with http://localhost:8080/MyCxfProject String username = "monIdentifiantHttp"; String password = "monMotDePasseHTTP"; // HttpBasicAuthSupplier.createUserPass(userid, password); // HttpBasicAuthSupplier { // HttpBasicAuthSupplier.UserPass Client client = ClientProxy.getClient(clientWs); HTTPConduit conduit = (HTTPConduit) client.getConduit(); AuthorizationPolicy auth = conduit.getAuthorization(); auth.setUserName(username); auth.setPassword(password); HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); httpClientPolicy.setConnectionTimeout(36000); httpClientPolicy.setAllowChunking(false); httpClientPolicy.setReceiveTimeout(32000); System.out.println("Server said: " + client.sum(2000, 11)); // Server said: 2011 // server log : 23:20:54,462 INFO [STDOUT] Summing 2000 + 11 } }
Client CXF avec SSL
Pour activer le SSL sur CXF, c'est dans le même genre il faut modifier le conduit HTTP
Et modifier au besoins les règles quand on a des erreurs du type :
class javax.xml.ws.WebServiceException: javax.xml.ws.WebServiceException: Could not send Message. java.io.IOException: IOException invoking https://192.168.0.1/servicescxf/Calculator: The https URL hostname does not match the Common Name (CN) on the server certificate. To disable this check (NOT recommended for production) set the CXF client TLS configuration property "disableCNCheck" to true. java.io.IOException: The https URL hostname does not match the Common Name (CN) on the server certificate. To disable this check (NOT recommended for production) set the CXF client TLS configuration property "disableCNCheck" to true.
Lire les paramètres côté servlet
// HTTP Transport > Servlet Transport : http://cxf.apache.org/docs/servlet-transport.html // Accessing the MessageContext and/or HTTP Request and Response // First, declare a private field for the WebServiceContext in your service implementation, and annotate it as a resource: //@Resource //private WebServiceContext context; MessageContext ctx = context.getMessageContext(); HttpServletRequest request = (HttpServletRequest) ctx.get(AbstractHTTPDestination.HTTP_REQUEST); HttpServletResponse response = (HttpServletResponse) ctx.get(AbstractHTTPDestination.HTTP_RESPONSE); LOG.info("Parameter(\"test\"):" + request.getParameter("test"));
Ressources :
- CXF › cxf-user › How to increase Service time-out
- Setting timeout on generated JAXWS CXF Clients
- Apache CXF with HTTP Basic Authentication
- Uses of Class org.apache.cxf.transport.http.HttpBasicAuthSupplier.UserPass
- org.apache.cxf.transport.http Class HttpBasicAuthSupplier This abstract class is extended by developers who need HTTP Basic Auth functionality on the client side. It supplies userid and password combinations to an HTTPConduit.
- org.apache.cxf.transport.http Class HttpBasicAuthSupplier.UserPass
Tracer les logs des échanges (appel et réponse) CXF entre le client et le serveur,
Apache CXF > Debugging and LoggingDebugging and Logging : Logging Messages
Tracer les demandes et réponses depuis le serveur
import org.apache.cxf.feature.Features; @javax.jws.WebService(portName = "MyWebServicePort", serviceName = "MyWebService", ...) @Features(features = "org.apache.cxf.feature.LoggingFeature") // permet de tracer les échanges CXF public class MyWebServicePortTypeImpl implements MyWebServicePortType {
ou
import org.apache.cxf.interceptor.InInterceptors; import org.apache.cxf.interceptor.OutInterceptors; @javax.jws.WebService(portName = "WebServicePort", serviceName = "WebServiceService", ...) @InInterceptors(interceptors = "org.apache.cxf.interceptor.LoggingInInterceptor") // permet de tracer les échanges CXF entrants @OutInterceptors(interceptors = "org.apache.cxf.interceptor.LoggingOutInterceptor") // permet de tracer les échanges CXF sortants public class WebServicePortTypeImpl implements WebServicePortType {
Tracer les demandes et réponses depuis le client
import org.apache.cxf.endpoint.Client; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.interceptor.LoggingInInterceptor; import org.apache.cxf.interceptor.LoggingOutInterceptor; public class WSClient { public static void main (String[] args) { MyService ws = new MyService(); MyPortType port = ws.getPort(); Client client = ClientProxy.getClient(port); client.getInInterceptors().add(new LoggingInInterceptor()); // permet de tracer les échanges CXF entrants client.getOutInterceptors().add(new LoggingOutInterceptor()); // permet de tracer les échanges CXF sortants // make WS calls...
Voir aussi
- Getting raw XML parameter in JAX-WS webservice method
- Getting the raw xml from client.invoke()
- CXF Spring client: getting the message´s XML payload
cxf serializable
- How do I integrate my application with CXF La pure liaison XML évite la sérialisation d'une enveloppe SOAP et l'envoie juste en message XML brut.
- JAX-RS : Data Bindings
- Is it possible to generate serializable classes with CXF?
- Cxf-codegen-plugin and Serializable
- wsdl2java (cxf-codegen-plugin) and WSDL that uses <wsdl:import>s
- Customizing generated JAXB classes during the WSDL-to-Java process - Using a binding customization file
- How to make classes created from wsdl2java implements serializable?
<?xml version="1.0" encoding="UTF-8"?> <jaxws:bindings wsdlLocation="YOUR_WSDL_LOCATION" xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> <jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='YOUR_TARGET_NAMESPACE']"> <jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <jxb:serializable/> </jxb:globalBindings> </jaxws:bindings> </jaxws:bindings>
Tel qu'Eclipse, en modifiant les options :
- -fe jaxws => -fe jaxws21 //This constructor requires JAX-WS API 2.2. You will need to endorse the 2.2 //API jar or re-run wsdl2java with "-frontend jaxws21" to generate JAX-WS 2.1 //compliant code instead.
- rajout d'un binding : -b http://w.placeoweb.com/wsdl/modif/TestSerializable.xml
wsdl2java ^ -client ^ -d C:\workspaceEclipse37Indigo\WsCxf\src ^ -classdir C:\workspaceEclipse37Indigo\WsCxf\build\classes ^ -p http://validation.placeoweb.com/=com.placeoweb.jaxws21 ^ -impl ^ -validate ^ -exsh false ^ -dns true ^ -dex true ^ -wsdlLocation http://localhost:9090/ServiceValiderSoapBindingImplPort?wsdl ^ -verbose ^ -defaultValues ^ -fe jaxws21 ^ -db jaxb ^ -wv 1.1 ^ -b http://w.placeoweb.com/wsdl/modif/TestSerializable.xml ^ http://ws.placeoweb.com/wsdl/modif/ServiceValider.wsdl ERREUR RENCONTREE org.apache.cxf.tools.common.ToolException: Could not find any node with the XPath expression: //wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='My_TARGET_NAMESPACE']
TestSerializable.xml
<?xml version="1.0" encoding="UTF-8"?> <jaxws:bindings wsdlLocation="http://ws.placeoweb.com/wsdl/modif/ServiceValider.wsdl" xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> <jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema"> <jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <jxb:serializable/> </jxb:globalBindings> </jaxws:bindings> </jaxws:bindings> <!-- <jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='YOUR_TARGET_NAMESPACE']"> node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace=http://validation.placeoweb.com/]"> node="wsdl:definitions/wsdl:types/xs:schema"> OK !!! [Fatal Error] :8:1: Le type d'ÚlÚment "jaxws:bindings" doit Ûtre suivi des spÚcifications d'attribut, ">" ou "/>". WSDLToJava Error: The binding file: http://ws.placeoweb.com/wsdl/modif/TestSerializable.xml references a not well-formed xml document -->
ou encore plus simplement avec Eclipse et votre fichier xml à bindé (dans Binding Files: CxfSerializable.xml) prêt à l'emploi :
<?xml version="1.0" encoding="UTF-8"?> <!-- CxfSerializable.xml --> <jaxws:bindings xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> <jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema"> <jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <jxb:serializable/> </jxb:globalBindings> </jaxws:bindings> </jaxws:bindings>
Loading FrontEnd jaxws ... Loading DataBinding jaxb ... wsdl2java -client -d D:\workspaceEclipse37Indigo\myProject\.cxftmp/src -classdir D:\workspaceEclipse37Indigo\myProject\build\classes -p http://validation.placeoweb.com/=com.placeoweb.jaxws21 -b D:\WS-CXF-Serializable\CxfSerializable.xml -impl -validate -exsh false -dns true -dex true -wsdlLocation http://localhost:9090/ServiceValiderSoapBindingImplPort?wsd -verbose -defaultValues -fe jaxws -db jaxb -wv 1.1 http://ws.placeoweb.com/wsdl/modif/ServiceValider.wsdl wsdl2java - Apache CXF 2.5.1
// du coup les classes Java sont sérialisables : import java.io.Serializable; public class MyObject implements Serializable { // ...
cxf supprimer les Holder de WebParam.Mode.OUT
Pour comprendre le contexte : @WebService OUT params via javax.xml.ws.Holder
Utiliser @WebParam and javax.xml.ws.Holder : L'annotation @WebParam nous permet de déclarer les paramètres porteurs (Holders) en tant que WebParam.Mode.OUT de sortie.
Selon vos clients de web services (par exemple sous Android), il faudra simplifier en supprimant ces Holders (ce qui rajoutera un autre objet intermédiaire), tel que l'illustre jax-ws generation: @WebMethod vs. @ResponseWrapper :
Comme précédemment, on bind wsdl2java avec le fichier en paramètre (sous Eclipse, ou manuellement) :
-b D:\workspaceEclipse\WsMobile\jaxws-custom.xml
<!-- jaxws-custom.xml --> <!--JAX-WD Customization: disable wrapper style rules see also: http://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/2.0/jaxws/customizations.html#2.2_Wrapper_Style --> <jaxws:bindings wsdlLocation="v1.0/dxpInsurerServiceV1.0.wsdl" xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"> <jaxws:enableWrapperStyle>false</jaxws:enableWrapperStyle> </jaxws:bindings>
Commentaires
merci de m'avoir aidé dans mes premiers pas en web services