Servicios Web RESTful en Axis 2
En este tutorial vamos realizar una descripción de REST y vamos a ver un ejemplo práctico de un Servicio Web RESTful
¿Qué es REST?
REpresentational Estado Transfer (REST) es un método de diseño de arquitectura que consiste en ver un servicio Web como un recurso identificable mediante una URL.
¿Cuándo usar REST?
Un diseño REST puede ser apropiado cuando:
- Cuándo la funcionalidad expuesta por el servicio es síncrona.
- Cuándo el servicio Web no tiene estado.
- Cuándo la información que provee el servicio puede ser cacheada para mejorar el rendimiento.
- Cuándo se conoce bien el contexto de la comunicación (formato de datos, métodos, etc.) entre productor y el consumidor.
- Cuándo es importante que la comunicación sea ligera en terminos de bytes transmitidos debido al coste »» PDAs, móviles, etc
- Cuándo el consumidor tiene limitaciones de ancho de banda (PDAs, móviles, etc).
- Cuándo el consumidor desea acceder a los servicios (sin tener que instalar nada), a través de una página Web con Ajax y analizar el resultado (xml).
¿Qué son los Web Services RESTful?
Son aquellos servicios Web que funcionan bajo REST
Los Web Service REST proporcionan acceso a través de los métodos GET y POST de HTTP.
- GET: En accesos vía GET, tanto las operaciones como los parámetros se pasan por la URL » Sólo soporta argumentos con tipos simples.
- POST: En este tipo de acceso, la información no viaja en mensajes SOAP Envelope, sino directamente en el payload del mensaje.
REST en Axis2
Axis2 puede ser configurado para funcionar con REST, de manera que pueda enviar y recibir peticiones REST. (Por defecto está configuración esta habilitada)
Para habilitar REST, hay que añadir la siguiente línea en el archivo de configuración axis2.xml
.
1 |
<parameter name="enableREST" locked="false">true</parameter> |
Cuando un mensaje es recibido, entonces:
- Si el content type es text/xml y además NO está presente la cabecera SOAP Action » Mensaje REST.
- Si el content type es text/xml y además SI está presente la cabecera SOAP Action » Mensaje SOAP.
Instalación de Axis 2
Para instalar Axis 2, simplemente deberás
- Descargártelo desde http://ws.apache.org/axis2/
- Descomprimirlo en tu disco duro
- Crear una variable de entorno de nombre
AXIS_HOME
que apunte al directorio donde fue descargardo. Por ejemploc:/java/axis2-1.3
- Desplegar el archivo
%AXIS_HOME%/dist/axis2.war
en tu servidor de aplicaciones o contenedor de servlets favorito (JBoss, iPlanet, WebSphere, Weblogic, GlassFish, Geronimo, Tomcat, etc.)
A continuación veremos varias maneras de invocar uno de los servicios Web que vienen preinstalados en la distribución de Axis 2
Ejemplo: Invocación del servicio Web a través de HTTP GET
Abra su navegador favorito y ponga la siguiente dirección: http://127.0.0.1:8080/axis2/services/Version/getVersion
Ejemplo: Invocación del servicio Web a través de HTTP POST desde un formulario
1 2 3 4 5 6 7 |
<html> <body> <form name="n1" method="POST" action="http://127.0.0.1:8080/axis2/services/Version/getVersion"> <input type="submit" value="Invocar el Servicio Web"> </form> </body> </html> |
Ejemplo: Invocación del servicio Web a través de HTTP POST usando las clases de Axis
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package com.autentia.ws.rest.sample1; import org.apache.axiom.om.OMElement; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.ServiceClient; /** * Invocación via POST del Web service * @author Autentia. */ public class RESTClient { public static void main(String[] args) throws Exception { // Instanciamos el cliente ServiceClient cliente = new ServiceClient(); cliente.setTargetEPR(new EndpointReference("http://127.0.0.1:8080/axis2/services/Version/getVersion")); // Invocamos el servicio Web OMElement result = cliente.sendReceive(null); // Imprimimos el resultado por la salida estándar result.serialize(System.out); } } |
Ejemplo: Invocación del servicio Web a través de HTTP POST desde las clases estándares de Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
package com.autentia.ws.rest.sample1; import java.io.*; import java.net.URL; import java.net.HttpURLConnection; import java.net.URLEncoder; /** * Invocación via POST del Web service * @author Carlos García. Autentia. * @see http://www.mobiletest.es */ public class RESTClient2 { public static void main(String[] args) throws Exception { // URL del sercivio Web URL url = new URL("http://127.0.0.1:8080/axis2/services/Version/getVersion"); // Establecemos la conexión HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // Enviamos los datos asociados a la petición connection.setDoOutput(true); OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream()); wr.write(URLEncoder.encode("parametro1", "UTF-8") + "=" + URLEncoder.encode("valor1", "UTF-8")); wr.write("&"); wr.write(URLEncoder.encode("parametro2", "UTF-8") + "=" + URLEncoder.encode("valor2", "UTF-8")); wr.flush(); if (connection.getResponseCode() == HttpURLConnection.HTTP_OK){ // Leemos el contenido de la respuesta y lo mostramos por la salida estándar BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); String line = reader.readLine(); while (line != null) { System.out.println(line); line = reader.readLine(); } reader.close(); } else { System.out.println(connection.getResponseMessage()); } // Cerramos la conexión connection.disconnect(); } } |
Ejemplo: Invocación del servicio Web a través de HTTP POST usando HTTPClient
Puedes ver un tutorial de HTTPClient aquí
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
package com.autentia.ws.rest.sample1; import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.methods.*; import org.apache.commons.httpclient.params.HttpMethodParams; import java.io.*; /** * Invocación via POST del Web service usando HttpClient * @author Carlos García. Autentia. * @see http://www.mobiletest.es */ public class RESTClient3 { /** * Punto de inicio de ejecución del ejemplo. */ public static void main(String[] args) { HttpClient httpClient = null; // Objeto a través del cual realizamos las peticiones HttpMethodBase request = null; // Objeto para realizar las peticiones HTTP GET o POST int status = 0; // Código de la respuesta HTTP BufferedReader reader = null; // Se usa para leer la respuesta a la petición String line = null; // Se usa para leer cada una de las lineas de texto de la respuesta try { // Instanciamos el objeto httpClient = new HttpClient(); // Invocamos por POST request = new PostMethod("http://127.0.0.1:8080/axis2/services/Version/getVersion"); // Añadimos los parámetros que deseemos a la petición ((PostMethod) request).addParameter("parametro1", "valor1"); ((PostMethod) request).addParameter("parametro2", "valor2"); // Indicamos reintente 2 veces en caso de que haya errores. request.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(2, true)); // Añadimos las cabeceras personalizadas que se requieran, de la siguiente forma: request.addRequestHeader("HeadName", "HeadValue"); // Leemos el código de la respuesta HTTP que nos devuelve el servidor status = httpClient.executeMethod(request); // Vemos si la petición se ha realizado satisfactoriamente if (status != HttpStatus.SC_OK) { System.err.println("Error\t" + request.getStatusCode() + "\t" + request.getStatusText() + "\t" + request.getStatusLine()); } else { // Leemos el contenido de la respuesta y realizamos el tratamiento de la misma. // En nuestro caso, simplemente mostramos el resultado por la salida estándar reader = new BufferedReader(new InputStreamReader(request.getResponseBodyAsStream(), request.getResponseCharSet())); line = reader.readLine(); while (line != null) { System.out.println(line); line = reader.readLine(); } } } catch (Exception ex){ System.err.println("Error\t: " + ex.getMessage()); ex.printStackTrace(); } finally { // Liberamos la conexión. (También libera los stream asociados) request.releaseConnection(); } } } |
Cuando Axis recibe una petición REST, internamente la traduce, a SOAP, por ejemplo:
1 2 3 4 5 |
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <axis2:getVersion xmlns:axis2="http://ws.apache.org/goGetWithREST" /> </soapenv:Body> </soapenv:Envelope> |
Información que nos devuelve el Servicio Web en todos los caso
1 2 3 |
<ns:getVersionResponse xmlns:ns="http://axisversion.sample"> <ns:return>Hello I am Axis2 version service , My version is 1.3</ns:return> </ns:getVersionResponse> |
Conclusiones
Como podemos deducir de este tutorial, para hacer que un servicio Web sea RESTful es más un tema del motor de servicio Web (en este caso Axis) que del propio servicio.
Además también se puede deducir que el acceso a este tipo de servicios Web no tiene dependencias con contratos WSDL, clases especificas de comunicación, esquemas XML, etc. por lo que se hace más fácil y ligero su uso.
Un saludo, Carlos García.
Muy interesante el tutorial. Una pregunta, ¿cuál es la mejor forma de añadir seguridad a REST? ¿mediante HTTPS? ¿o hay algún otro mecanismo recomendado?