Mostrando entradas con la etiqueta xsd. Mostrar todas las entradas
Mostrando entradas con la etiqueta xsd. Mostrar todas las entradas

viernes, 31 de mayo de 2013

Introducción a los servicios web

La primera vez que un programador se enfrenta a la tarea de tener que realizar un servicio web (en adelante WS, Web Service) se suele encontrar un poco perdido. Normalmente se recurre a internet o a algún libro especializado. El problema es que son tantas las tecnologías con las que se puede desarrollar un WS, y son tantos los tipos de WS que existen, protocolos y demás, que a no ser que alguien ayude pueden pasar horas hasta que el programador obtenga el resultado deseado.

En mi caso he desarrollado muchos WS en distintos lenguajes como java, python y php; y distintas tecnologías, como XMLRPC, SOAP, MAVEN, AXIS, AXIS2… y os comento que me he encontrado con muchos problemas, siendo algunos de ellos de solución muy compleja.

Desde hace un tiempo sigo mi propia metodología para realizar WS. En realidad lo que os voy a contar no es de mi propia cosecha, sino que fue una gran aportación de un amigo (JT). Evidentemente yo hice mis cambios y lo adapté a mi forma de trabajar, pero sirvan estos posts como agradecimiento.

Durante cuatro posts, este inclusive, voy a contar lo que es un WS. No voy a hacer como muchos libros que profundizan tanto en los detalles que no se sabe por donde cogerlos, sino que voy a ir al grano. La estructura a seguir será la siguiente:

  • En este primer post, daré una explicación light de lo que es un WS y comentaré el ejemplo que realizaré.
  • En el segundo post programaré una aplicación “productor”.
  • El tercer post será un ejemplo de manejo de la interfaz de eclipse para obtener datos del “productor”.
  • El cuarto y último post lo usaré para crear un “cliente” y una aplicación que use dicho “cliente”.

Así pues, que comience el espectáculo:

¿Qué es un Web Service?

Para responder a esta pregunta, me remito a la descripción dada en la Wikipedia: Un servicio web (en inglés, Web services) es una tecnología que utiliza un conjunto de protocolos y estándares que sirven para intercambiar datos entre aplicaciones. Distintas aplicaciones de software desarrolladas en lenguajes de programación diferentes, y ejecutadas sobre cualquier plataforma, pueden utilizar los servicios web para intercambiar datos en redes de ordenadores como Internet. La interoperabilidad se consigue mediante la adopción de estándares abiertos. Las organizaciones OASIS y W3C son los comités responsables de la arquitectura y reglamentación de los servicios Web. Para mejorar la interoperabilidad entre distintas implementaciones de servicios Web se ha creado el organismo WS-I, encargado de desarrollar diversos perfiles para definir de manera más exhaustiva estos estándares. Es una máquina que atiende las peticiones de los clientes web y les envía los recursos solicitados.

¿Y esto que significa?

Imaginemos la siguiente situación: Tenemos una aplicación (llamada A) que almacena datos de películas. Dicha aplicación sólo está accesible vía web, y queremos que otra aplicación distinta (llamémosla B) muestre los datos de la aplicación A. En este ejemplo la aplicación A se llama productor, ya que produce los datos, y la aplicación B se llama consumidor o cliente.

Para que la aplicación A pueda compartir los datos, es necesario que publique un archivo de descripción del servicio. Dicho archivo debe estar bien formado y contiene una descripción de los métodos que acepta el WS, y de los datos que utiliza tanto si son de llamada como de retorno. Además si dichos datos son clases propias de la aplicación, también deben estar descritas en el archivo. A dicho archivo se le denomina WSDL (Web Services Description Language). En realidad esto es una verdad a medias, puesto que los tipos de datos no son necesarios que estén. Lo que pasa es que si el WSDL está completo el cliente se puede generar de forma automática, ya sea con maven, con eclipse o con cualquier otra aplicación que lo permita. Si no lo estuviera es requisito indispensable que el programador que va a realizar el cliente conozca a la perfección los tipos de datos, etc.

