Accueil > Non classé > Création et utilisation de webservice avec Java 6

Création et utilisation de webservice avec Java 6

On y pense pas forcement mais les webservices font partie de J2SE 6. Oui oui, vous avez bien lu : J2SE 6. C’est d’ailleurs ce qui a conduit JBoss à créer deux versions, une pour java 5 et une pour  java 6, pour cause de conflits de librairies.  Cela signifie qu’il n’y a pas besoin de conteneur pour déployer un web service.

Il est assez simple de créer un web service avec J2SE. Il suffit d’annoter une classe quelconque avec l’annotation javax.jws.WebService bien connue :


1
2
3
4
5
6
7
8
9
10
package com.exemple.testws;

import javax.jws.WebService;

@WebService
public class Ws {
    public String hello() {
        return "Hello, World";
    }
}

Il faut ensuite générer les classes du service avec la commande wsgen, présente dans le jdk 6 :


1
$wsgen -cp. ../bin -keep  com.exemple.testws.Ws

On peut ensuite voir apparaitre les classes générées dans eclipse :

La classe du web service annotée et les classes générées par wsgen

La classe du web service annotée et les classes générées par wsgen

Pour lancer le service il n’y a plus qu’à créer un main() qui servira de lanceur. L’URL est arbitraire.


1
2
3
4
5
6
7
package com.exemple.testws;
import javax.xml.ws.Endpoint;
public class WsLauncher {
    public static void main(String[] args) {
        Endpoint.publish("http://localhost:8080/Ws", new Ws());
    }
}

La wsdl est accessible à l’adresse demandée :

Wsdl dans firefox

Wsdl dans firefox

On peut ensuite créer le client de manière traditionnelle avec wsimport :


1
2
3
4
$wsimport  -keep http://localhost:8080/Ws?wsdl
parsing WSDL...
generating code...
compiling code...

Et utiliser le code généré pour le client :


1
2
3
4
5
6
7
8
9
10
package com.exemple.testws.client;
import com.exemple.testws.Ws;
import com.exemple.testws.WsService;
public class Client {
    public static void main(String[] args) {
        WsService service = new WsService();
        Ws ws = service.getWsPort();
        System.out.println(ws.hello());
    }
}

Et voilà ! Simple, non ?

helloworld

