WebServices in Java : Apache XMLRPC

In questo articolo vediamo come utilizzare il progetto opensource Apache XMLRPC per realizzare dei webservices in Java in maniera semplice e veloce

Introduzione

Apache XMLRPC, precedentemente conosciuto come Helma XML-RPC, è l’implementazione Java di XML-RPC, un protocollo che permette di effettuare chiamate remote (RPC) effettuando delle richieste in XML su protocollo HTTP.
Questo progetto è stato pensato da una parte per implementare le specifiche di XMLRPC, quindi supportare tipologie predefinite di tipi dati, sia per essere utilizzato in modalità estesa rispetto all’XMLRPC
e fornire ulteriori tipologie di tipi trasferibili tra client e server. In questo articolo vedremo come gestire questa libreria per utilizzare entrambe le funzionalità

Server XMLRPC

Esistono diversi modi per utilizzare questa libreria lato server, come potete leggere nel seguente url

http://ws.apache.org/xmlrpc/server.html

In questo articolo noi utilizzeremo quello che potrebbe essere il comodo ed utile all’interno di un progetto web. Come prima cosa dobbiamo definire una classe Java che potremo richiamare remotamente. In questo caso andiamo a realizzare una semplice classe che restituisce i valori delle quotazioni di determinati indici di borsa (esempio classico nell’ambito di webservice quindi scusatemi per l’originalità)

package com.javastaff.xmlrpc;

public class StokeQuote {

    public double getQuote(String code) {
         double result = 0.0;
         if (code.equals("SUN")) {
            result = 20.0;
         } else if (code.equals("IBM")){
            result = 83.0;
         } else if (code.equals("BEA")) {
            result = 12;
         }
         return result;
    }
}

Questa classe, con il solo metodo getQuote, non fa altro che restituire determinati valori double in base agli indici di borsa che vengono passati come argomento. Vediamo ora come utilizzare questa classe attraverso un webservice XMLRPC, rendendola remota.

Configurazione

All’interno del nostro progetto web, dove andremo ad includere le librerie XMLRPC che vengono fornite da Apache, dovremo anche inserire alcune configurazioni prima di poter rendere “remota” la nostra classe StokeQuote. Prima di tutto dobbiamo dire alla libreria che abbiamo definito questa nuova classe, creando un file XmlRpcServlet.properties all’interno di un package org.apache.xmlrpc.webserver che andremo a creare all’interno del nostro progetto web.

Praticamente un semplice file di properties che deve essere posizionato in quel package nominato perchè la libreria XMLRPC lo leggerà e si renderà conto delle nuove definizioni che abbiamo nel nostro progetto. In questo file dobbiamo associare un nome univoco alla nostra classe, per poterla poi richiamare da remoto come potete vedere qui di seguito

StokeQuote=com.javastaff.xmlrpc.StokeQuote

Da remoto quindi il nostro oggetto sarà visibile come StokeQuote. Passiamo ora alla configurazione della nostra web application. Nel file web.xml della nostra applicazione server dobbiamo definire la Servlet che gestirà le chiamate XMLRPC utilizzando un determinato path. Dobbiamo quindi aggiungere le seguenti linee al file web.xml

<servlet>
        <servlet-name>XmlRpcServlet</servlet-name>
        <servlet-class>
           org.apache.xmlrpc.webserver.XmlRpcServlet
        </servlet-class>
        <init-param>
          <param-name>enabledForExtensions</param-name>
          <param-value>false</param-value>
          <description>
            enable extensions for XML-RPC.
          </description>
        </init-param>
</servlet>
<servlet-mapping>
        <servlet-name>XmlRpcServlet</servlet-name>
        <url-pattern>/xmlrpc</url-pattern>
</servlet-mapping>

Nel mapping che abbiamo riportato è stato specificato che non vogliamo supportare le estensioni al protocollo XMLRPC, ovvero la nostra applicazione supporta come valori di scambio tra client e server soltanto tipi primitivi e array/struct che utilizzano questi tipi. Per il momento utilizziamo questa specifica poi nella seconda parte dell’articolo utilizzeremo anche delle estensioni che ci permettono di trasferire veri e propri oggetti.

A questo punto la nostra applicazione server è pronta e ci rimane da sviluppare il client

Client XMLRPC

Il client che sviluppiamo in questo caso è una classica classe Java che possiamo far partire dalla console, ma chiaramente possiamo utilizzare il metodo che richiama il server in altri modi

package com.javastaff.xmlrpc;

import java.net.MalformedURLException;
import java.net.URL;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;