Como podéis imaginar realizar este archivo a mano resulta una tarea tediosa, ya que cualquier error en el mismo hace que no funcione, y para colmo estos errores son difíciles de localizar. Ahora pensad, si hacer un simple xsd es complicado, imaginad un super xsd, es decir, un WSDL.

Sigamos con la teoría. Tenemos una aplicación productora que además de producir datos, publica un archivo que describe que operaciones se pueden realizar con ella. Pues lo que nos quedaría sería leer dicho archivo, y generar una aplicación que sea capaz de usar los métodos y los datos definidos en el WSDL. La aplicación productora a su vez publica una url a la que conectaremos el cliente, y así las dos aplicaciones se comunicarán y pasarán información entre ellas.


Diagrama de funcionamiento de un WS

En resumen:

El productor publica un archivo WSDL que describe como interactuar con él, y además dispone de una url para poder realizar dicha interacción.

El cliente interactúa con el productor y muestra los datos en su aplicación. El WSDL sirve para generar las clases y llamadas a métodos que usará el cliente.

En el próximo post realizaremos una aplicación que será el productor del WS.

Saludos.

sábado, 4 de mayo de 2013

Escritura de archivos XML con JAXB

En un post anterior presenté el proceso que hay que seguir para leer archivos XML usando JAXB. En dicho post generé las clases necesarias y las usé de ejemplo.

Para cerrar el círculo adecuadamente, usando el mismo ejemplo, presento ahora una clase que permite escribir un archivo XML en disco.


import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import org.example.personas.Persona;
import org.example.personas.Personas;


public class SaveXMLwithJAXB {

 public static void main(String[] args) {

  JAXBContext ctx;
  
  Personas p = new Personas();
  Persona pItem = new Persona();
  pItem.setCiudad("Madrid");
  pItem.setEdad("20");
  pItem.setId("1");
  pItem.setNombre("Carlos");
  
  p.getPersona().add(pItem);
  
  try {
   ctx = JAXBContext.newInstance(Personas.class);
   Marshaller m = ctx.createMarshaller();
   
   File f = new File("C:/destino.xml");
   m.marshal(p, f);
   
  } catch (JAXBException e) {
   e.printStackTrace();
  }  
 }
}


Saludos.

martes, 26 de marzo de 2013

Lectura de archivos XML en Java. Uso de JaxB.

En mi anterior post sobre Groovy realicé un ejemplo que leía un archivo xml. En este post voy a leer casi el mismo archivo xml usando JAXB.

Archivo personas.xml (modificado), la diferencia es que a la etiqueta persona le voy a añadir un namespace, quedando el archivo así:


 

  
   1
   Carlos G. González
   Sin ley
   
  
  
   2
   M. Rajoy
   
   Mamoncete
  
  
   3
   ZP
   
   Engañabobos
  


JAXB son las siglas de Java API for XML Binding. Con JAXB podemos serializar objetos java y archivos xml. ¿Y esto qué significa? Pues que podemos tener una clase java con atributos y relacionar esa clase con un archivo xml. También podemos cargar los valores del archivo xml en dicha clase, con lo cual facilitamos mucho la lectura del mismo. En realidad la unión de la clase java no se va a realizar con el archivo xml que contiene los datos que queremos leer, sino con el archivo de definición del mismo, es decir, con el XSD (XML Schema Definition).

Ejecutando xjc

Como personas.xml fue un ejemplo creado a mano para el post mencionado, no tengo su archivo xsd. Eclipse permite crear este tipo de archivos de forma rápida, autocompletando, etc. Tras un par de minutos mi xsd quedaría:







 
  
 



 
  
  
  
  
 
 




Aunque yo para este ejemplo he picado el xsd a mano, existen herramientas que lo pueden generar a partir de clases java (eclipse) o de archivos xml (Microsoft tiene una que mola mucho). El libro Profesional Java JDK 6 de Anaya multimedia dedica varias páginas a este tema, por lo que lo recomiendo si alguien quiere profundizar más.