Share
Categories: Non classé Tags: , ,
  1. Pierre-Yves RICAU
    10/12/2009 à 17:23 | #1

    Génial! J’ignorai totalement qu’on pouvait faire des WS SOAP en J2SE …

    Ca peut-être vraiment pratique pour prototyper/mocker, notamment quand le développement du client n’est pas tout à fait synchro avec le développement du back :-)

  2. Maxime Picque
    10/12/2009 à 17:53 | #2

    je précise aussi qu’il est possible d’utiliser la méthode “bottom-up”, c’est à dire créer la WSDL à la main et ensuite générer toutes les classes à l’aide de wsgen en précisant le paramètre -wsdl (chemin d’accès à la wsdl pour la génération des classes) et -wsdlLocation (URI utilisée par JaxWS pour retourver la WSDL associée au service.

  3. Raphaël LEMAIRE
    10/12/2009 à 19:11 | #3

    Hum je ne crois pas que ce soit possible avec wsgen. Un wsgen -help te donnera les options disponibles : il y a un bien un -wsdl mais il permet de générer la wsdl à partir de la classe.

    Je pense que tu confonds avec CXF (anciennement xFire) qui lui, le fait. Et me donne quelques soucis cette après midi.

  4. 10/12/2009 à 21:44 | #4

    @Maxime

    Je vous rejoins, je suis un ardent défenseur de l’approche “contract first” pour SOAP et j’ai pour référence sur le sujet le document “Spring WS – Why Contract First?” (1) et d’ailleurs, je regrette beaucoup que Spring WS ne permette pas de faire du “WSDL to Java” mais seulement du “XSD to Java”.

    Si je peux me permettre, j’ai l’impression que vous avez fait une petite coquille dans votre élan pour défendre “Contract First”, la commande pour faire du “WSDL to Java” avec l’implémentation JAX-WS embarquée dans la JVM (2) est plutôt wsimport (3) que wsgen ;-) .

    Pour revenir sur “Contract First” versus “Code First”, j’aime utiliser SOAP pour intégrer entre elles des applications et j’aime alors avoir un contrat très strict et très documenté que m’offre WSDL même si je reconnais que WSDL n’est pas très agréable à utiliser. Je ne modifie alors jamais les XSD et WSDL que je versionne (namespaces et nom de fichier) et je ne risque pas de “casser le contrat” lorsque je refactore du code. Si j’ai des évolutions à faire, je créé une nouvelle version du contrat et je continue à exposer les anciennes version de mes services. Souvent, il suffit de brancher les anciennes versions du contrat sur la plus récente en faisant un mapping à la main voir avec un framework comme Dozer (4) ; l’approche manuelle, même si elle est plus verbeuse, m’a souvent été la plus efficace.

    Pour les communications internes à une application (ajax, un seul widget/flash associé à un service, stockage sur disque de configuration, etc), je préfère alors l’approche “code first” mais dans ce cas, je préfère m’éloigner de SOAP au profit d’approche Plain Old Xml / JSON voire REST et je privilégie alors JAXB / JAX-RS et j’attends avec impatience Spring MVC 3 REST (5).

    Cyrille

    (1) http://static.springsource.org/spring-ws/sites/1.5/reference/html/why-contract-first.html
    (2) JAX-WS RI : https://jax-ws.dev.java.net/
    (3) http://java.sun.com/javase/6/docs/technotes/tools/share/wsimport.html
    (4) http://dozer.sourceforge.net/
    (5) http://blog.springsource.com/2009/03/08/rest-in-spring-3-mvc/

  5. 10/12/2009 à 21:57 | #5

    @Raphaël

    CXF apporte son lot de moment ‘délicats’ mais j’aime beaucoup cette implémentation parce qu’elle est bien intégrée à Spring, qu’elle offre des fonctionnalités importante en production (logging, monitoring JMX, etc), qu’elle offre aussi REST et que ce projet est très ouvert au contributions des utilisateurs.

    JAX-WS RI / Metro (1) est aussi une très bonne implémentation SOAP mais je trouve que c’est un implémentation “un peu trop brute de fonderie”, activer des logs est délicat, je n’ai pas trouvé de monitoring JMX, … et le projet est moins ouvert que CXF ; je ne m’imaginais pas proposer une contribution pour améliorer le logging par exemple :-) En revanche, je crois que l’intégration de JAX-WS RI dans Glassfish 3 apporte certaines des fonctionnalités qu’il me manquait ; hélas j’utilise Tomcat :-)

    Pour Axis 2, je ne connais pas. J’ai beaucoup utilisé Axis 1 mais les ‘soucis de démarrage’ et l’impression de complexité d’Axis 2 m’ont coupé dans mon élan.

    Un ‘disclaimer’ quand même. Après avoir proposé plusieurs correctifs et évolutions au projet CXF, ils m’ont intégré la semaine dernière comme committer et je me fais régulièrement charrier par mon entourage qui rencontre des misères avec le framework :-)

    Cyrille

    (1) https://metro.dev.java.net/

  6. Maxime PICQUE
    11/12/2009 à 10:23 | #6

    Effectivement Raphaël, après vérification, la commande n’est pas wsgen mais wsimport.

    Mea culpa.

  7. Maxime PICQUE
    11/12/2009 à 10:34 | #7

    Voici la commande wsimport à utiliser :

    wsimport -d src -p com.excilys.testws.service -wsdllocation /META-INF/wsdl/MonService.wsdl src/META-INF/wsdl/MonServiceService.wsdl

    à supposer qu’on se trouve à la base du projet.

  8. Raphaël LEMAIRE
    11/12/2009 à 21:35 | #8

    Merci Maxime.

    L’approche contract first est en effet beaucoup plus sympa pour les clients qui n’ont pas a régénérer leur code à chaque petite modification du serveur. Mais bon c’est quand même un peu programmer en xml et je fais partie de ceux qui n’adorent pas cela.

    En fait ce que je n’aime pas dans les webs services c’est la génération de code. Surtout du code avec des URL, des QName et autres wsdls location en dur dedans. Les clients dynamiques de cxf m’intéressent donc pas mal, à voir s’il y a un cout important en terme de perfs. Ca serait pas mal aussi d’avoir des stubs dynamiques coté serveurs.

  9. 12/12/2009 à 16:47 | #9

    @Raphael,

    Je vous trouve sévère quand vous comparez WSDL à de la programmation en XML.
    Je dirais plutôt que, parmis les Interface Definition Languages (1), XSD est assez lourd et WSDL franchement désagréable même si c’est un peu moins pire avec un environnement de développement. Pour les langages de programmation en XML, je pense à BPEL et je vais alors être plus tranché que vous : j’ai une sainte horreur de ces languages :-) .

    Pour revenir à notre point initial, les défauts de WSDL et SOAP ne justifient pas pour moi de renoncer à l’approche Contract First quand on utilise XML.

    “SOAP est le pire des protocoles … à l’exception de tous les autres.” :-)

    OK, Google Protocol Buffer et Facebook Thrift sont beaucoup plus ‘hype’ mais je ne travaille pas ni chez Google ni chez Facebook ; je ne suis pas à Top Gun, je n’utilise pas des technologies d’exception, je fais juste de l’informatique de gestion … et j’aime ça parce que c’est chouette l’informatique de gestion :-) .

    Cyrille

    (1) http://en.wikipedia.org/wiki/Interface_definition_language

  10. hanane
    03/06/2013 à 15:37 | #10

    salut , merci beaucoup pour le tutoriel , pouvez vous me dire comment utiliser wsimport si le WSDL est protégé par une “Basic authentication”
    Merci pour toute suggestion

  11. Chennorris
    13/06/2016 à 15:09 | #11

    Bonjour et désolé par avance pour ma question si jamais elle vous paraît hors sujet mais…
    – quand je souhaite consommer un web service depuis javascript, j’appelle simplement une URL avec des paramètres.
    – quand je souhaite consommer un web service en Java, je ne comprends plus rien du tout à ce qu’il faut faire tant il y a de structures à déclarer et à gérer dans tous les sens. La solution de wsimport ne m’intéresse pas car je dois appeler un webservice dont l’URL varie au cours du temps (il y a un numéro de version dans l’URL) et je dois donc m’adapter de manière dynamique…

    Ma question est donc la suivante : dans mon cas, existe-t-il une manière simple de consommer un web service en Java ? (par “simple”, j’entends “appeler un web service en donnant une URL et des paramètres, rien de plus”).
    Merci d’avance pour vos éclaircissements.

  1. 06/05/2012 à 16:09 | #1