public class Client {
    public static void main(String a[]) throws Exception {
        XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
        config.setServerURL(new URL(
           "http://127.0.0.1:8080/TestXMLRPC/xmlrpc"));
        config.setEnabledForExtensions(false);
        XmlRpcClient client = new XmlRpcClient();
        client.setConfig(config);
        Object[] params = new Object[]{new String("IBM")};
        Double result = (Double) client.execute(
           "StokeQuote.getQuote", params);
        System.out.println("IBM: "+result);
    }

}

Vediamo cosa abbiamo fatto in questo client. Abbiamo creato un’istanza di XmlRpcClientConfigImpl e abbiamo settato il server XMLRPC che abbiamo precedentemente realizzato. Oltre a questo abbiamo specificato che non vogliamo utilizzare estensioni del protocollo XMLRPC con il metodo setEnabledForExtensions. Infine abbiamo creato un array di Object, che utilizziamo come parametro per la nostra chiamata remota e abbiamo utilizzato il metodo execute di XmlRpcClientConfigImpl, specificando l’oggetto e il metodo che vogliamo utilizzare e passando il parametro definito.
Il server XMLRPC a questo punto processa la nostra richiesta, la comprende, esegue il metodo della nostra classe StokeQuote e ritorna il risultato che noi vedremo scritto nella console

IBM: 83.0

Oggetti come parametri/valori di ritorno

Se non ci interessa molto pubblicare un webservice XMLRPC compliant, che può essere richiamato in molti altri linguaggi viste le tante librerie che implementano questo protocollo, possiamo anche realizzare un’applicazione che utilizzi le estensioni di questa libreria Java e che ci permetta di utilizzare oggetti Java che implementano l’interfaccia Serializableoggetti JAXB o nodi DOM.
Per abilitare le estensioni dobbiamo prima di tutto cambiare il web.xml mettendo a true il relativo tag

<param-name>enabledForExtensions</param-name>
<param-value>true</param-value>

Ora creiamo una semplice classe che ha due oggetti String, i relativi metodi get/set e che implementa l’interfaccia Serializable

package com.javastaff.xmlrpc;

import java.io.Serializable;

public class Dummy implements Serializable {

    private String stringa1;
    private String stringa2;

    public String getStringa1() {
        return stringa1;
    }

    public void setStringa1(String stringa1) {
        this.stringa1 = stringa1;
    }

    public String getStringa2() {
        return stringa2;
    }

    public void setStringa2(String stringa2) {
        this.stringa2 = stringa2;
    }

}

A questo punto definiamo una nuova classe “remota” che attraverso un suo metodo change scambia semplicemente le due variabili all’interno dell’oggetto Dummy

package com.javastaff.xmlrpc;

public class DummyWorker {

    public Dummy change(Dummy dummy) {
        String a=dummy.getStringa1();
        String b=dummy.getStringa2();
        dummy.setStringa1(b);
        dummy.setStringa2(a);
        return dummy;
    } 

}

Lato server ci rimane soltanto da aggiungere la definizione di questa nuova classe nel file di properties di XMLRPC

DummyWorker=com.javastaff.xmlrpc.DummyWorker

Client per l’estensione

Come nel caso precedente dobbiamo utilizzare XmlRpcClientConfigImpl, ma in questo caso settare a true le estensioni e gestire la classe Dummy mostrando prima e dopo cosa succede

package com.javastaff.xmlrpc;

import java.net.MalformedURLException;
import java.net.URL;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;

public class Client {

    public static void main(String a[]) throws Exception {
        XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
        config.setServerURL(new URL(
           "http://127.0.0.1:8080/TestXMLRPC/xmlrpc"));
        config.setEnabledForExtensions(true);
        XmlRpcClient client = new XmlRpcClient();
        client.setConfig(config);
        Dummy dummy=new Dummy();
        dummy.setStringa1("Prima stringa");
        dummy.setStringa2("Seconda stringa");
        System.out.println("Stringa 1: "+dummy.getStringa1());
        System.out.println("Stringa 2: "+dummy.getStringa2());
        Object[] params = new Object[]{dummy};
        Dummy newDummy=(Dummy) client.execute(
           "DummyWorker.change", params);
        System.out.println("Stringa 1 dopo: "+newDummy.getStringa1());
        System.out.println("Stringa 2 dopo: "+newDummy.getStringa2());
    }

}

Eseguendo il client l’output della nostra console sarà il seguente, dove possiamo vedere che il nostro oggetto è stato modificato e rispedito

Stringa 1: Prima stringa
Stringa 2: Seconda stringa
Stringa 1 dopo: Seconda stringa
Stringa 2 dopo: Prima stringa

Conclusioni

Apache XMLRPC è un progetto interessante che può trovare spazio in diversi progetti senza dover scomodare altri ingombranti framework/librerie e soprattutto permettendo di fornire un servizio che può essere sfruttato in molti altri linguaggi, essendo XMLRPC una specifica implementata un pò ovunque.

 

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.