Ahora lo que vamos a hacer es crear las clases java asociadas al xsd. Hasta la versión 5 del jdk había que bajarse el paquete JWSDP, el cual contenía el ejecutable que nos hace falta para esta tarea. A partir de la versión 6 del jdk, dicho paquete se incluyó en el jdk, por lo que ya no es necesario bajarse nada independiente.

El ejecutable xjc es el que nos permite generar las clases a partir del archivo xsd. La opción –d permite indicar el directorio en el que queremos generar las clases, en mi caso “.\src “. El otro directorio escrito es la ruta hacia el archivo xsd.

En mi caso la sentencia es:

c:\Java(x86)\jdk1.6.0_21\bin\xjc.exe -d .\src src\xml\Personas.xsd

Existen otros parámetros para indicar el nombre de los paquetes a generar… pero no los he usado para no complicar el ejemplo.

Tras ejecutar la sentencia, en el paquete org.example.personas he obtenido cuatro clases:

  • ObjectFactory.java
  • package-info.java
  • Persona.java
  • Personas.java

Aún falta un paso para que la unión entre el xsd y las clases esté finalizada, y es que a veces el elemento raíz del xsd no queda marcado en las clases java. En mi caso hay que añadir la anotación @XmlRootElement a la clase Personas.java, quedando así:

@XmlRootElement (name="personas")
public class Personas {…}

El problema parece estar relacionado con información incompleta en los xsd o en los xml. Si se quiere obtener más información sobre este problema, en los siguientes links comentan la jugada:

Enlace a magicmonster.com.

Enlace a weblogs.java.net.

Usando las clases obtenidas

La siguiente clase es muy sencilla y muestra como se realizaría la lectura del xml:

import java.io.FileInputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

import org.example.personas.Persona;
import org.example.personas.Personas;


public class ReadXMLwithJAXB {

 public static void main(String[] args) {

  JAXBContext ctx;
  try {
   ctx = JAXBContext.newInstance(Personas.class);
   Unmarshaller u = ctx.createUnmarshaller();
   
   Personas root = (Personas) u.unmarshal(new FileInputStream("C:/Users/Carlos/workspace/ReadXML/src/xml/personas.xml"));
   for(Persona p:root.getPersona()){
    System.out.println(p.getNombre());
   }
   
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

El resultado obtenido es:

Carlos G. González
M. Rajoy
ZP

Y una vez montado todo este tinglado, sinceramente, ¿no mola mucho más Groovy?

Saludos.

domingo, 3 de febrero de 2013

Configurando un nuevo catálogo (XSD) en eclipse

Al crear nuevos contenidos estructurados de opencms desde eclipse, los tipos propios de OpenCms son subrayados en rojo. Para que eclipse conozca esos tipos de contenidos, simplemente hay qe configurar un nuevo catálogo de datos XML con las definiciones de los mismos.

¿Y dónde obtenemos el catálogo de tipos? El propio Alexander Kandzior nos daba la solución en la lista de correos de OpenCms.

org.opencms.xml.CmsXmlEntityResolver resolver = new org.opencms.xml.CmsXmlEntityResolver(null); 
org.xml.sax.InputSource source = resolver.resolveEntity(null,org.opencms.xml.CmsXmlContentDefinition.XSD_INCLUDE_OPENCMS); 
byte[] bytes = org.opencms.util.CmsFileUtil.readFully(source.getByteStream()); 
String string = org.opencms.i18n.CmsEncoder.createString(bytes,"UTF-8"); 
System.out.println(string); 

Una vez obtenido el fichero opencms-xmlcontent.xsd simplemente hay que darlo de alta en eclipse, en XML\XML Catalog.

Captura de Catálogo XML en eclipse con valores de configuración.

Saludos.

Related Posts Plugin for WordPress, Blogger...