martedì 1 novembre 2011

Java Web Services su Tomcat

Di seguito un esempio di WS deployato su tomcat ed invocato da client Java.
Per effettuare il deploy su Tomcat per prima cosa ho dovuto scaricare da qui l'ultima versione di JAX/WS.
Una volta scompattato lo zip ho messo tutti i jar dentro la directory lib di Tomcat 7.
Ho quindi creato un progetto Web da Eclipse.
Ho definito quindi la seguente interfaccia:

package it.ws;
import java.math.BigInteger;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.jws.soap.SOAPBinding.Use;
@WebService
@SOAPBinding(style=Style.DOCUMENT,use=Use.LITERAL)
public interface FattorialeInt {
public BigInteger getFattoriale(long n);
}

Implementata dalla seguente classe:

package it.ws;
import java.math.BigInteger;
import javax.jws.WebService;
@WebService(endpointInterface="it.ws.FattorialeInt")
public class FattorialeImpl implements FattorialeInt {

    @Override
    public BigInteger getFattoriale(long n) {
        BigInteger fatt=new BigInteger("1");
        for(long i=1;i<=n;i++){
            fatt=fatt.multiply(new BigInteger(String.valueOf(i)));
        }
        return fatt;
    }
   

}

A questo punto, poichè lo style di binding è DOCUMENT e non RPC ho dovuto lanciare dalla console il comando wsgen per generarmi gli artefatti software necessari.
Quindi dalla directory dove sono i .class (quindi in build/class/it/ws, proprio a livello dei file .class)  ho digitato il seguente comando:

wsgen -keep -cp . it.ws.FattorialeImpl

In questo modo sono state generate le seguenti classi
1) GetFattoriale.java
2) GetFattorialeResponse.java

Codice 1

package it.ws.jaxws;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "getFattoriale", namespace = "http://ws.it/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getFattoriale", namespace = "http://ws.it/")
public class GetFattoriale {

    @XmlElement(name = "arg0", namespace = "")
    private long arg0;

    /**
     *
     * @return
     *     returns long
     */
    public long getArg0() {
        return this.arg0;
    }

    /**
     *
     * @param arg0
     *     the value for the arg0 property
     */
    public void setArg0(long arg0) {
        this.arg0 = arg0;
    }

}
Codice 2
package it.ws.jaxws;
import java.math.BigInteger;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlRootElement(name = "getFattorialeResponse", namespace = "http://ws.it/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getFattorialeResponse", namespace = "http://ws.it/")
public class GetFattorialeResponse {

    @XmlElement(name = "return", namespace = "")
    private BigInteger _return;

    /**
     *
     * @return
     *     returns BigInteger
     */
    public BigInteger getReturn() {
        return this._return;
    }

    /**
     *
     * @param _return
     *     the value for the _return property
     */
    public void setReturn(BigInteger _return) {
        this._return = _return;
    }

}

A questo punto bisogna effettuare delle configurazioni sul file Web Xml, in particolare bisogna dichiarare

1) la servlet com.sun.xml.ws.transport.http.servlet.WSServlet ;
2) il Listener com.sun.xml.ws.transport.http.servlet.WSServletContextListener

NOTA: per questo serve copiare quei jar dentro la lib di Tomcat
Quindi nel web.xml avremo:

 <servlet>
    <description></description>
    <display-name>WsTest</display-name>
    <servlet-name>FattConvert</servlet-name>
    <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>FattConvert</servlet-name>
    <url-pattern>/FattConvert</url-pattern>
  </servlet-mapping>
  <listener>
  <listener-class>
  com.sun.xml.ws.transport.http.servlet.WSServletContextListener
  </listener-class>
  </listener>

Il listener dichiarato ha bisogno del seguente file xml sun-jaxws.xml dove è dichiarato l'endpoint:

<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
<endpoint name="FattConvert" implementation="it.ws.FattorialeImpl" url-pattern="/FattConvert"/>
</endpoints>

Notare che bisogna fare in modo che nell'endpoint il name sia uguale al servlet name, l'implementation sia la classe del web service e l'url-pattern sia l'url-pattern della servlet.

Una volta effettuato il deploy il WS è richiamabile al seguente url:

http://localhost:8080/TestWs/FattConvert?wsdl

Per richiamare il Web Service è possibile come sempre generare un client tramite l'utility wsimport (già analizzato in un precedente POST).








Nessun commento:

Posta un commento