Wednesday, October 6, 2010

Creación de ws con JAXWS

Estoy maravillado por lo fácil que es crear un WS en java, nada de AXIS2 ni cosas por el estilo. Con JAXWS es casi trivial.

Te creas un interface, siempre viene bien definir un contrat, aunque no es necesario.

public interface ILeerSensor {
   public abstract int dameLaTemperatura(String nombreDelSensor) throws SensorError;

}

Implementas el servicio


import javax.jws.WebParam;
import javax.jws.WebService;



@WebService
public class LeerSensorImpl implements ILeerSensor {

    public int dameLaTemperatura(@WebParam(name="nombreDelSensor") String nombreDelSensor) throws SensorError{
      
       return Sensor.find(nombreDelSensor).getTemperatura();


    }
}


creamos el WS
ejecutas esta simple instrucción:
wsgen -cp src\main\java;target\classes  -d target/web-classes -verbose -r src\main\webapp\WEB-INF\wsdl -wsdl pais.compania.proyecto.server.ws.LeerSensorImpl

Con esto se genera la estructura para generar un WS. Luego hay que empaquetarlo en un war para publicarlo en el servidor Tomcat o JBoss.

creamos el cliente

wsimport -p pais.compania.proyecto.cliente.ws -s src\main\java -d target\classes http://ip:port/nombreDelWar/LeerSensorImpl?wsdl

Nos genera unas clases por cada servicio. Y solamente hay que usarlo.


Problemas que me he encontrado:

Problema:
Si generas varios WS con nombre de objetos reutilizados, estos objetos no son los mismos. Es decir, la clase SensorError, si se usa en varios WS, genera tantas clases como WS (no metodos) implementes. No se como usar solo uno, ya que uso distintos paquetes y da error de "cast". Además si quieres pasar como parámetro a un WS una clase que te ha devuelto otro WS tienes que convertir a mano estos objetos que a priori son iguales.

Solución: Hacer un Wrapper para cada tipo de objeto.


Problema:
Si al crear una interfaz pones como valor de retorno un objeto List,  y luego en la signatura de la implementación devuelves un ArrayList, que implementa un List, todo funciona menos al generarte el cliente que consume el servicio.

Solución:
Poner tal cual la implementacion del interfaz, es decir si decimos que devolvemos un List en la interfacedevolver un List en la signatura de la implementación.


Problema:
Al generar los WS y los clientes, se pierden los nombres de los parametros en los métodos del WS.
Solución
Hay que poner explicitamente  @WebParam(name="nombreDelSensor") si quieres que te salga en eclipse el nombre del parámetro.







2 comments: