M4-UF1 FRAMEWORK SPRING

UNIDAD 11: Servicios Web

eugeniaperez.es

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

 

Un servicio web constituye un método que es accedido a través de la red. Es decir, se puede acceder a él de manera remota desde otra máquina que tenga conectividad con la máquina que aloja el servicio.

El término API sirve para identificar una serie de servicios web disponibles y relacionados entre sí. Ejemplos son Google Maps, ebay, Amazon, etc.

 

¡Reutilización de código!

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

 

Por lo tanto una API representa un catálogo de métodos públicos que podemos utilizar desde nuestras aplicaciones.  

Quiero desarrollar una web de "música" que presente información extraída de diversas APIs que me proporcionan información para tal propósito:

http://www.lastfm.es/api

http://www.lastfm.es/api/rest

 

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

 

Las dos maneras fundamentales de implementar servicios web independientemente de la tecnología son:

  • SOAP: forma tradicional. Basada en ficheros XML. Más lento parseo entre el cliente/servidor. Mayor complejidad
  • REST: basado en las APIs Restful. Método más sencillo que aprovecha la potencia del objeto HTTP. Basado en JSON.

 

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

SOAP es un protocolo estándar que define cómo diferentes procesos pueden comunicarse por medio de

intercambio de datos XML.

Un mensaje SOAP es un documento XML ordinario con una estructura definida en la especificación del protocolo.

Al utilizar XML el parseo es más costoso y la comunicación entre cliente y servidor más lenta.

 

 

 

 

 

 

 

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

Veamos un ejemplo de cómo crear servicios Web SOAP en Spring. Para ello, descárgate el proyecto y carga complete:

https://github.com/spring-guides/gs-producing-web-service.git

  • Dependencias (org.springframework.boot y wsdl4j)
  • Esquema XSD, en src/main/resources, que va a definir el tipo de datos de nuestras peticiones y respuestas
  • Maven generate-sources ...

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

El XSD de countries define objetos con sus atributos del WS:

 <xs:element name="getCountryRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="name" type="xs:string"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

Las peticiones (request) que consistirán en un objeto con un atributo nombre de tipo String.

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

La response devuelve un Country, que es un objeto complejo:

 <xs:element name="getCountryResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="country" type="tns:country"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="country">
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
            <xs:element name="population" type="xs:int"/>
            <xs:element name="capital" type="xs:string"/>
            <xs:element name="currency" type="tns:currency"/>
        </xs:sequence>
    </xs:complexType>

    <xs:simpleType name="currency">
        <xs:restriction base="xs:string">
            <xs:enumeration value="GBP"/>
            <xs:enumeration value="EUR"/>
            <xs:enumeration value="PLN"/>
        </xs:restriction>
    </xs:simpleType>

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

Dentro del pom.xml:

 

 

 

 

Genera unas clases Java a partir de los XSD (En nuestro caso src/main/resources/countries.xsd)

<executions>
	<execution>
		<id>xjc</id>
		<goals>
		<goal>xjc</goal>
		</goals>
	</execution>
</executions>

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

Desde el proyecto: Run As -> Maven generate-sources







Se generan las anteriores clases...

Varios countries para enviar la respuesta (datos consulta)

Define el servicio web

Lanza el servicio

Genera el WSDL que es el descriptor del WS

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

Clase endpoint (define el servicio web):

 

 

@Endpoint
public class CountryEndpoint {
	private static final String NAMESPACE_URI = 
"http://spring.io/guides/gs-producing-web-service";

	private CountryRepository countryRepository;

	@Autowired
	public CountryEndpoint(CountryRepository countryRepository) {
		this.countryRepository = countryRepository;
	}

	@PayloadRoot(namespace = NAMESPACE_URI, localPart = "getCountryRequest")
	@ResponsePayload
	public GetCountryResponse getCountry(@RequestPayload GetCountryRequest request) {
		GetCountryResponse response = new GetCountryResponse();
		response.setCountry(countryRepository.findCountry(request.getName()));

		return response;
	}
}

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

La clase Endpoint posee el método getCountryque es el servicio web propiamente dicho. 

Recibe un objeto GetCountryRequest y retorna un GetCountryResponse.

Es decir, genera una respuesta a partir del parámetro name de la petición: se busca en el repositorio el país que recibido y se establece la respuesta como retorno del servicio.

 

 

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

Sobre la clase WebServiceConfig que contiene la configuración, genera el WSDL y que se lanza finalmente...

Esta configuración genera como resultado un fichero WSDL: sirve para describir nuestro servicio web para que los clientes lo puedan consultar y ver así cómo deben generar las peticiones y qué tipo de respuestas pueden esperar. 

 

 

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

La siguiente dependencia en el pom.xml descarga un Tomcat empotrado para servir el servicio web:

 

 

 

Para cambiar el puerto 8080 por defecto, en src/main/resources genero un application.properties con una entrada: server.port = 8888

 

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-ws</artifactId>
</dependency>

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

Finalmente se arranca la clase Application.java (Run As -> Java Application)

Y se puede visualizar la especificación del WSDL

Desde el navegadorhttp://localhost:8080/ws/countries.wsdl

Si cambio el puerto: http://localhost:8888/ws/countries.wsdl

 

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

Especificación del WSDL

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

¡¡Ahora sólo nos queda probarlo!!

No obstante, esto es un poco más complicado, ya que debemos componer un mensaje SOAP, y eso requiere de un formato XML de acuerdo a nuestro XSD.

Existen clientes que nos facilitan la tarea. Uno de ellos es SOAPUI (versión gratuita):

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

  • Generamos la petición a través de SOAPUI:
  • Ejecutamos
  • En Projects -> New SOAP Project

 

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

Se genera el esqueleto del mensaje a enviar y relleno los valores:

 

 

 

En CountriesRepository tendría la información a ser retornada por el servicio

Request

Response

UNIDAD 11: servicios web

 

eugeniaperez.es

11.1 Spring y Soap

La configuración tanto de los servicios como de los clientes con SOAP es mucho más compleja.

La transmisión de la información al ser en XML es más lenta y su parseo en el cliente más costosa.

Era el método tradicional anteriormente a REST, dado que antes se tendía a trabajar con XMLs.

UNIDAD 11: servicios web

 

eugeniaperez.es

11.2 Spring y Rest

Rest (Representational State Transferse refiere a una colección de principios para el diseño de arquitecturas web.

Rest NO es un estándar, solo un estilo de arquitectura basado en estándares:

  • HTTP
  • URL
  • Representación de recursos: XML/HTML/GIF/JPEG, etc
  • Tipos MIME: text/xml, text/html, etc

 

 

UNIDAD 11: servicios web

 

eugeniaperez.es

11.2 Spring y Rest

Lo mejor para captar la idea de lo que supone REST es ver la anatomía de una RESTful url.

Las URLs son nominales y no verbales, y representan un recurso:

Sobre esto se realizarían variaciones en función de si es inserción, actualización, borrado, etc. En contraposición a las peticiones tradicionales (sin un fw MVC):

 

http://www.miapp.net/cliente/42
http://www.miapp.net/cliente.php?id=45&ac=delete

UNIDAD 11: servicios web

 

eugeniaperez.es

11.2 Spring y Rest

Se permite utilizar toda la potencia que nos ofrecen los distintos métodos HTTP, y no sólo GET y POST, que son los que se han venido usando tradicionalmente:

  • GET: para leer datos, (READ)
  • PUT: para modificar datos, (UPDATE)
  • DELETE: para borrar datos, (DELETE)
  • POST: para crear datos, (CREATE)

Esto nos permite realizar un CRUD completo a través del controlador...

 

 

 

unidad 11: servicios web

 

eugeniaperez.es

Descarga el código en Bitbucket

 

Descarga el proyecto springmvc.rest del repositorio de Bitbucket:

Usuario: 

Psswd:

URL: https://eugenia_perez@bitbucket.org/eugenia_perez/springmvc.rest.git

 

 

UNIDAD 11: servicios web

 

eugeniaperez.es

11.2 Spring y Rest

Desarrollo del servicio web

Antes de nada, es muy importante incorporar estas dependencias al pom:

  • jackson-core
  • jackson-databind

UNIDAD 11: servicios web

 

eugeniaperez.es

11.2 Spring y Rest

Desarrollo del servicio web

  • El controlador será de tipo @RestController
  • Se puede unificar el mapeo al comienzo de la clase: @RequestMappping("nombre_controlador")
  • Fíjate que en lugar de retornar vistas  ahora retorna objetos de nuestro modelo de dominio (y no elementos que son una vista o un ModelView). Estos  serán serializados por el framework, por defecto en JSON.

 

No busco cambiar de 

página, sino datos...

UNIDAD 11: servicios web

 

eugeniaperez.es

11.2 Spring y Rest

Consumo del servicio web desde cliente

¡Ya tenemos nuestra API Rest! -> Estas acciones pueden ser llamadas desde cualquier dispositivo con conectividad a nuestra máquina, con la simple ayuda de un cliente que sea capaz de realizar peticiones HTTP.

Por ejemplo, comenzaremos haciendo una petición mediante el navegador. Vamos a hacer una petición GET a la URL: 

 

http://localhost:8080/springmvc/series

UNIDAD 11: servicios web

 

eugeniaperez.es

11.2 Spring y Rest

Consumo del servicio web desde cliente

Recuerda que el API Rest que se ofrece responde a:

SelectAll [GET]: 

SelectById [GET]:

Insert [POST]:

Update [PUT]:

Delete [DELETE]:

http://localhost:8080/springmvc/series
http://localhost:8080/springmvc/series/id
http://localhost:8080/springmvc/series
http://localhost:8080/springmvc/series/id
http://localhost:8080/springmvc/series/id

UNIDAD 11: servicios web

 

eugeniaperez.es

11.2 Spring y Rest

Consumo del servicio web desde cliente

¿Qué acción responderá? El método get de nuestro controlador (devuelve todas las películas en BD...):

1) A través del navegador

