Ejercicios de creación de Servicios Web

1. Vamos a ver como ejemplo la creación del servicio HolaMundo visto en la sesión anterior.

a) Vamos a crear el servicio utilizando como backend una clase Java. Este ejercicio se encuentra implementado a modo de ejemplo en el directorio hola dentro de los ejercicios de la sesión. Seguiremos los siguientes pasos:

javac utils/*.java
<target name="service">
  <servicegen
    destEar="sw_hola.ear"
    warName="sw_hola.war">
    <service
      javaClassComponents="utils.HolaMundo"
      targetNamespace="http://www.rvg.ua.es/ws"
      serviceName="Hola"
      serviceURI="/hola"
      generateTypes="True"
      expandMethods="True">
    </service>
  </servicegen>
</target>

De esta forma para acceder al servicio deberemos introducir la ruta "/hola" relativa al contexto donde despleguemos el servicio.

ant service

Con esto habremos generado el fichero EAR sw_hola.ear con el servicio.

http://localhost:7001/sw_hola/hola

b) Vamos a implementar ahora este mismo servicio utilizando un EJB como backend. En este caso podemos encontrar la implementación en el subdirectorio hola_ejb dentro del directorio de los ejercicios de la sesión. Seguiremos los siguientes pasos:

package utils;
   
   import java.rmi.RemoteException;
   import javax.ejb.CreateException;
   import javax.ejb.EJBHome;
   
   public interface HolaMundoHome extends EJBHome {
   
       HolaMundoHome create() throws CreateException, RemoteException;
   }
package utils;
   
   import java.rmi.RemoteException;
   import javax.ejb.EJBObject;
   
   public interface HolaMundo extends EJBObject {
   
       String saluda(String nombre) throws RemoteException;
   }
package utils;
   
   import javax.ejb.CreateException;
   import javax.ejb.SessionBean;
   import javax.ejb.SessionContext;
   import javax.naming.InitialContext;
   import javax.naming.NamingException;
   
   public class HolaMundoBean implements SessionBean {
   
     private SessionContext ctx;
   
     public void ejbActivate() { }
   
     public void ejbRemove() { }
   
     public void ejbPassivate() { }
   
     public void setSessionContext(SessionContext ctx) {
       this.ctx = ctx;
     }
   
     public void ejbCreate () throws CreateException { }
   
     public String saluda(String nombre) {
       return "Hola " + nombre;
     }
   }
<!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.
  //DTD Enterprise JavaBeans    2.0//EN' 
  'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>

  <!-- Generated XML! -->
   
   <ejb-jar>
     <enterprise-beans>
       <session>
         <ejb-name>HolaMundo</ejb-name>
         <home>utils.HolaMundoHome</home>
         <remote>utils.HolaMundo</remote>
         <ejb-class>utils.HolaMundoBean</ejb-class>
         <session-type>Stateless</session-type>
         <transaction-type>Container</transaction-type>
       </session>
     </enterprise-beans>
   
     <assembly-descriptor>
       <container-transaction>
         <method>
           <ejb-name>HolaMundo</ejb-name>
           <method-name>*</method-name>
         </method>
         <trans-attribute>NotSupported</trans-attribute>
       </container-transaction>
     </assembly-descriptor>
   
   </ejb-jar>
cd ejb
javac utils/*.java
cd ..
java weblogic.ejbc ejb hola_ejb.jar
<target name="service">
  <servicegen
    destEar="sw_hola_ejb.ear"
    warName="sw_hola_ejb.war">
    <service
      ejbJar="hola_ejb.jar"
      targetNamespace="http://www.rvg.ua.es/ws"
      serviceName="HolaMundo"
      serviceURI="/hola"
      generateTypes="True"
      expandMethods="True">
    </service>
  </servicegen>
</target>
ant service

Lo cual generará un fichero sw_hola_ejb.ear con la Aplicación Web donde tenemos nuestro servicio.

http://localhost:7001/sw_hola_ejb/hola
<target name="ejb">
  <javac srcdir="ejb" includes="utils/*.java" destdir="ejb"    />
  <java classname="weblogic.ejbc" fork="no">
    <arg line="-noexit ejb hola_ejb.jar" />
  </java>
</target>

De esta forma, podremos generar el fichero hola_ejb.jar que contiene el EJB de forma automática, introduciendo el comando:

ant ejb

 

2. Vamos a implementar un Servicio Web sencillo que realice la conversión de euros a ptas y de ptas a euros. Para ello proporcionaremos dos operaciones:

double ptas2euro(int ptas)
int euro2ptas(double euros)

El nombre del servicio en este caso será Conversion.

a) Implementar el servicio utilizando como backend una clase Java. Como ayuda puedes seguir los pasos del ejercicio anterior, cambiando los datos que sean necesarios. Vamos a desplegar el servicio en el contexto sw_conv, y la ruta para acceder a él será /conv. Una vez hayamos finalizado, deberemos poder ser capaces de acceder al servicio en la dirección:

http://localhost:7001/sw_conv/conv

b) Implementar el servicio utilizando como backend un EJB. Como ayuda puedes seguir los pasos del ejercicio anterior, cambiando los datos que sean necesarios. Vamos a desplegar el servicio en el contexto sw_conv_ejb, y la ruta para acceder a él será /conv. Una vez hayamos finalizado, deberemos poder ser capaces de acceder al servicio en la dirección:

http://localhost:7001/sw_conv_ejb/conv


3. Tienda de DVDs. Nuestro negocio consiste en una tienda que vende películas en DVD a través de Internet. Para dar una mayor difusión a nuestro catálogo de películas, decidimos implantar una serie de Servicios Web para acceder a información sobre las películas que vendemos.

De cada película ofreceremos información sobre su título, su director y su precio. Esta información podemos codificarla en una clase DatosPelicula como la siguiente:

public class DatosPelicula {
  public String titulo;
  public String director;
  public float precio;
   
  public DatosPelicula() {}
   
  public DatosPelicula(String titulo, String director, float precio) {
    this.titulo = titulo;
    this.director = director;
    this.precio = precio;
  }

  public String toString() {
return titulo + ", " + director + ", " + precio + " euros."; } }

Vamos a permitir que se busquen películas proporcionando el nombre de su director. Por lo tanto, el servicio ofrecerá una operación como la siguiente:

DatosPelicula [] buscaPorDirector(String director)

Proporcionaremos el nombre del director, y nos devolverá la lista de películas disponibles dirigidas por este director.

En un principio, podemos crear una lista estática de películas dentro del código de nuestro servicio, como por ejemplo:

DatosPelicula [] peliculas = { 
  new DatosPelicula("Mulholland Drive", "David Lynch", 26.96),    
  new DatosPelicula("Carretera perdida", "David Lynch", 18.95),    
  new DatosPelicula("Twin Peaks", "David Lynch", 46.95), 
  new DatosPelicula("Telefono rojo", "Stanley Kubrick", 15.95),    
  new DatosPelicula("Barry Lyndon", "Stanley Kubrick", 24.95),    
  new DatosPelicula("La naranja mecánica", "Stanley    Kubrick", 22.95)
}

Se pide:

a) Implementar el servicio utilizando como backend una clase Java.

Para construir una lista con las películas cuyo director coincida con el nombre del director que se ha solicitado, podemos utilizar un código similar al siguiente, donde se ha proporcionado un parámetro director:

director = director.toLowerCase();
   
ArrayList list = new ArrayList();
   
for(int i=0;i<peliculas.length;i++)    {
  if(peliculas[i].director.toLowerCase().indexOf(director)    != -1) {
    list.add(peliculas[i]);
  }
}
   
DatosPelicula [] result = new DatosPelicula[list.size()];
list.toArray(result);
   
return result;

En este caso ya no estamos utilizando tipos de datos soportados directamente por JAX-RPC, por lo que la tarea servicegen deberá crear los serializadores y deserializadores necesarios para la clase DatosPelicula.

Debemos de recordar que la clase DatosPelicula deberá tener un contructor void para que se puedan generar estos componentes.

Puede ocurrir que se obtenga un error de compilación mientras se genera el servicio. Si esto ocurre puede que sea necesario introducir el directorio donde tenemos nuestra aplicación en el CLASSPATH, para que pueda localizar las clases necesarias:

export CLASSPATH=$CLASSPATH:${dir.ejercicios}/ejercicios_2/tienda

b) Como tarea optativa, se puede crear una BD de películas, y leer las películas de la BD en lugar de tener una lista estática.

c) Como tarea avanzada, implementar el servicio mediante un EJB de sesión sin estado, y utilizar EJBs de entidad para acceder a los datos.