Java Web Service

Un Web service permet de découpler la gestion des données du visuel. Un web service permettant la communication et l’échange de données entre applications et systèmes hétérogènes dans des environnements distribués Le principe de base est assez simple: un client “questionne” un web service hébergé sur un serveur via le protocole http, il obtient alors une réponse. Le réponse est de nature XML et peut représenter des objets.

Le protocole de communication est défini dans le cadre de la norme SOAP dans la signature du service exposé (WSDL). Actuellement, le protocole de transport est essentiellement HTTP(S).

Note

il est possible de faire des webs services avec d’autres technologies que java, ... python par exemple (aussi bien côté client que serveurs)

Serveur

Pour pouvoir utiliser un web service il faut l’héberger. Pour cela nous allons devoir installer

  • un serveur applicatif Java EE: Tomcat
  • une application permettant le développement de services web: Axis

Les deux projets sont hébergés par la fondation Apache Software.

Nous partons sur un serveur Debian fraichement installé.

L’objectif est d’installer la dernière version de chaque outil ... sinon un simple apt suffit

apt-get install tomcat8

Installation de Java

Note

on installe la version oracle de java mais il existe aussi une version open-source

apt-get install openjdk-7-jre openjdk-7-jdk
java -version
javac -version

Le principe est de télecharger via le site d’oracle le jdk (ou le jre), de l’installer puis d’indiquer au système que nous souhaitons utiliser de façon préférentielle cette machine virtuelle

su - root
wget --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u5-b13/jdk-8u5-linux-x64.tar.gz
mkdir /opt/jdk
tar -zxf jdk-8u5-linux-x64.tar.gz
mv jdk1.8.0_05 /opt/
ln -s /opt/jdk1.8.0_05 /opt/jdk
ls /opt/jdk
update-alternatives --install /usr/bin/java java /opt/jdk/bin/java 2000
update-alternatives --install /usr/bin/javac javac /opt/jdk/bin/javac 2000
update-alternatives --display java
update-alternatives --display javac
java -version

Note

dans update-alternatives on sélectionne une version d’outil par sa priorité içi 2000 (mais on aurait put mettre autre chose)

Installation de Tomcat

Le principe reste simple:

  • on récupère les sources
  • on installe les sources
  • on paramètre
  • on lance
su - root
cd /opt
wget http://mirrors.ircam.fr/pub/apache/tomcat/tomcat-8/v8.0.20/bin/apache-tomcat-8.0.20.tar.gz
tar -xvf apache-tomcat-8.0.20.tar.gz
ln -s apache-tomcat-8.0.20 tomcat
rm apache-tomcat-8.0.20.tar.gz

Pour paramétrer le port de l’interface d’administration web de tomcat, il faut éditer /opt/tomcat/conf/server.xml (par défaut 8080)

Pour créer un utilisateur tomcat il faut éditer /opt/tomcat/conf/tomcat-user.xml et ajouter dans la balise racine

<role rolename="tomcat"/>
<role rolename="manager"/>
<role rolename="manager-gui"/>
<role rolename="admin-gui"/>
<user username="admin" password="tomcat" roles="manager,manager-gui,admin-gui"/>

On peut maintenant démarrer et arrêter tomcat

/opt/tomcat/bin/startup.sh
/opt/tomcat/bin/shutdown.sh

une fois démarrer on peut avoir accès à la console d’administration via l’url http://127.0.0.1:8080

Si on a des soucis de lenteurs par faute de mémoire il faut modifier la variable JAVA_OPTS contenu dans le fichier /opt/tomcat/bin/startup.sh

export JAVA_OPTS="-server -Xms2048 -Xmx4096"

Il est possible d’intégrer Tomcat comme un service en éditant le fichier /etc/init.d/tomcat

#!/bin/sh
CATALINA_HOME=/opt/tomcat; export CATALINA_HOME
JAVA_HOME=/opt/java; export JAVA_HOME
TOMCAT_OWNER=root; export TOMCAT_OWNER

start() {
    echo -n « Starting Tomcat:  »
    su $TOMCAT_OWNER -c $CATALINA_HOME/bin/startup.sh
    sleep 2
}
stop() {
    echo -n « Stopping Tomcat:  »
    su $TOMCAT_OWNER -c $CATALINA_HOME/bin/shutdown.sh
}

# See how we were called.
case « $1″ in
    start)
        start
    ;;
    stop)
        stop
    ;;
    restart)
        stop
        start
    ;;
*)
    echo $ »Usage: tomcat {start|stop|restart} »
    exit
esac

Apache et Tomcat

Note

cette installation n’est pas obligatoire

Il est possible d’utiliser le moteur http d’Apache au lieu du moteur de Tomcat. Pourquoi? car pour de grosse infrastructure Apache est plus robuste.

apt-get install apache apache2-mpm-prefork libapache2-mod-jk

On edite le module jk /etc/apache2/mods-available/jk.load afin d’ajouter quelques paramètres

LoadModule jk_module /usr/lib/apache2/modules/mod_jk.so

JkWorkersFile /etc/apache2/workers.properties
JkLogFile /var/log/apache2/mod_jk.log
JkLogLevel debug
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "

Dans le fichier de configuration Apache de notre site on rajoute les directives JKMount avec context1 et contextB correspondant aux application web déployées sur notre tomcat

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/
    ...
    JkMount /contextA/* worker1
    JkMount /contextB/jsps/*.jsp worker1
</VirtualHost>

/*

Au niveau de tomcat on active le connecteur ajp dans le fichier server.xml

<Connector port= »8009″ address= »127.0.0.1″ enableLookups= »false » redirectPort= »8443″ protocol= »AJP/1.3″ />

On génère un fichier etc/apache2/workers.properties

workers.tomcat_home=/opt/tomcat
workers.java_home=/opt/java
ps=/
worker.list=worker1
worker.worker1.port=8009
worker.worker1.host=localhost
worker.worker1.type=ajp13
worker.worker1.lbfactor=1

On peut redémarrer apache

/etc/init.d/apache2 restart

On a maintenant accès à nos serveur tomcat via le port apache 80

Installation de Axis

Note

Axis peut être lancer de façon indépendante comme un serveur. Mais les performances sont meilleurs en tant que webapp d’un serveur d’application. Donc nous utiliserons la version war et non Binary Distribution

Le principe général est

  • on récupère axis
  • on l’installe
  • on l’intègre comme webapp dans tomcat
  • on valide l’intégration
cd /tmp
wget http://archive.apache.org/dist/axis/axis2/java/core/1.6.1/axis2-1.6.2-war.zip
unzip axis2.1.6.1-war.zip
cp axis2.war /opt/tomcat/webapps
/opt/tomcat/bin/shutdown.sh
/opt/tomcat/bin/startup.sh

On a maintenant accès à l’interface http://127.0.0.1:8080/axis2. On peut via cette interface valider notre système.

Note

le premier accès à l’interface génère un dossier /opt/tomcat/webapps/axis2.

Dans une utilisation plus approfondie des web services il faudra peut être rajouter des librairies dans /opt/tomcat/webapps/axis2/WEB-INF/lib. Certaine de ces librairies sont accessibles via la Binary Distribution de Axis.

L’interface d’Axis2 donne accès à la liste des services disponibles (et à leurs définitions WSDL) mais aussi à une interface d’administration. Cette dernière réclame une authentification qu’on gère au niveau du fichier /opt/tomcat/webapps/axis2/axis2.xml (par défaut le user est admin, password axis2).

Programmation et déploiement du Web Service

Nous allons développer un web service. Nous allons d’abord créer un workspace qui le permet

root
 +--- workspace
        +--- tmp
        +--- service
                +--- myws
                      +--- test
                            +--- MyTest.java

Ce qui s’obtient ainsi

mkdir -p /root/workspace/tmp
mkdir -p /root/workspace/service/myws/test

On édite notre service mytest.java

package service.myws.test;

public class MyTest {

    public String echo(String value) {
        return value;
    }
 }

On compile notre service

cd /root/workspace
javac -d tmp/ service/myws/test/MyTest.java

On a donc maintenant dans tmp notre classe compilée.

On ajoute un fichier xml permet de décrire notre service

cd /root/workspace
mkdir -p tmp/META-INF
vi tmp/META-INF/services.xml
<service>
    <parameter name="ServiceClass"
            locked="false">service.myws.test.MyTest</parameter>

    <operation name="echo">
        <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
    </operation>
</service>

On génère une archive pour la déployer en tant que service

cd /root/workspace
jar -cvf MyTest.aar -C tmp/ .

Note

il faut noter que l’archive se nomme aar et non jar comme d’habitude

On peut maintenant déployer notre archive. Ce déployement peut être réalisé via l’interface web dans la partie administration upload de service. Cette interface est complète et permet notament d’activer ou de désactiver un service.

En ligne de commande le déployement consiste à copier notre archive dans le dossier services de l’application axis2 de tomcat

cp /root/workspace/MyTest.aar /opt/tomcat/webapps/axis2/WEB-INF/services

Client

Pour créer un client il faut un serveur ... sur lequel on a accès à la définition du service qu’on souhaite appeler.

Dans notre cas on a accès à cetté définition via l’url http://127.0.0.1:8080/axis2/services/MyTest?wsdl.

Axis possède un script qui permet à partir d’une définition wsdl de générer des classes pour avoir accès à ce service

cd /root/workspace
java -Djava.ext.dirs=/opt/tomcat/webapps/axis2/WEB-INF/lib org.apache.axis2.wsdl.WSDL2Java -uri http://127.0.0.1:8080/axis2/services/MyTest?wsdl

On retrouve ainsi dans /root/workspace/src/service/myws/test deux classes:

  • MyTestCallbackHandler.java
  • MyTestStub.java

qui permettent l’accès au service.

On va créer un fichier Client.java dans /root/workspace/src/service/myws/test

ackage service.myws.test;

import service.myws.test.MyTestStub.EchoResponse;

public class Client {

    public static void main(String[] args) throws Exception {

        MyTestStub stub = new MyTestStub();

        //Create the request
        MyTestStub.Echo request = new MyTestStub.Echo();
        request.setArgs0("Hello world");

        //Invoke the service
        EchoResponse response = stub.echo(request);
        System.out.println("Response : " + response.get_return());
    }
}

On peut maintenant compiler cette classe

mkdir -p /root/workspace/tmp
cd /root/workspace/src
javac -Djava.ext.dirs=/opt/tomcat/webapps/axis2/WEB-INF/lib service/myws/test/*.java -d ../tmp/

/* Et maintenant on utilise notre classe

cd /root/workspace/tmp
java -Djava.ext.dirs=/opt/tomcat/webapps/axis2/WEB-INF/lib service/myws/test/Client

Note

il faut noter qu’on utilise la librairie axis2 même pour le client

On peut aussi écrire un client python

import SOAPpy
client = SOAPpy.SOAPProxy("http://localhost:8080/axis2/services/MyTest", namespace="http://test.myws.service")
print client.echo("coucou")

Note

la notion de namespace est obtenu via le wsdl, et le nom de la méthode via l’operation des binding SOAP

Note

pour voir les messages SOAP échangés il faut activer les logs dans notre client python

client.config.debug = 1

Par défaut sur un serveur tomcat avec une webapps Axis il existe un service Version qui permet d’avoir la version d’Axis. Et bien on peut obtenir cette information via:

import SOAPpy
client = SOAPpy.SOAPProxy("http://localhost:8080/axis2/services/Version", namespace="http://axisversion.sample")
print client.getVersion()

Vive l’interportabilité