UNIDAD 11: servicios web

 

eugeniaperez.es

11.2 Spring y Rest

Consumo del servicio web desde cliente

2) A través de un cliente REST del navegador:

Instalo el plugin de Google Advanced REST client.

Lo inicio: http://localhost:8080/springmvc/series

  • GET: muestra todas
  • POST: inserta una serie {"title":"Fargo","numberOfEpisodes":"100","dateReleased":"2015-02-01","country":"USA"}  Cambio content-type a application/json

 

Se inserta en BD

UNIDAD 11: servicios web

 

eugeniaperez.es

11.2 Spring y Rest

Consumo del servicio web desde cliente

3) A través de una llamada Ajax mediante JQuery:

Mediante el fichero jsClient.html en src/main/webapp/resources.

Crea una fila por cada película retornada y la añade a la table:

 

 

 

 

$.get('http://localhost:8080/springmvc/series', function(data){
	var tableData = $('table tbody');

	$.each(data, function(idx, elm){
		tableData.append('<tr><td>' + elm.id + '</td><td>' + elm.title + '</td><td>' + elm.dateReleased + 
				'</td><td>' + elm.numberOfEpisodes + '</td><td>' + elm.country + '</td></tr>')
	});
});

UNIDAD 11: servicios web

 

eugeniaperez.es

11.2 Spring y Rest

Consumo del servicio web desde cliente

3) A través de una llamada Ajax mediante JQuery:

Utilizo el método PUT para actualizar el número de episodios de la serie con ID 1:

 

 

 

 

$('#updateSeries').on('click', function(){
	$.ajax({
		  url: "http://localhost:8080/springmvc/series/1",
		  type: "PUT",
		  data: JSON.stringify({
			  "id" : 1, 
			  "title" : "Better call Saul", 
			  "numberOfEpisodes" : "100", 
			  "dateReleased" : "2015-02-01",
			  "country":"USA"
			  }),
		  contentType: "application/json"
		}).done(function(response){
			alert(response);
		});	
});

UNIDAD 11: servicios web

 

eugeniaperez.es

11.2 Spring y Rest

Consumo del servicio web desde cliente

3) A través de una llamada Ajax mediante JQuery:

Para ejecutarlo: 

 

 

 

 

http://localhost:8080/springmvc/resources/jsClient.html

UNIDAD 11: servicios web

 

eugeniaperez.es

11.2 Spring y Rest

Consumo del servicio web desde cliente

4) Consumo desde otras aplicaciones, como una aplicación en Java.

Aunque el escenario más común de los servicios web REST es nutrir de datos a código Javascript que corre en el cliente, estos están disponibles a cualquiera otra tecnología servidor que los invoque.

Nos descargamos el proyecto a continuación.

 

 

 

 

unidad 11: Servicios web

 

eugeniaperez.es

Descarga el código en Bitbucket

 

Descarga el proyecto restclient del repositorio de Bitbucket:

Usuario: 

Psswd:

URL: https://eugenia_perez@bitbucket.org/eugenia_perez/restclient.git



Unit 11

By eugenia_perez