<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>java &#8211; Oscar Blancarte &#8211; Software Architecture</title>
	<atom:link href="https://www.oscarblancarteblog.com/tag/java-2/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.oscarblancarteblog.com</link>
	<description>Software Architect &#38; FullStack developer</description>
	<lastBuildDate>Sun, 02 Aug 2020 22:41:52 +0000</lastBuildDate>
	<language>es-MX</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.5.15</generator>

<image>
	<url>https://www.oscarblancarteblog.com/wp-content/uploads/2019/03/cropped-ob-32x32.png</url>
	<title>java &#8211; Oscar Blancarte &#8211; Software Architecture</title>
	<link>https://www.oscarblancarteblog.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">89905023</site>	<item>
		<title>Java Converter Pattern</title>
		<link>https://www.oscarblancarteblog.com/2019/09/05/java-converter-pattern/</link>
					<comments>https://www.oscarblancarteblog.com/2019/09/05/java-converter-pattern/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Thu, 05 Sep 2019 11:00:05 +0000</pubDate>
				<category><![CDATA[Patrones de Diseño]]></category>
		<category><![CDATA[java]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2884</guid>

					<description><![CDATA[<p>El patrón converter nos permite realizar conversiones bidireccionales entre dos tipo de datos equivalentes, evitando repetir código.</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/09/05/java-converter-pattern/">Java Converter Pattern</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image"><img loading="lazy" width="759" height="426" src="https://www.oscarblancarteblog.com/wp-content/uploads/2019/09/converter.jpg" alt="" class="wp-image-2885" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2019/09/converter.jpg 759w, https://www.oscarblancarteblog.com/wp-content/uploads/2019/09/converter-300x168.jpg 300w" sizes="(max-width: 759px) 100vw, 759px" /></figure>



<p>En Java como en cualquier otro lenguaje de programación, es común encontrarnos con la necesidad de realizar conversión de tipos de datos, sobre todo, aquellos tipos de datos de Entidad que tiene una relación directa con un DTO que utilizamos para enviar los datos del servidor a un cliente o aplicación web, lo que hace que tengamos que convertir la Entidad a DTO para enviarla al cliente y de DTO a Entidad para persistirla en la base de datos, lo cual es una tarea cansada y repetitiva que podemos evitar mediante el uso del patrón Converter.</p>



<span id="more-2884"></span>



<blockquote class="wp-block-quote"><p>Si no sabes que es un DTO te dejo la siguiente liga a mi artículo  <br><a href="https://www.oscarblancarteblog.com/2018/11/30/data-transfer-object-dto-patron-diseno/">Data Transfer Object (DTO)</a>, donde explico a detalle este patrón.</p></blockquote>



<p>Pues como lo acabo de decir, convertir tipos de datos es una tarea que se presenta mucho en las aplicaciones, pero sobre todo en la capa de negocio o servicios, donde tenemos que enviar un tipo de dato amigable para el cliente o navegador pero en el Backend necesitamos otros tipos de datos. Para evitar esta tarea tan repetitiva se puede utilizar el patrón Converter, el cual permite encapsular la lógica de conversión de dos tipos de datos de forma bidireccional, de esta forma, evitamos tener que repetir la lógica de conversión de los tipos de datos en todas las partes del programa donde sea requerido, y en su lugar, delegamos esta responsabilidad a una clase externa.</p>



<p>Para analizar esta problemática, analizaremos el caso típico de la Entidad Usuario, la cual tiene por lo general un id, username, password y los roles, tal como podemos ver a continuación:</p>



<pre class="wp-block-code"><code lang="java" class="language-java line-numbers">package com.oscarblancarteblog.entity;

import java.util.List;
import com.oscarblancarteblog.enums.Role;

public class User {
	
	private Long id;
	private String username;
	private String password;
	private List&lt;Role> roles;

	/** GET &amp; SET */
}</code></pre>



<p>Esta entidad es utiliza por el Backend para persisitir la información en la base de datos, sin embargo, no es la que utilizamos para enviar a los clientes, ya que por ejemplo, el campo `roles` es de un tipo de Enumeración, el cual no puede interpretar el cliente que quizás consuma el backend por medio de un API REST, por lo que es posible que en lugar de enviarle una lista de <em>Roles</em>, le tendremos que mandar un lista de <em>Strings</em>, lo que nos obliga a crear un DTO que se ve de la siguiente manera:</p>



<pre class="wp-block-code"><code lang="java" class="language-java line-numbers">import java.util.List;

public class UserDTO {
	private Long id;
	private String username;
	private String password;
	private List&lt;String> roles;

	/* GET &amp; SET */
}</code></pre>



<p>Este DTO ya es más amigable para el cliente, pero ahora tenemos un problema, como crear el DTO a partir del Entity y luego, cuando nos lo manden de regreso para guardarlo o actualizarlo, hay que hacer el proceso inverso. Por simple que parezca, esta es un tarea que se puede repetir muchas veces en la aplicación, creando mucho código redundante y que cada repetición puede inyectar errores, además, un cambio en la Entity o en el DTO, nos obliga a refactorizar todas las secciones donde habríamos echo la conversión, por este motivo, siempre es mejor crear una clase que se encargue exclusivamente de convertir entre Entity y DTO. </p>



<p>Para solucionar este problema y tener un mejor orden en nuestro código, deberemos crear una clase base de la cual extiendan todos los Converters de nuestra aplicación:</p>



<pre class="wp-block-code"><code lang="java" class="language-java line-numbers">package com.oscarblancarteblog.converter;

public abstract class AbstractConverter&lt;E,D> {

	public abstract E fromDto(D dto);

	public abstract D fromEntity(E entity);
}</code></pre>



<p>Esta clase abstracta define dos método, <code>fromEntity</code> que convierte una Entidad a DTO y <code><code>fromDto</code></code> que hace lo inverso, adicional , la clase define dos tipos genéricos <code>E</code> para representar al tipo Entidad y <code>D</code> para representar al DTO. </p>



<p>El siguiente paso es crear implementaciones concretas del Converter, por que deberá existir una implementación por cada Par Entidad-DTO. En este caso solo tenemos la clase User, por lo que crearemos el Convertidor para esta clase:</p>



<pre class="wp-block-code"><code lang="java" class="language-java line-numbers">package com.oscarblancarteblog.converter;

import java.util.stream.Collectors;

import com.oscarblancarteblog.dto.UserDTO;
import com.oscarblancarteblog.entity.User;
import com.oscarblancarteblog.enums.Role;

public class UserConverter extends AbstractConverter&lt;User, UserDTO>{

	@Override
	public User fromDto(UserDTO dto) {
		User user = new User();
		user.setId(dto.getId());
		user.setUsername(dto.getUsername());
		user.setPassword(dto.getPassword());
		
		// Prevent NullPointerException
		if(dto.getRoles()!=null) {
			user.setRoles(dto.getRoles().stream().map(rol -> Role.valueOf(rol)).collect(Collectors.toList()));
		}
		return user;
	}

	@Override
	public UserDTO fromEntity(User entity) {
		UserDTO user = new UserDTO();
		user.setId(entity.getId());
		user.setUsername(entity.getUsername());
		user.setPassword(entity.getPassword());
		
		// Prevent NullPointerException
		if(entity.getRoles()!=null) {
			user.setRoles(entity.getRoles().stream().map(rol -> rol.name()).collect(Collectors.toList()));
		}
		return user;
	}
}</code></pre>



<p>Esta nueva clase se encargará de convertir los dos tipos de datos dejando en un solo lugar la lógica de conversión y evitando tener que repetir esta lógica en toda nuestro código.</p>



<p>Podrás observar que esta clase no tiene gran ciencia, pues es básicamente tomar los valores de un objeto y pasarlos a otro objeto pero diferente tipo de datos, nada del otro mundo.</p>



<p>Ahora bien, ya con esto, ¿como le haríamos para convertir los datos?, pues ya solo falta instanciar al convertidor y utilizarlo. Imaginemos que tenemos un método que consulta un usuario:</p>



<pre class="wp-block-code"><code lang="java" class="language-java line-numbers">public UserDTO findUserByUsername(String username) {
	User user = userDAO.findByUsername(username);
	UserConverter converter = new UserConverter();
	return converter.fromEntity(user);
}</code></pre>



<p>En este método ya podemos observar las bondades del converter, pues nos deja un código muy limpio y no tenemos que preocuparnos por convertir la Entidad a DTO. Pero que pasaría si ahora nos mandan el Usuario como DTO para actualizarlo en la base de datos:</p>



<pre class="wp-block-code"><code lang="java" class="language-java line-numbers">public void save(UserDTO userDto) {
	UserConverter converter = new UserConverter();
	User userEntity = converter.fromDto(userDto);
	userDAO.save(userEntity);
}</code></pre>



<p>Nuevamente vemos como el converter nos ha salvado de nuevo, pues nos olvidamos de la lógica de conversión.</p>



<p>Pero que pasaría ahora si en lugar de buscar un solo usuario, necesitamos que nos regrese todos los usuarios, bueno, estos nos obligaría a retornar una lista en lugar de un solo usuario, por lo que tendriamos que implementar una lógica para convertir listas. Lo primero que se nos puede ocurrir es crear un for en el servicio anterior y convertir cada uno de los objetos, crear una nueva lista a partir de los resultados y retornar el valor, pero esto traerá el mismo problema que hablamos al inicio, pues tendríamos que repetir este proceso cada vez que necesitemos convertir una lista. Por suerte contamos con una clase base llamada <code>AbstractConverter</code>, ¿la recuerdas?</p>



<p>Que te parece si entonces aprovechamos esta clase base para agregar los método de conversión de listas y de esta forma, se podrán utilizar en todos los converters:</p>



<pre class="wp-block-code"><code lang="java" class="language-java line-numbers">package com.oscarblancarteblog.converter;

import java.util.List;
import java.util.stream.Collectors;

public abstract class AbstractConverter&lt;E,D> {

	public abstract E fromDto(D dto);
	
	public abstract D fromEntity(E entity);
	
	public List&lt;E> fromDto(List&lt;D> dtos){
		if(dtos == null) return null;
		return dtos.stream().map(dto -> fromDto(dto)).collect(Collectors.toList());
	}
	
	public List&lt;D> fromEntity(List&lt;E> entities){
		if(entities == null) return null;
		return entities.stream().map(entity -> fromEntity(entity)).collect(Collectors.toList());
	}
}</code></pre>



<p>Observa que hemos agregado dos nuevos métodos, <code>fromDto</code> y <code>fromEntity</code> los cuales se encargan de convertir las listas aprovechando los método abstractos previamente definidos, de esta forma, en cuanto creemos una implementación de <code>AbstractConverter</code> tendremos de forma automática los método para convertir listas. Ahora veamos como quedaría el ejemplo de un servicio de consulta de todos los usuarios:</p>



<pre class="wp-block-code"><code lang="java" class="language-java line-numbers">public List&lt;UserDTO> findAllUsers() {
	List&lt;User> users = userDAO.findAllUsers();
	UserConverter converter = new UserConverter();
	return converter.fromEntity(users);
}</code></pre>



<p>Observemos que esta ves solo hace falta pasar la lista al Converter para que este se encargue de iterar la lista y crearnos una nueva con todos los datos convertidos.</p>



<p>Ya solo nos quedaría hacer un ejemplo de convertir una lista de DTO a Entity, pero creo que ya está de más, por lo que si tienes tiempo, puedes hacer una prueba tu mismo para que veas que funcionará de la misma forma.</p>



<h2>Composición de convertidores</h2>



<p>Otra de las ventajas de los convertidores es que podemos utilizar un Converter dentro de otro, por ejemplo, imagina que tienes una Entidad  <code>Invoice</code> (factura) la cual tiene asociado al usuario que la creo:</p>



<pre class="wp-block-code"><code lang="java" class="language-java line-numbers">package com.oscarblancarteblog.entity;

import java.util.List;

public class Invoice {
	
	private Long id;
	private User user;
	private List&lt;Lines> lines;
}</code></pre>



<p>No te voy a aburrir nuevamente con toda la explicación, así que solo nos enfocaremos en las novedades. Dicho esto, observar que entre todos los campos que puede tener una factura, tiene una referencia al Usuario, por lo que en el converter de la factura podríamos implementar nuevamente la lógica para convertir al usuario, pero eso sería estúpido, pues ya tenemos una clase que lo hace, por lo tanto, podríamos utilizar el converter del usuario dentro del converter de la factura:</p>



<pre class="wp-block-code"><code lang="java" class="language-java line-numbers">package com.oscarblancarteblog.converter;

import com.oscarblancarteblog.entity.Invoice;
import com.oscarblancarteblog.entity.User;

public class InvoiceConverter extends AbstractConverter&lt;Invoice, InvoiceDTO>{

	private final UserConverter userConverter = new UserConverter();
	
	@Override
	public Invoice fromDto(InvoiceDTO dto) {
		
		Invoice invoice = new Invoice();
		invoice.setUser(userConverter.fromDto(dto.getUser()));
		// ... other setters
		return invoice;
	}

	@Override
	public InvoiceDTO fromEntity(Invoice entity) {
		InvoiceDTO invoice = new InvoiceDTO();
		invoice.setUser(userConverter.fromEntity(entity.getUser()));
		// ... other setters
		return invoice;
	}
}</code></pre>



<p>En este nuevo converter podemos ver que hemos instanciado a <code>UserConverter</code> y lo hemos utilizado para convertir el usuario en lugar de volver a implementar la lógica de conversión aquí.</p>



<figure class="wp-block-image"><a href="https://codmind.com/courses/java-lambda"><img loading="lazy" width="800" height="450" src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/banner-md.jpg" alt="Curso de Java lambdas y Streams" class="wp-image-3207" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/banner-md.jpg 800w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/banner-md-300x169.jpg 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/banner-md-768x432.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption>Te invitamos a ver nuestro curso de Java Lambdas + Streams para aprender a programar con el nuevos paradigma funcional.<br></figcaption></figure>



<h2>Conclusiones</h2>



<p>Hemos podido comprobar que los convertidores son de gran ayuda para evitar la repetición de código que puede se tedioso y propenso a errores, además, vemos que mediante la composición podemos reutilizar los convertidores para crear convertidores más avanzados. </p>



<p>Solo me resta mencionar un detalle importante, y es que debemos de tener cuidado que datos regresamos al cliente, ya que por ejemplo, regresar el password de nuestros usuarios a nuestros clientes puede ser una mala idea, así que podemos omitir este campo en el converter o eliminarlo de los objetos una vez que ha sido convertido, todo dependerá de que te funcione mejor.</p>



<p>Finalmente, recuerda que la clase base <code>AbstractConverter</code> es un punto de partida importante para implementar método genéricos para todos los convertidores, por lo que debemos aprovecharla si queremos agregar nuevos método en el futuro.</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/09/05/java-converter-pattern/">Java Converter Pattern</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2019/09/05/java-converter-pattern/feed/</wfw:commentRss>
			<slash:comments>16</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2884</post-id>	</item>
		<item>
		<title>Valores por defecto con @DefaultValue</title>
		<link>https://www.oscarblancarteblog.com/2019/01/21/valores-por-defecto-con-defaultvalue/</link>
					<comments>https://www.oscarblancarteblog.com/2019/01/21/valores-por-defecto-con-defaultvalue/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Mon, 21 Jan 2019 14:00:34 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[API REST]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2748</guid>

					<description><![CDATA[<p>Es habitual que algunos de los parámetros de nuestros servicios sean opcionales para el cliente, lo que provocaría la llega de estos valores en null para nuestra API, lo que puede resultar un problema para algunos parámetros que son requeridos para el correcto funcionamiento del API y que al menos debemos de tener un valor [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/21/valores-por-defecto-con-defaultvalue/">Valores por defecto con @DefaultValue</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/defaultvalues-1024x575.jpg" alt="Default Values con @DefaultValues" class="wp-image-2749"/></figure>



<p>Es habitual que algunos de los parámetros de nuestros servicios sean opcionales para el cliente, lo que provocaría la llega de estos valores en null para nuestra API, lo que puede resultar un problema para algunos parámetros que son requeridos para el correcto funcionamiento del API y que al menos debemos de tener un valor por defecto en caso de no enviarse.<br></p>



<span id="more-2748"></span>



				
<blockquote class="wp-block-quote"><p>NOTA: Este artículo es parte de un tutorial completo para crear API REST con JAX-RS, <a href="https://www.oscarblancarteblog.com/api-rest-java-jax-rs/">si quieres ver el índice completo entra aquí</a>. </p></blockquote>
		


<p><br>Mediante la anotación <code>@DefaultValue</code> podemos establecer un valor por default a algunos de nuestros parámetros que son opcionales para el cliente, lo que evita que tengan un valor nulo al llegar al API. Esta característica es especialmente buena en casos en los que el API necesita que estos parámetros tengan algún valor a pesar que el cliente no lo envíe, pues dejarlos en null puede provocar el fallo del servicio.</p>



<p>Imaginemos el siguiente ejemplo, tenemos que construir un servicios de consulta de clientes que permita paginar los resultados, por lo que el servicio deberá proporcionar la página actual y el número de registros esperados por página. En este ejemplo, podríamos imagina que si los valores no se definen, entonces el API debería de retornar todo, pero esto puede provocar un problema de performance, por que hay muchísimos clientes y cada cliente tiene una serie de objetos asociados que deberán ser retornados también, provocando una gran carga sobre la base de datos, es por ello, que debemos asegurarnos de que si el API no recibe estos parámetros entonces deberemos establecer un valor por default. Veamos el siguiente ejemplo:</p>



<pre class="wp-block-code"><code lang="java" class="language-java line-numbers">package api.services;

import java.util.*;
import javax.ws.rs.core.*;

@Path("customers")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class CustomersService {
	
	@GET
	public Response getCustomers(
			@DefaultValue("1") @QueryParam("currentPage") int currentPage, 
			@DefaultValue("10") @QueryParam("pageSize") int pageSize) {
		
		//Validate input
		if(currentPage &lt; 1 || pageSize &lt; 1) {
			return Response.ok("Invalid params").build();
		}
		
		//ccreate Dataset 
		List&lt;String> customers = new ArrayList&lt;>();
		for(int c = 1 ; c&lt;=100 ; c++) {
			customers.add("Customer " + c);
		}
		
		//Calculate sublist range
		int startIndex = (currentPage-1) * pageSize;
		int endIndex = startIndex + pageSize;
		
		//No more results
		if(startIndex >=customers.size()) {
			return Response.ok(new Object[0]).build();
		}
		
		//Prevent ArrayIndexOutOfBoundsException
		if(endIndex > customers.size()) {
			endIndex = customers.size();
		}
		
		//Getting sublist of elements
		List&lt;String> filters = customers.subList(startIndex, endIndex);
		
		return Response.ok(filters)
				.header("x-size", customers.size())
				.header("x-startIndex", startIndex)
				.header("x-endIndex", endIndex)
				.build();
	}	
}</code></pre>



<p><br>Para este ejemplo hemos definido que si el cliente no envía la página actual (<code>currentPage</code>) le daremos el valor de 1 por default, y para el tamaño de la página (<code>pageSize</code>) hemos definido el valor de 10. Esto quiere decir que en caso de que el cliente no envíe estos parámetros, regresaremos los 10 primeros registros.</p>



<p>También hemos retornado los headers <code>x-size</code>, <code>x-startIndex</code>, <code>x-endIndex</code> como metadato para el cliente, para que sepa el total de los elementos, el index del primer registro y el último respectivamente.</p>



<p>Veamos algunos ejemplos. En primer lugar probaremos ejecutar el servicio sin ninguno de los parámetros, para comprobar los valores por default:</p>



<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/test-sin-parametros.jpg" alt="probando los Default Values " class="wp-image-2751"/></figure>



<p>Podemos comprobar que se han retornado los primeros 10 resultados. </p>



<p>Hora probaremos únicamente con el parámetro pageSize=3, lo que establecerá la página por default en 1, regresando los primeros 3 resultados:</p>



<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/test-pagesize.jpg" alt="probando los Default Values 2" class="wp-image-2752"/></figure>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2>Conclusiones</h2>



<p>Los valores por default son una excelente opción para lidiar con valores requeridos por el API, pero que nos obligatorios para el cliente, sin embargo, el echo de que tengamos valores por default, no significa que no debemos validar los parámetros, pues el cliente siempre podrá enviar valores no esperados por el API que provoquen una falla o en el peor de los casos, hacer una <a href="https://www.oscarblancarteblog.com/2016/11/15/sql-injection/">inyección SQL</a>.</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/21/valores-por-defecto-con-defaultvalue/">Valores por defecto con @DefaultValue</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2019/01/21/valores-por-defecto-con-defaultvalue/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2748</post-id>	</item>
		<item>
		<title>Bean Params con @BeanParam</title>
		<link>https://www.oscarblancarteblog.com/2019/01/17/bean-params/</link>
					<comments>https://www.oscarblancarteblog.com/2019/01/17/bean-params/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Fri, 18 Jan 2019 00:17:13 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[API REST]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2735</guid>

					<description><![CDATA[<p>Los bean params hacen referencia a la capacidad de JAX-RS para recibir como parámetro objetos complejos definidos por una clase, esta clase puede ser vista como un Data Transfer Object (DTO), la cual contiene una serie de propiedades recuperadas de varias partes del request, como el header, query, path y formulario. Los Beans params no [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/17/bean-params/">Bean Params con @BeanParam</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[
				
<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/beanparam-1024x575.jpg" alt="Bean Params con @BeanParam" class="wp-image-2736"/></figure>



<p>Los bean params hacen referencia a la capacidad de JAX-RS para recibir como parámetro objetos complejos definidos por una clase, esta clase puede ser vista como un <a href="https://www.oscarblancarteblog.com/2018/11/30/data-transfer-object-dto-patron-diseno/">Data Transfer Object</a> (DTO), la cual contiene una serie de propiedades recuperadas de varias partes del request, como el header, query, path y formulario.<br><br></p>



<span id="more-2735"></span>



				
<blockquote class="wp-block-quote"><p>NOTA: Este artículo es parte de un tutorial completo para crear API REST con JAX-RS, <a href="https://www.oscarblancarteblog.com/api-rest-java-jax-rs/">si quieres ver el índice completo entra aquí</a>. </p></blockquote>
		


<p><br>Los Beans params no es una característica nativa del protocolo HTTP o la arquitectura REST, si no que JAX-RS la agrega para poder mapear todos los tipos de parámetros en una sola clase, la cual podríamos ver como un DTO que concentra en un solo punto todos los parámetros esperados. </p>



<p>Para comprender mejor como funcionan los Beans params, imaginemos que tenemos un formulario para registrar nuevos clientes, este formulario enviara al servicio todos los campos al API por medio de <code>@FormParams</code>, también enviaremos como un header un token de autenticación, para identificar al usuario que está realizando la invocación, imaginemos que el cliente llego por medio de una campaña promocional, por lo que necesitamos saber si llego por facebook, google, etc. por lo que enviaremos un <code>@QueryParam</code> para saber de donde llego el cliente. </p>



<p>Este caso, podríamos crear un parámetro en Java para uno de los parámetros esperados o podríamos crear una clase como la siguiente:</p>



<pre class="wp-block-code"><code>package api.services;

import javax.ws.rs.*;

public class CustomerDTO {
	@CookieParam("token") 
	private String token;

	@FormParam("firstname") 
	private String firstname; 
	
	@FormParam("lastname") 
	private String lastname;
	
	@FormParam("status") 
	private String status;
	
	@QueryParam("source")
	private String source;

	/* GET and SET */
}</code></pre>



<p><br>La clase <code>CustomerDTO</code> es en realidad una composición de variables que son recuperadas de varias partes de la petición. Solo en este caso hemos recuperado parámetros de las cookies (<code>@CookieParam</code>), form (<code>@FormParam</code>), query (<code>@QueryParam</code>), sin embargo, la idea de los <code>@BeanParam</code> es que se pueden utilizar cualquiera de las @xxxParam, lo que quiere decir que podemos utilizar:</p>



<ul><li><a href="https://www.oscarblancarteblog.com/2018/12/17/path-params-con-pathparam/">@PathParam</a></li><li>@QueryParam</li><li>@MatrixParam</li><li>@CookieParam</li><li>@HeaderParam</li></ul>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<p>El siguiente paso es crear un método REST que reciba el <code>@BeanParam</code>:</p>



<pre class="wp-block-code"><code>package api.services;

import java.util.Map;

import javax.ws.rs.*;
import javax.ws.rs.core.*;

@Path("customers")
public class CustomersService {
	
	@POST
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Response saveCustomer(@BeanParam CustomerDTO customer) {
		
		String result = String.format("firstname = %s, lastname = %s, status = %s, token = %s, source = %s", 
				new Object[]{customer.getFirstname(), 
						customer.getLastname(),
						customer.getStatus(), 
						customer.getToken(),
						customer.getSource()});
		
		return Response.ok(result).build();
	}	
}
</code></pre>



<p><br>El formulario con el que invocaremos el servicio REST es el siguiente:</p>



<pre class="wp-block-code lang:xhtml decode:true"><code>&lt;!DOCTYPE html>
&lt;html>
	&lt;body>
		&lt;p>Customer form&lt;/p>
	
		&lt;form action="http://localhost:8080/api-0.0.1-SNAPSHOT/customers?source=google" method="post">
			&lt;div>
				&lt;label for="firstname" style="display:inline-block; width: 100px;">Nombre&lt;/label>
				&lt;input id="firstname" type="text" name="firstname" />
			&lt;/div>
			&lt;div>
				&lt;label for="lastname" style="display:inline-block; width: 100px;">Apellido&lt;/label>
				&lt;input id="lastname" type="text" name="lastname" />
			&lt;/div>
			&lt;div>
				&lt;label for="status" style="display:inline-block; width: 100px;">Estatus&lt;/label>
				&lt;select id="status" name="status" >
					&lt;option value="active">Activo&lt;/option>
  					&lt;option value="inactive">Inactivo&lt;/option>
				&lt;/select>
			&lt;/div>
			&lt;br/>
			&lt;input type="submit" value="Guardar" />
		&lt;/form>
	&lt;/body>
&lt;/html></code></pre>



<p>Observemos que hemos agregado el query param en el <code>action</code> del <code>&lt;form&gt;</code>, por lo que será enviado al servidor al momento del submit.</p>



<p>Adicional, agregaremos la cookie token directamente desde el inspector de chrome:</p>



<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/test-3-1024x502.jpg" alt="@BeanParam cookie" class="wp-image-2739"/></figure>



<p><br>Y obtendremos el siguiente resultado:</p>



<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/result-1.jpg" alt="@BeanParam test result" class="wp-image-2741"/></figure>



<h2>Conclusiones</h2>



<p>Como hemos podido validar, los <code>@BeanParam</code> son una excelente estrategia para realizar una composición de una serie de parámetros en una sola fuente de datos, los cuales podríamos fácilmente reutilizar para más de un servicio. Además, nos evita tener que definir una serie de parámetros para poder recuperar cada uno de los valores esperados.</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<hr class="wp-block-separator"/>
		<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/17/bean-params/">Bean Params con @BeanParam</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2019/01/17/bean-params/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2735</post-id>	</item>
		<item>
		<title>Cookie params con @CookieParam</title>
		<link>https://www.oscarblancarteblog.com/2019/01/15/cookie-params-con-cookieparam/</link>
					<comments>https://www.oscarblancarteblog.com/2019/01/15/cookie-params-con-cookieparam/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Tue, 15 Jan 2019 19:14:39 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[API REST]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2727</guid>

					<description><![CDATA[<p>Las cookies son hasta la fecha una de las formas más utilizadas que tenemos para persistir valores del lado del cliente, las cuales pueden ser recuperadas por el servidor para identificar a un usuario, darle seguimiento o simplemente para guardar algún valor que utilizaremos después. Todas las cookies que guardemos en el cliente serán transmitidas [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/15/cookie-params-con-cookieparam/">Cookie params con @CookieParam</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[
				
<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/cookieparam-1024x575.jpg" alt="Cookie params con @CookieParam" class="wp-image-2728"/></figure>



<p>Las cookies son hasta la fecha una de las formas más utilizadas que tenemos para persistir valores del lado del cliente, las cuales pueden ser recuperadas por el servidor para identificar a un usuario, darle seguimiento o simplemente para guardar algún valor que utilizaremos después.<br><br></p>



<span id="more-2727"></span>



				
<blockquote class="wp-block-quote"><p>NOTA: Este artículo es parte de un tutorial completo para crear API REST con JAX-RS, <a href="https://www.oscarblancarteblog.com/api-rest-java-jax-rs/">si quieres ver el índice completo entra aquí</a>. </p></blockquote>
		


<p><br>Todas las cookies que guardemos en el cliente serán transmitidas al servidor de forma automática al servidor en los request posteriores, lo que puede ser de grán ayuda para identificar la sesión del usuario, el estado o incluso, guardar tokens de autenticación para identificar al usuario en cada llamada.</p>



<p>Las cookies no es algo que podamos ver a simple vista, pues solo se pueden ver con ayuda de herramientas que monitoren el tráfico HTTP, como es el caso del inspector de elementos de Chrome u otras herramientas especializadas como es el caso de Restlet, SOAPUI, postman, etc.</p>



<p>Desde chrome podemos ver todas las cookies que una página ha dejado en nuestro equipo, e incuso, podríamos agregar algunas manualmente para realizar algunas pruebas. Para verlas, solo basta abrir el inspector de elementos, dirigirse a la pestaña de Application y seleccionar la opción de cookies, tal como podemos ver en la siguiente imagen:</p>



<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/cookies-chrome.jpg" alt="cookies Inspector de elementos con Chorme" class="wp-image-2729"/></figure>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2>Recuperar las Cookies con JAX-RS</h2>



<p>Mediante el API de JAX-RS es muy fácil de recuperar las cookies del lado del servidor, ya que solo es necesario anotar con <code>@CookieParam</code> alguno de los parámetros del método Java en la cual queremos inyectar el valor de una cookie. Veamos el siguiente ejemplo que espera una cookie de autenticación llamado token:</p>



<pre class="wp-block-code"><code>package api.services;

import java.util.Map;

import javax.ws.rs.*;
import javax.ws.rs.core.*;

@Path("customers")
public class CustomersService {

	@POST
	@Produces(MediaType.TEXT_PLAIN)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Response saveCustomer(
			@CookieParam("token") String token) {
		
		if("1234".equals(token)) {
			return Response.ok("OK").build();
		}else {
			return Response.ok("UNAUTHORIZED").status(Response.Status.UNAUTHORIZED).build();
		}
	}
}</code></pre>



<p>En este ejemplo estamos el header <code>token</code>, el cual deberá tener el valor <code>1234</code>, de lo contrario, mandaremos un error de autenticación.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2>Establecer una nueva Cookie</h2>



<p>Otra cosa que podemos hacer es establecer una nueva cookie en el cliente, por ejemplo, podríamos agregar el token en caso de que este no tenga uno, veamos cómo quedaría:</p>



<pre class="wp-block-code"><code>package api.services;

import java.util.Map;
import javax.ws.rs.*;
import javax.ws.rs.core.*;

@Path("customers")
public class CustomersService {

	@POST
	@Produces(MediaType.TEXT_PLAIN)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Response saveCustomer(
			@CookieParam("token") String token) {
		
		if(token == null) {
			NewCookie newToken = new NewCookie("token", "1234");
			return Response.ok("OK").cookie(newToken).build();
		}
		
		return Response.ok("OK").build();
	}	
}</code></pre>



<p>Utilizamos la clase <code>NewCookie</code> para definir una nueva cookie que deberá ser creada en el cliente, demás, utilizamos el método <code>cookie</code> de la clase Response para enviarla al cliente.</p>



<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/newtoken.jpg" alt="nuevo cookie" class="wp-image-2730"/></figure>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2>Conclusiones</h2>



<p>A pesar de que las cookies han sido la forma tradicional de guardar los datos en el cliente, la llegada de HTML5 nuevas alternativas, como lo es el Local Storage y el Session Storage, de los cuales no hablaremos en esta ocasión, pero las menciono por si quieres investigar un poco más al respecto.</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<hr class="wp-block-separator"/>
		<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/15/cookie-params-con-cookieparam/">Cookie params con @CookieParam</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2019/01/15/cookie-params-con-cookieparam/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2727</post-id>	</item>
		<item>
		<title>Header params con @HeaderParam</title>
		<link>https://www.oscarblancarteblog.com/2019/01/10/header-params-con-headerparam/</link>
					<comments>https://www.oscarblancarteblog.com/2019/01/10/header-params-con-headerparam/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Fri, 11 Jan 2019 05:30:38 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[API REST]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2709</guid>

					<description><![CDATA[<p>Los header son utilizados en REST para enviar metadatos asociados a la petición o la respuesta, los cuales van desde el formato y tamaño del payload, nombre del servidor del servidor de aplicaciones, fecha de invocación, caducidad de un recurso, versión y nombre del sistema operativo, tipo de navegador, dispositivo, lenguaje y hasta headers para [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/10/header-params-con-headerparam/">Header params con @HeaderParam</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[
				
<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/headerpram-1024x575.jpg" alt="Header params con @HeaderParam" class="wp-image-2720"/></figure>



<p>Los header son utilizados en REST para enviar metadatos asociados a la petición o la respuesta, los cuales van desde el formato y tamaño del payload, nombre del servidor del servidor de aplicaciones, fecha de invocación, caducidad de un recurso, versión y nombre del sistema operativo,  tipo de navegador, dispositivo, lenguaje y hasta headers para la seguridad.<br><br></p>



<span id="more-2709"></span>



				
<blockquote class="wp-block-quote"><p>NOTA: Este artículo es parte de un tutorial completo para crear API REST con JAX-RS, <a href="https://www.oscarblancarteblog.com/api-rest-java-jax-rs/">si quieres ver el índice completo entra aquí</a>. </p></blockquote>
		


<p><br>Los headers es una sección adicional al payload de una solicitud, la cual no puede ser vista a simple vista, si no que requiere de un analizador HTTP para poderlos ver, sin embargo, todas las solicitudes llevan por default una serie de headers, incluso si nosotros no  las establecemos. Los headers enviados por default varían de cliente a cliente y de servidor a servidor, por lo que en este artículo aprenderemos a analizar los headers.</p>



<p>Uno de los principales usos de los header es para enviar los tokens de  <br>autenticación, como es el caso de<a href="https://www.oscarblancarteblog.com/2017/06/08/autenticacion-con-json-web-tokens/"> JSON Web Token</a> (JWT), el cual lo establecemos en el header <code>Authorization</code>, dicho lo anterior, veremos como recuperar este header mediante el API JAX-RS de Java.</p>



<pre class="wp-block-code"><code>package api.services;

import javax.ws.rs.*;
import javax.ws.rs.core.*;

@Path("security")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class Security {
	
	@GET
	public Response authenticate(@HeaderParam("authorization") String token) {
		return Response.ok("token="+token).build();
	}
}</code></pre>



<p>Los header pueden ser recuperados anotando los parámetros con <code>@HaderParam</code>, por lo que vamos a requerir un parámetro en Java por cada header que esperamos recibir en el API.</p>



<p>Si ejecutamos el ejemplo anterior, podemos ver el siguiente resultado:</p>



<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/test-1-1024x625.jpg" alt="JAX-RS @HeaderParam recuperar un query param" class="wp-image-2721"/></figure>



<p>En la parte superior podemos ver los header que definimos en el request y en la parte de abajo los header que nos retorno el servidor; en la respuesta podemos ver el token que le hemos enviado.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Otra de las formas de recuperar los header es por medio de la clase <code>HttpHeaders</code>, la cual podemos inyectar a nuestro método mediante la anotación <code>@Context</code>. La ventaja evidente de esté método es que podemos recuperar cualquier header, sin importar si lo esperábamos o no y nos evita tener que definir una grán cantidad de parámetros si esperamos muchos headers. Veamos un nuevo ejemplo con este método:</p>



<pre class="wp-block-code"><code>package api.services;

import java.util.Map;

import javax.ws.rs.*;
import javax.ws.rs.core.*;

@Path("security")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public class Security {
	
	@GET
	public Response authenticate (@Context HttpHeaders headers) {
		String result = "";
		for(Map.Entry entry: headers.getRequestHeaders().entrySet() ) {
			result += entry.getKey() + "=" + entry.getValue() + ", ";
		}
		
		return Response.ok(result).build();
	}
}</code></pre>



<p><br>Ahora veamos una ejecución de prueba:</p>



<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/test-2-1024x679.jpg" alt="JAX-RS @HeaderParam recuperar todos los query params" class="wp-image-2722"/></figure>



<p>En este caso, podemos observar que hemos recibido muchos más parámetros de los que enviamos, y esto se debe a lo que mencionamos al inicio, y es que cada cliente agrega una serie de headers para identificarlo.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2>Agregar headres en la respuesta</h2>



<p>Ademas de recibir headers, también podemos enviar headers a los clientes del API; los headers los podemos agregar directamente al objeto Response, mediante una serie de claves-valor, veamos un ejemplo:</p>



<pre class="wp-block-code"><code>package api.services;

import java.util.Map;
import javax.ws.rs.*;
import javax.ws.rs.core.*;

@Path("security")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public class Security {
		
	@GET
	public Response authenticate (@Context HttpHeaders headers) {
		String result = "";
		for(Map.Entry entry: headers.getRequestHeaders().entrySet() ) {
			result += entry.getKey() + "=" + entry.getValue() + ", ";
		}
		
		Response.ResponseBuilder response = Response.ok(result);
		response.header("my-header1", "value 1");
		response.header("my-header2", "value 2");
		
		return response.build();
	}
}</code></pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2>Conclusiones</h2>



<p>No debemos de confundirnos al momento de utilizar los headers, pues no se deben de utilizar como una forma de enviar parámetros a nuestro API, si no como metadatos que complementen el request y que ayuden al servidor/cliente como tratar la solocitud/respuesta.</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<hr class="wp-block-separator"/>
		<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/10/header-params-con-headerparam/">Header params con @HeaderParam</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2019/01/10/header-params-con-headerparam/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2709</post-id>	</item>
		<item>
		<title>Java 8 – Streams</title>
		<link>https://www.oscarblancarteblog.com/2017/03/16/java-8-streams-2/</link>
					<comments>https://www.oscarblancarteblog.com/2017/03/16/java-8-streams-2/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Thu, 16 Mar 2017 09:00:25 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[java8]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=1574</guid>

					<description><![CDATA[<p>Los Streams son una secuencia de elementos que soportan operaciones de agregación secuencial y paralela. Una de las nuevas características de Java 8 que permite manipular las colecciones como nunca, casi parecido a un sueño. Como programador seguramente has trabajado con una infinidad de colecciones, seguramente te ha tocado recorrerlas, ordenarlas, dividirlas, filtrarlas, eliminar o [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2017/03/16/java-8-streams-2/">Java 8 – Streams</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="aligncenter size-full wp-image-1575" src="https://www.oscarblancarteblog.com/wp-content/uploads/2017/03/java-8-Streams.png" alt="java 8 - Streams" width="929" height="524" />Los Streams son una secuencia de elementos que soportan operaciones de agregación secuencial y paralela. Una de las nuevas características de Java 8 que permite manipular las colecciones como nunca, casi parecido a un sueño.<span id="more-1574"></span></p>
<p>Como programador seguramente has trabajado con una infinidad de colecciones, seguramente te ha tocado recorrerlas, ordenarlas, dividirlas, filtrarlas, eliminar o agregar nuevos elementos en la colección. Y cada vez que hacías esto estabas casi forzado a realizar un foreach sobre la colección, incluso, tenías que hacer un foreach anidado para poder realizar operaciones más complejas; prueba de ello es que el nombre <span class="lang:java decode:true crayon-inline ">ConcurrentModificationException</span>  te recuerda a algo (¿o no?).</p>
<p>Pues bien, los Streams no permite crear atajos a la hora de procesar colecciones, creando flujos de datos que permite el procesamiento de una forma declarativa, es decir, que nos centramos en lo que queremos resolver, y no en cómo debemos hacerlo, como pasa en la programación imperativa.</p>
<p><iframe class='youtube-player' width='648' height='365' src='https://www.youtube.com/embed/EsBXjODbmJM?version=3&#038;rel=1&#038;fs=1&#038;autohide=2&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;wmode=transparent' allowfullscreen='true' style='border:0;'></iframe></p>
<p style="text-align: center;">Sígueme en mi canal de Youtube</p>
<p style="text-align: center;">
<p>Pero dejémonos de palabrerías (que me sobran) y vallamos a un escenario concreto donde se puede aplicar para entender mejor. Veamos el caso más simple al utilizar una colección, imprimamos todos los valores de una lista ¿Simple no?</p>
<pre class="lang:java decode:true">public static void printForeach(){
  List&lt;String&gt; names = getStringArray();
  for (String name : names) {
     System.out.println(name);
  }
}</pre>
<p>Este código que está viendo, es un escenario normal que utilizarías para imprimir todos los elementos de una lista (apuesto que sí), ¿verdad que no tiene nada de extraño? La verdad es que no, porque ya estamos acostumbrados a hacerlo así, pero te apuesto que tu punto de vista acerca de este código cambiaría si ti dijera que puedo hacer el foreach en una solo línea de código. ¿no me crees? Pues tómala!!</p>
<pre class="lang:java decode:true ">public static void printStream(){
    List&lt;String&gt; names = getStringArray();
    names.stream().forEach(System.out::println);
}</pre>
<p>Probablemente te estés preguntado ¿qué clase de brujería es eso?, pero la realidad es que no hay tal brujería, simplemente estamos utilizando los Streams. Notemos que estamos utilizando el método <span class="lang:java decode:true crayon-inline ">stream()</span> para obtener el Stream, seguido, solo utilizamos el método <span class="lang:java decode:true crayon-inline ">forEach()</span> en el cual definimos mediante lo que vamos a hacer para cada elemento de la colección. En este caso estamos imprimiendo cada empleado utilizando <a href="https://www.oscarblancarteblog.com/2017/02/27/java-8-metodos-referenciados/">Referencia a métodos</a>.</p>
<p>Para comprender mejor que es un stream (espero no herir los sentimientos de algunos) lo voy a explicar de una forma simple fácil de digerir y que pueda que no cuadre con la definición perfecta, pero seguro me entenderás. Imagina que los streams son una forma de iterar todos los elementos de la colección de una forma simple, y que además mientras los iteras puedes realizar operaciones sobre la colección de forma declarativa. Es decir, vamos a realizar operaciones pero centrándonos en el objetivo que buscamos, no en cómo implementar el algoritmo para que funcione. Veamos otro ejemplo más complejo.</p>
<p>Imaginemos que tenemos una lista de Empleados, cada empleado tiene un ID que lo identifica como único, tiene un nombre y el departamento el que pertenece. La lista de empleados es la siguiente:</p>
<table  class=" table table-hover" >
<tbody>
<tr>
<td width="56">ID</td>
<td width="321">Name</td>
<td width="189">Department</td>
</tr>
<tr>
<td width="56">1</td>
<td width="321">Oscar Blancarte</td>
<td width="189">Systems</td>
</tr>
<tr>
<td width="56">2</td>
<td width="321">Liliana Castro</td>
<td width="189">Systems</td>
</tr>
<tr>
<td width="56">3</td>
<td width="321">Fernanda Martinez</td>
<td width="189">Systems</td>
</tr>
<tr>
<td width="56">4</td>
<td width="321">Manuel Lopez</td>
<td width="189">RH</td>
</tr>
<tr>
<td width="56">5</td>
<td width="321">Rebeca Perez</td>
<td width="189">Systems</td>
</tr>
<tr>
<td width="56">1</td>
<td width="321">Oscar Blancarte</td>
<td width="189">Systems</td>
</tr>
</tbody>
</table>
<p>Ahora bien, sobre esta lista queremos filtrar todos los Empleados que pertenecen al departamento de sistemas, luego vamos a ordenas todos los empleados de forma ascendente por su nombre, luego vamos a filtrar los elementos repetidos mediante su ID, finalmente, imprimiremos el nombre de todos los empleados que cumplieron con todas las reglas. Pfff!! ¿Imaginas hacer esto con una colección? A mí ya me empezó a doler la cabeza 🙁 . Por suerte, el enfoque declarativo de los Streams nos permite enfocarnos solamente en el <strong>que</strong> y no en el <strong>cómo</strong>. Veamos cómo quedaría la solución usando Streams.</p>
<pre class="lang:java decode:true ">public static void printOrderedSystemEmployees(){
    List&lt;Employee&gt; employess = getEmployeeArray();
    employess.stream()
            .filter(x -&gt; x.getDepartment().equals("Systems"))
            .sorted((x,y) -&gt; x.getName().compareToIgnoreCase(y.getName()))
            .distinct()
            .forEach(System.out::println);
}</pre>
<p><figure id="attachment_3207" aria-describedby="caption-attachment-3207" style="width: 800px" class="wp-caption aligncenter"><a href="https://codmind.com/courses/java-lambda"><img loading="lazy" class="wp-image-3207 size-full" src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/banner-md.jpg" alt="Curso de Java Lambdas con Streams" width="800" height="450" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/banner-md.jpg 800w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/banner-md-300x169.jpg 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/banner-md-768x432.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption id="caption-attachment-3207" class="wp-caption-text">Te invitamos a ver nuestro curso de Java Lambdas + Streams para aprender a programar con el nuevos paradigma funcional.</figcaption></figure></p>
<p>Ves lo fácil que es hacer todo esto con los Streams, solo nos preocupamos por lo que queremos hacer pero no por el cómo. Veamos los métodos del Stream utilizados, filter, nos permite filtrar elementos de la lista, para lo cual solo deberemos crear una expresión que regrese un boolean, si regresa true, entonces es agregado al Stream de resultados. Luego tenemos el método <span class="lang:java decode:true crayon-inline ">sorted()</span> en el cual definimos cual es mayor mediante la comparación de los nombres. Seguido, utilizamos el método <span class="lang:java decode:true crayon-inline ">distinct()</span> para filtrar los Empleados repetidos, para esto hemos sobreescrito el método equals para comprar por el ID en lugar del Hashcode. Finalmente un foreach para imprimir los resultados:</p>
<ul>
<li>Fernanda Martinez</li>
<li>Liliana Castro</li>
<li>Oscar Blancarte</li>
<li>Rebeca Perez</li>
</ul>
<p>¡Realmente sorprendente verdad!!, al menos para mí si… Pues bien, así como vimos algunos métodos interesantes de los Streams, debes de saber que la interface Stream proporciona varios métodos interesantes que te pueden ayudar muchísimo, sin embargo la intención de este artículo es introducirte en el concepto de los Stream y que logres entender que son y cómo se utilizan, por lo que si quieres aprender todavía más, poder ver este <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html">link</a>, donde explican a profundidad la interface Stream y todos los métodos que expone. Me gustaría explicarte a detalle cada uno de los métodos disponibles, pero en realidad creo que sería reinventar la rueda, pues en el link se explica mucho mejor de lo que yo mismo podría hacerlo.</p>
<p>El resultado se puede apreciar mejor con la siguiente imagen:</p>
<p><img loading="lazy" class="aligncenter wp-image-1583" src="https://www.oscarblancarteblog.com/wp-content/uploads/2017/03/Java-8-Streams.png" alt="Java 8 - Streams" width="1003" height="713" /></p>
<p>En fin, creo que si lograste entender que son los Streams yo me doy por bien servidor, pero si por algún motivo tienes alguna duda, puedes escribirme en la sección de comentarios y con gusto te contestaré.</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2017/03/16/java-8-streams-2/">Java 8 – Streams</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2017/03/16/java-8-streams-2/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1574</post-id>	</item>
		<item>
		<title>Ordenar Listas en Java</title>
		<link>https://www.oscarblancarteblog.com/2017/02/28/ordenar-listas-en-java/</link>
					<comments>https://www.oscarblancarteblog.com/2017/02/28/ordenar-listas-en-java/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Tue, 28 Feb 2017 09:00:26 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[javahints]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=1451</guid>

					<description><![CDATA[<p>Si eres programador seguramente te has encontrado con el problema de Ordenar Listas, pero ¿Estamos utilizando la solución correcta o estamos reinventando la rueda? Pues en este artículo hablaremos de las formas estándares que ofrece Java para ordenar listas sin tener que programar más de lo requerido. Básicamente Java ofrece dos interfaces que serán claves [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2017/02/28/ordenar-listas-en-java/">Ordenar Listas en Java</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="alignleft wp-image-594 size-thumbnail" src="https://www.oscarblancarteblog.com/wp-content/uploads/2014/07/google-oracle-java1-150x150.jpg" alt="Ordenar Listas en Java" width="150" height="150" />Si eres programador seguramente te has encontrado con el problema de Ordenar Listas, pero ¿Estamos utilizando la solución correcta o estamos reinventando la rueda? Pues en este artículo hablaremos de las formas estándares que ofrece Java para ordenar listas sin tener que programar más de lo requerido.</p>
<p>Básicamente Java ofrece dos interfaces que serán claves para realizar un ordenamiento simple, las cuales son <span class="lang:java decode:true crayon-inline">Comparator</span>  y <span class="lang:java decode:true crayon-inline">Comparable</span>, estas dos interfaces atienden contextos diferentes en el ordenamiento de las listas, pues existen dos escenarios concretos (Si ya conoces la teoría puedes brincarte a la última sección):</p>
<p><span id="more-1451"></span></p>
<h2>Objetos preparados para ser Ordenados</h2>
<p>El escenario más simple para ordenar un Lista, es cuando sus elementos están preparados para ser ordenados, esto implica que los elementos de la lista implementan la interface <span class="lang:java decode:true crayon-inline ">Comparable</span>. Al implementar esta interface, las clases deberá implementar el método <span class="lang:java decode:true crayon-inline ">public interface Comparable&lt;T&gt;</span>, el cual sirve para comprar un objeto contra otro, este método recibe como parámetro otro objeto, el cual utilizaremos para comprarlo contra el actual para responder con un entero, el cual deberá ser:</p>
<ul>
<li>&lt; 0 (Menor que cero): cuando el objeto actual es menor que el otro</li>
<li>= 0 (Igual a cero): cuando los objetos son iguales</li>
<li>&gt; 0 (Mayor que cero): cuando el otro objeto es mayor.</li>
</ul>
<p>Cuando una clase implementa <span class="lang:java decode:true crayon-inline ">Comparable</span> entonces podemos decir que está preparada para ser Ordenada y ordenarla será tan simple como hacer lo siguiente:</p>
<p>Collections.sort(lstSortEmployees);</p>
<p>Asumiendo que la variable <span class="lang:java decode:true crayon-inline ">lstSortEmployees</span> es una lista de objetos que implementan <span class="lang:java decode:true crayon-inline ">Comparable</span>.<!--more--></p>
<h2>Objetos que no están preparados para ser Ordenados</h2>
<p>Por otra parte, las clases que no implementan <span class="lang:java decode:true crayon-inline ">Comparable</span> no podrán ser ordenadas de forma natural, por lo que tendremos que recurrir a la interface <span class="lang:java decode:true crayon-inline ">Comparator</span>, la cual sirve para crear una clase externa que ayude al ordenamiento de los Objetos sin modificar la estructura de las clases existentes. Para lo cual será necesario crear una nueva clase que implementa la interface <span class="lang:java decode:true crayon-inline ">Comparator</span> y con ello el método <span class="lang:java decode:true crayon-inline ">int compare(T o1, T o2)</span>, el cual funciona exactamente igual que el de la interface <span class="lang:java decode:true crayon-inline ">Comparable</span>, solo que este recibe como parámetros los dos objetos que será comparados.</p>
<p>Ahora bien, si queremos ordenar una lista mediante este método podríamos hacerlo de la siguiente manera:</p>
<pre class="lang:java decode:true ">Collections.sort(lstEmployees, new EmployeeComparator());</pre>
<p>Donde <span class="lang:java decode:true crayon-inline ">lstEmployees</span> es la lista de objetos a ordenar y <span class="lang:java decode:true crayon-inline ">EmployeeComparator</span> es una clase que implementa <span class="lang:java decode:true crayon-inline ">Comparator</span>. Aunque también podríamos ahorrarnos la creación de una nueva clase y crear una clase anónima, como podemos ver a continuación:</p>
<pre class="tab-convert:true lang:java decode:true">Collections.sort(lstEmployees, new Comparator&lt;Employee&gt;(){

    @Override
    public int compare(Employee o1, Employee o2) {
        return o1.getName().compareToIgnoreCase(o2.getName());
    }
});</pre>
<p>Veamos que este último ejemplo instanciamos la interface <span class="lang:java decode:true crayon-inline">Comparator</span> al vuelo y definimos el método <span class="lang:java decode:true crayon-inline ">compare</span> para determinar cuál empleado es mayor que cual.</p>
<p>Finalmente, Java 8 ofrece una forma muchos más simple de ordenar los objetos utilizado Lamba Expresión, por lo cual en lugar de crear un <span class="lang:java decode:true crayon-inline ">Comparator</span>, solo definimos la estrategia para comparar los objetos, veamos cómo quedaría:</p>
<pre class="lang:java decode:true ">Collections.sort(lstEmployees, (x, y) -&gt; x.getName().compareToIgnoreCase(y.getName()));</pre>
<p>Mediante lamba expresión definimos solamente como los objetos deberán ser comparados.</p>
<h2>Un ejemplo práctico:</h2>
<p>Muy bonita la explicación, pero pasemos mejor a un ejemplo práctico. Vamos a ver un ejemplo rápido para realizar los 3 tipos de ordenamientos que vimos anteriormente. Todo el código fuente lo puedes encontrar el GiHub: <a href="https://github.com/oscarjb1/SortList.git">https://github.com/oscarjb1/SortList.git</a></p>
<pre class="lang:java decode:true" title="SortMain.java">package com.osb.sortlist;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * @author Oscar Blancarte &lt;oscarblancarte3@gmail.com&gt;
 */
public class SortMain {

    private static final String[] NAMES = new String[]{
        "Oscar Blancarte",
        "Juan Perez",
        "Gabriel German",
        "Liliana Castro",
        "Alfredo Alvarado",
        "Rebeca Hernandez",
        "Sofia Galindo",
        "Samuel Alvarez",
        "Manuel Orozco"
    };

    public static void main(String[] args) {

        //Ordenar empleados que estan preparados para ser ordenados
        List&lt;SortEmployee&gt; lstSortEmployees = getSorteableEmployeeList();
        Collections.sort(lstSortEmployees);
        printList("lstSortEmployess ==&gt;", lstSortEmployees);

        //Ordenar empleados que no estan preparados para ser ordenados
        List&lt;Employee&gt; lstEmployees = getEmployeeList();
        Collections.sort(lstEmployees, new Comparator&lt;Employee&gt;(){
            @Override
            public int compare(Employee o1, Employee o2) {
                return o1.getName().compareToIgnoreCase(o2.getName());
            }
        });
        printList("lstEmployees ==&gt;", lstEmployees);

        //Ordenas Empleados con Lambda Expresion
        Collections.sort(lstEmployees, (x, y) -&gt; x.getName().compareToIgnoreCase(y.getName()));
        printList("lstEmployees Lambda ==&gt;", lstEmployees);
    }

    private static void printList(String title, List list) {
        System.out.println(title);
        list.forEach(x -&gt; System.out.println("\t" + x.toString()));
        System.out.println("");
    }

    private static List&lt;Employee&gt; getEmployeeList() {
        List&lt;Employee&gt; employees = new ArrayList&lt;&gt;();
        for (String name : NAMES) {
            employees.add(new Employee(name));
        }
        return employees;
    }

    private static List&lt;SortEmployee&gt; getSorteableEmployeeList() {
        List&lt;SortEmployee&gt; employees = new ArrayList&lt;&gt;();
        for (String name : NAMES) {
            employees.add(new SortEmployee(name));
        }
        return employees;
    }
}</pre>
<p>La siguiente clase representa un empleado que no está preparado para ser ordenado:</p>
<pre class="tab-convert:true lang:java decode:true">package com.osb.sortlist;

/**
 * @author Oscar Blancarte &lt;oscarblancarte3@gmail.com&gt;
 */
public class Employee {
    private String name;
    
    public Employee(){
    }

    public Employee(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return name;
    }
}</pre>
<p>Este otro empleado si está preparado para ser ordenado:</p>
<pre class="tab-convert:true lang:java decode:true">package com.osb.sortlist;

/**
 * @author Oscar Blancarte &lt;oscarblancarte3@gmail.com&gt;
 */
public class SortEmployee implements Comparable&lt;SortEmployee&gt; {
    
    private String name;

    public SortEmployee( String name) {
        this.name = name;
    }

    @Override
    public int compareTo(SortEmployee employee1) {
        return this.name.compareToIgnoreCase(employee1.name);
    }

    @Override
    public String toString() {
        return name;
    }
}</pre>
<p>El resultado de la ejecución del proyecto nos da el siguiente resultado:</p>
<pre class="tab-convert:true lang:java decode:true">lstSortEmployess ==&gt;
    Alfredo Alvarado
    Gabriel German
    Juan Perez
    Liliana Castro
    Manuel Orozco
    Oscar Blancarte
    Rebeca Hernandez
    Samuel Alvarez
    Sofia Galindo

lstEmployees ==&gt;
    Alfredo Alvarado
    Gabriel German
    Juan Perez
    Liliana Castro
    Manuel Orozco
    Oscar Blancarte
    Rebeca Hernandez
    Samuel Alvarez
    Sofia Galindo

lstEmployees Lambda ==&gt;
    Alfredo Alvarado
    Gabriel German
    Juan Perez
    Liliana Castro
    Manuel Orozco
    Oscar Blancarte
    Rebeca Hernandez
    Samuel Alvarez
    Sofia Galindo</pre>
<p>Como puedes ver, estamos realizando tres ordenamientos, el primero es con una lista de <span class="lang:java decode:true crayon-inline ">SortEmployee</span>, el segundo ordenamiento es con una lista de <span class="lang:java decode:true crayon-inline ">Employee</span>, y la tercera es utilizando lamba expresión.</p>
<p><figure id="attachment_3213" aria-describedby="caption-attachment-3213" style="width: 800px" class="wp-caption aligncenter"><a href="https://codmind.com/courses/java"><img loading="lazy" class="wp-image-3213 size-full" src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/java-core-banner-3-md.jpg" alt="" width="800" height="450" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/java-core-banner-3-md.jpg 800w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/java-core-banner-3-md-300x169.jpg 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/java-core-banner-3-md-768x432.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption id="caption-attachment-3213" class="wp-caption-text">Te invito a que veas mi curso de Java Core, en el cual enseñamos Java desde cero con las mejores prácticas y un proyecto final.</figcaption></figure></p>
<p>Espero que esta explicación sea lo suficientemente clara como para aclarar cualquier duda que tuvieras, pero si no es así, recuerda que puedes escribirme en los comentarios y con gusto te responderé.</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2017/02/28/ordenar-listas-en-java/">Ordenar Listas en Java</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2017/02/28/ordenar-listas-en-java/feed/</wfw:commentRss>
			<slash:comments>14</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1451</post-id>	</item>
		<item>
		<title>Java 8 – Métodos referenciados</title>
		<link>https://www.oscarblancarteblog.com/2017/02/27/java-8-metodos-referenciados/</link>
					<comments>https://www.oscarblancarteblog.com/2017/02/27/java-8-metodos-referenciados/#respond</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Mon, 27 Feb 2017 09:00:06 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[java8]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=1439</guid>

					<description><![CDATA[<p>Los métodos referenciados son una de las nuevas características de Java 8 que nos permite hacer referencia a los métodos y constructores por medio de una interface funcional, dicho de otra manera, podemos implementar la funcionalidad de un método abstracto por medio de la implementación de un método ya implementado, asignando el método implementado al [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2017/02/27/java-8-metodos-referenciados/">Java 8 – Métodos referenciados</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="aligncenter wp-image-1548" src="https://www.oscarblancarteblog.com/wp-content/uploads/2017/02/Referencia-métodos.jpg" alt="métodos referenciados" width="768" height="431" />Los métodos referenciados son una de las nuevas características de Java 8 que nos permite hacer referencia a los métodos y constructores por medio de una <a href="https://www.oscarblancarteblog.com/2016/12/08/java-8-interfaces-funcionales/">interface funcional</a>, dicho de otra manera, podemos implementar la funcionalidad de un método abstracto por medio de la implementación de un método ya implementado, asignando el método implementado al método abstracto. Esto puede resultar un tanto extraño, sobre todo porque Java era, hasta la versión 8 un lenguaje demasiado estricto.<span id="more-1439"></span></p>
<p>La siguiente imagen muestra más claro cómo funciona la referencia a métodos:</p>
<p><img loading="lazy" class="aligncenter wp-image-1441" src="https://www.oscarblancarteblog.com/wp-content/uploads/2017/02/1-1.png" alt="Métodos referenciados" width="670" height="341" /></p>
<p>En la imagen podemos ver una <a href="https://www.oscarblancarteblog.com/2016/12/08/java-8-interfaces-funcionales/">interface funcional</a>, la cual define un método abstracto, por otro lado, tenemos una clase Custom, la cual define un método implementado, este método tiene un cuerpo y una funcionalidad previamente implementada. Sabemos que el método abstracto de la interface funcional no tiene implementada una funcionalidad, pues es una interface, y queremos que el método abstracto haga referencia al método de la clase Custom, por lo cual “asignamos” o referenciamos el método de la clase custom por medio del método de la interface funcional. Para que un método pueda ser referenciado debe de coincidir los parámetros y el retorno de la interface funcional con el del método que queremos referenciar, por lo tanto, el nombre del método no importaría.<br />
¿Pero cómo funciona esto?<br />
Cuando referenciamos un método, lo que pasa es que la funcionalidad del método original es implementada con una referencia al método referenciado, esto quieres decir que cuando ejecutemos el método de la interface funcional, en realidad lo que pasara es que se ejecutara el método de la otra clase.</p>
<h2>Tipos de métodos referenciados:</h2>
<p>• Referencia a un método estático<br />
• Referencia a un método de un objeto<br />
• Referencia a un método de un objeto arbitrario<br />
• Referencia a un constructor</p>
<p>Antes de explicarlos, me gustaría que vieras el código, trates de familiarizarte con las clases para después entrar en la explicación. El código completo lo puedes encontrar GitHub: <a href="https://github.com/oscarjb1/MethodReferences.git">https://github.com/oscarjb1/MethodReferences.git</a></p>
<p>La siguiente clase es un Interface Funcional debidamente anotada con <span class="lang:java decode:true crayon-inline">@FunctionalInterface</span> , Esta interface la cual utilizaremos como base para referenciar los métodos.</p>
<pre class="lang:java decode:true" title="Hello.java">package com.osb.referencedmethod;

/**
* @author Oscar Blancarte &lt;oscarblancarte3@gmail.com&gt;
*/
@FunctionalInterface
public interface IHello {
public void sayHello();
}</pre>
<p>La siguiente clase será utilizada para referencias a su constructor.</p>
<pre class="lang:java decode:true" title="Hello.java">package com.osb.referencedmethod;

/**
* @author Oscar Blancarte &lt;oscarblancarte3@gmail.com&gt;
*/
public class Hello implements IHello {

private String helloMessage;

public Hello() {
System.out.println("Hey!!! i'am a constructor");
}

public void createHello(String helloMessage) {
this.helloMessage = helloMessage;
}

@Override
public void sayHello() {
System.out.println(this.helloMessage);
}
}</pre>
<p>La siguiente clase tiene el contenido más importante de este artículo, en ella veremos los 4 tipos de referencias a métodos.</p>
<pre class="lang:java decode:true" title="Hello.java">package com.osb.referencedmethod;

import com.osb.referencedmethod.IHello;
import java.util.Arrays;

/**
* @author Oscar Blancarte &lt;oscarblancarte3@gmail.com&gt;
*/
public class Methods {
public static void sayStaticHello() {
System.out.println("Hey!!! i'am a static hello!");
}

public void sayInstanceHello() {
System.out.println("Hey!!! i'am a instance hello");
}

public static void main(String[] args) {
//Referencia a un método estatico
IHello staticRef = Methods::sayStaticHello;
staticRef.sayHello();

//Referencia a un método de un objeto
Methods methods = new Methods();
IHello instanceRef = methods::sayInstanceHello;
instanceRef.sayHello();

//Referencia a un método de un objeto arbitrario
String[] names = new String[]{"Oscar", "Alex", "Maria", "Samuel", "Perla", "Fausto"};
Arrays.sort(names, String::compareToIgnoreCase);
System.out.println("Hey!!! i'am a ordered array " + Arrays.toString(names));

//Referencia a un constructor
IHello hello = Hello::new;
hello.sayHello();
}
}</pre>
<p>Una vez, analizadas las clases pasaremos explicar, pero antes, me gustaría que vieras el resultado de la ejecución del proyecto:</p>
<pre class="">Hey!!! i'am a static hello!
Hey!!! i'am a instance hello
Hey!!! i'am a ordered array [Alex, Fausto, Maria, Oscar, Perla, Samuel]
Hey!!! i'am a constructor</pre>
<p>¡Impresionante no!!!, ¿esperabas este resultado? Si es así, entonces quieres decir que ya estas más familiarizado con Java 8 y las expresiones lambda, pero si no es así, no importa, porque a continuación explicaremos lo que está pasando. Para hacer esta explicación más simple, asumiremos que ya conocemos que son las interfaces funcionales, si no es así, aquí explico cómo. Pues bien, iniciaremos con las referencias a los métodos estáticos, para lo cual regresaremos a las líneas 20-21, observemos que estamos creando la variable <span class="lang:java decode:true crayon-inline">staticRef</span>, la cual es de tipo <span class="lang:java decode:true crayon-inline">IHello</span> (Recordemos que IHello es una interface funcional), pero al asignarle valor a la variable, no lo hacemos con un <span class="lang:java decode:true crayon-inline">new</span>, si no que indicamos que la interface funcional se debe implementar con el método <span class="lang:java decode:true crayon-inline">sayStaticHello</span> el cual está definido en la clase <span class="lang:java decode:true crayon-inline">Methods</span>, para hacer la referencia al método <span class="lang:java decode:true crayon-inline">sayStaticHello</span> de la clase <span class="lang:java decode:true crayon-inline">Methods</span>. Para hacer la referencia se utiliza <span class="lang:java decode:true crayon-inline">::</span> (Cuadro puntos o dos dobles punto). Al ejecutar el método en la línea 21, vemos que se imprime <em>“Hey!!! i&#8217;am a static hello!”</em>.<br />
La otra forma de implementar las referencias es por medio de los métodos a un objeto en particular como en las líneas 24-26, en la cual vemos que primero instanciamos la clase <span class="lang:java decode:true crayon-inline">Methods</span>, luego volvemos a utilizar <span class="lang:java decode:true crayon-inline">::</span> para hacer referencia al método <span class="lang:java decode:true crayon-inline">sayInstanceHello</span>, observa que esta vez utilizamos el objeto en lugar de la clase, ya que este método no es <span class="lang:java decode:true crayon-inline">static</span>. Al ejecutar el método se imprimirá <em>“Hey!!! i&#8217;am a instance hello”</em>.<br />
Otra de las formas de implementar la referencia a métodos es por medio de un objeto arbitrario. Se dice arbitrario, porque en realidad no sabes sobre que objeto vamos hacer la referencia, pero si sabes el tipo de datos, por lo tanto, podemos asumir los métodos que tiene para referenciarlos. Un ejemplo de esto está en las líneas 29-31. Veamos lo que vamos a hacer, tenemos un Array de Strings el cual tiene una serie de nombre que queremos ordenar, para lo cual vamos a utilizar la clase <span class="lang:java decode:true crayon-inline">Arrays</span>, esta clase nos permite ordenar Objetos que implementen la interface <span class="lang:java decode:true crayon-inline">Comparator</span>, esta interface es una interface funcional debido a que solo tiene el método <span class="lang:java decode:true crayon-inline">public int compareTo(T o)</span>, por lo que podríamos mandar una referencia a un método que pueda implementarla, en este caso veamos que al método <span class="lang:java decode:true crayon-inline">sort</span> le mandamos el array de nombre y una referencia al método <span class="lang:java decode:true crayon-inline">compareToIgnoreCase</span> el cual tiene la siguiente definición <span class="lang:java decode:true crayon-inline">public int compareToIgnoreCase(String str)</span>, veamos que tanto <span class="lang:java decode:true crayon-inline">compareTo</span> y <span class="lang:java decode:true crayon-inline">compareToIgnoreCase</span> reciben el <span class="lang:java decode:true crayon-inline">String</span> a comprar y los dos regresan un <span class="lang:java decode:true crayon-inline">int</span>, por lo tanto la referencia a métodos es compatible. Lo que pasa entonces en la línea 30, es que la lista será iterada, y por cada String, llamará a su método <span class="lang:java decode:true crayon-inline">compareToIgnoreCase</span>, notemos algo muy importante…. La instrucción <span class="lang:java decode:true crayon-inline">String::compareToIgnoreCase</span>, no es una referencia a un método estático como podríamos creer, en su lugar, como sabemos que es una lista de String, le estamos diciendo que de cada String que está en la lista, use su método <span class="lang:java decode:true crayon-inline">compareToIgnoreCase</span> para comprar el siguiente elemento de la lista. Es por eso que se llama referencia a métodos de objetos arbitrario, porque conocemos el tipo de datos, pero no el objeto concreto. Al imprimir la lista, veremos una lista correctamente ordenada: <em>“Hey!!! i&#8217;am a ordered array [Alex, Fausto, Maria, Oscar, Perla, Samuel]”</em></p>
<p><figure id="attachment_3207" aria-describedby="caption-attachment-3207" style="width: 800px" class="wp-caption aligncenter"><a href="https://codmind.com/courses/java-lambda"><img loading="lazy" class="wp-image-3207 size-full" src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/banner-md.jpg" alt="Curso de Java Lambdas + Streams" width="800" height="450" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/banner-md.jpg 800w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/banner-md-300x169.jpg 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/banner-md-768x432.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption id="caption-attachment-3207" class="wp-caption-text">Te invitamos a ver nuestro curso de Java Lambdas + Streams para aprender a programar con el nuevos paradigma funcional.</figcaption></figure></p>
<p>Finalmente, tenemos la referencia a constructores, la cual nos permitirá asignar la referencia de un constructor a el método de la interface funcional, de tal forma que cuando ejecutemos el método, este en realidad llamará al constructor de la clase referenciada. Como vemos en las líneas 34-35, estamos haciendo referencia al constructor mediante los <span class="lang:java decode:true crayon-inline">::</span> (cuatro puntos) seguido del operador <span class="lang:java decode:true crayon-inline">new</span>, así de fácil. Finalmente cuando ejecutemos el método <span class="lang:java decode:true crayon-inline">sayHello</span>, este en realidad llamará al constructor de la clase <span class="lang:java decode:true crayon-inline">Hello</span> y se imprimirá en pantalla: <em>“Hey!!! i&#8217;am a constructor”</em>. Recordemos que las clases pueden tener más de un constructor, ¿entonces como sabe Java a que constructor llamar?, pues es fácil, llamará al que tenga compatibilidad con los parámetros de la interface funcional. Como en este caso, el método <span class="lang:java decode:true crayon-inline">sayHello</span>, no recibe parámetros, entonces se llama al constructor sin parámetros de la clase <span class="lang:java decode:true crayon-inline">Hello</span>. Por otra parte, si el método recibiera un <span class="lang:java decode:true crayon-inline">String</span>, entonces llamaría al constructor que recibe un solo parámetro. ¡Así de fácil!</p>
<h2>Conclusiones:</h2>
<p>Desde mi punto de vista, los métodos y constructores referenciados fueron de las cosas más extrañas que me parecieron del Java 8, pues al inicio no lograba entender cómo funcionaba a la perfección, sobre todo la referencia a métodos de un objeto arbitrario, pero la verdad es que es solo práctica, tenemos que descargar el código y probar, modificar las clases y probar de nuevo. Si no experimentamos se nos hará muy difícil entenderlas, pero más a un recordarlas cuando las necesitemos.<br />
Como verás esta fue una guía rápida de los métodos referenciados, pero si tienes dudas, déjamelas en los comentarios y con gusto las resolveré. Recuerda que puedes descargar el código y a practicar.</p>
<p>Si estas interesado en seguir aprendiendo más de las mejoras de Java 8 te dejo este <a href="https://www.oscarblancarteblog.com/tag/java8/">Enlace</a> donde están todos los artículos que he escrito sobre Java 8</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2017/02/27/java-8-metodos-referenciados/">Java 8 – Métodos referenciados</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2017/02/27/java-8-metodos-referenciados/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1439</post-id>	</item>
		<item>
		<title>WebSocket con Java</title>
		<link>https://www.oscarblancarteblog.com/2017/02/23/websocket-con-java/</link>
					<comments>https://www.oscarblancarteblog.com/2017/02/23/websocket-con-java/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Thu, 23 Feb 2017 10:00:41 +0000</pubDate>
				<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaEE]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[WebSocket]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=1427</guid>

					<description><![CDATA[<p>En este artículo aprenderemos a implementar WebSocket con Java, ya que en el pasado ya había dado una completa Introducción a los WebSocket y explicamos que estos fueron introducidos como una mejora en HTML5, pero también dijimos que los WebSocket son ejecutados por el navegador, y estos requieren de dos partes, un WebSocket cliente (Navegador) [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2017/02/23/websocket-con-java/">WebSocket con Java</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="alignleft wp-image-594 size-thumbnail" src="https://www.oscarblancarteblog.com/wp-content/uploads/2014/07/google-oracle-java1-150x150.jpg" alt="WebSockets con Java" width="150" height="150" />En este artículo aprenderemos a implementar WebSocket con Java, ya que en el pasado ya había dado una completa <a href="https://www.oscarblancarteblog.com/2017/02/20/introduccion-a-lo-websocket/">Introducción a los WebSocket</a> y explicamos que estos fueron introducidos como una mejora en HTML5, pero también dijimos que los WebSocket son ejecutados por el navegador, y estos requieren de dos partes, un WebSocket cliente (Navegador) y un WebSocket Server (Backend). Pues bien, ya habíamos platicado como es que los WebSocket funcionan del lado del navegador, es por eso que ahora hablaremos de la otra cara, los WebSocket Server.</p>
<p>Como el título de este articulo lo dice, hablaremos de cómo implementar los WebSocket utilizado Java como BackEnd, pero cabe mencionar que todos los lenguajes de programación deberían de tener sus propias API’s para soportar conexiones del lado del servidor.  Los WebSocket fueron agregados a apartar de la versión Java EE 7 bajo la especificación JSR 356, es por ello que todos los Application Server certificados para Java EE 7 deberán de tener una implementación estándar de dicha especificación. Basta de charla y pasemos a cómo implementar un WebSocket con Java.</p>
<h2>Implementando un WebSocket con Java</h2>
<p>Para explicar cómo funcionan los WebSocket vamos a implementar un ejemplo muy simple, crearemos una barra de progreso la cual se cargará del valor 0 al 100 simulando que un proceso se está ejecutando en el BackEnd. En el formulario tendremos un botón que iniciara el proceso, cuando el usuario presione el botón, enviaremos un mensaje al BackEnd por medio del WebSocket, en ese momento, el BackEnd iniciara con un proceso de notificaciones el cual enviará por medio del WebSocket un mensaje con las actualizaciones de la barra de progreso. Este ejemplo está desarrollado con Java 8 y Wildfly 9.0.</p>
<p><img loading="lazy" class="aligncenter wp-image-1429" src="https://www.oscarblancarteblog.com/wp-content/uploads/2017/02/WebSocket.gif" alt="WebSocket con Java" width="563" height="226" /><span id="more-1427"></span></p>
<p>Este ejemplo está compuesto de 4 archivos:</p>
<ul>
<li><strong>html:</strong> página principal del proyecto, sobre la que mostraremos la barra de progreso.</li>
<li><strong>js:</strong> Archivo de JavaScript en donde está programado el WebSocket y el procesamiento de los mensajes de envío y recepción.</li>
<li><strong>css:</strong> archivo de clases de estilo (opcional).</li>
<li><strong>java</strong>: Clase donde implementamos el WebSocket Server con Java, esta se ejecuta del lado del servidor.</li>
</ul>
<p><img loading="lazy" class="aligncenter wp-image-1430" src="https://www.oscarblancarteblog.com/wp-content/uploads/2017/02/WebSocket-con-Java.png" alt="WebSocket con Java" width="683" height="303" /></p>
<p>Todo el código del proyecto lo puedes descargar de GitHub: <a href="https://github.com/oscarjb1/ProgressWebSocket.git">https://github.com/oscarjb1/ProgressWebSocket.git</a></p>
<h2>Index.html</h2>
<p>Primero que nada, veremos el documento index.html para entender como esta armada la pantalla:</p>
<pre class="lang:xhtml decode:true" title="index.hml">&lt;!DOCTYPE html&gt;
&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt;WebSocket Progress&lt;/title&gt;
        &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
        &lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;
        &lt;script type="text/javascript"src="websocket.js"/&gt;&lt;/script&gt;
        &lt;link rel="stylesheet" type="text/css" href="styles.css"&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;section  class="container"&gt;
        &lt;h1&gt;WebSocket Progress&lt;/h1&gt;
        &lt;div&gt;
            &lt;div class="progress-container"&gt;
                &lt;form id="form"&gt;
                    &lt;input id="btnSubmit" type="button" value="start" onclick="formSubmit();"/&gt;
                    &lt;progress id="progress" value="0" max="100"&gt;&lt;/progress&gt;
                    &lt;label for="progress" id="lblProgress"&gt;&lt;/label&gt;
                &lt;/form&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/section&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Lo primero que hacemos en el Header es importar al archivo <span class="lang:java decode:true crayon-inline">styles.css</span> del cual no hay mucho que decir, salvo que es utilizado para darle una apariencia más agradable a la página, y el archivo <span class="lang:java decode:true crayon-inline">websocket.js</span> del cual hablaremos más adelante.</p>
<p>El siguiente punto importante es el formulario, en el definimos un botón que al presionarlo ejecutara la función <span class="lang:java decode:true crayon-inline">formSubmit()</span> que está definido en el archivo <span class="lang:java decode:true crayon-inline">websocket.js</span>, que iniciara con el proceso de carga del progress bar.</p>
<p>También tenemos un progress, el cual será actualizado a medida que el WebSocket reciba las notificaciones del BackEnd, para lo cual utilizaremos el ID (progress) para identificarlo más adelante. Finalmente, debajo del progress tenemos un label el cual será actualizado con el progreso del progress bar.</p>
<p>Tanto el progress como el label son actualizados por Javascript a medida que el servidor manda los datos por medio del WebSocket.</p>
<h2>Websocket.js</h2>
<p>Por su nombre, podríamos pensar que se trata de una librería o algún script ya desarrollado, pero la realidad es que es un Script totalmente custom y desarrollado a la medida para esta solución.</p>
<pre class="lang:js decode:true " title="websocket.js">var socket = new WebSocket("ws://localhost:8080/ProgressWebSocket-1.0-SNAPSHOT/progress");
socket.onmessage = onMessage;

function onMessage(event) {
    var btnSubmit = document.getElementById("btnSubmit");
    btnSubmit.disabled = true;
    
    var progress = document.getElementById("progress");
    var data = JSON.parse(event.data);
    progress.value = data.value;
    
    var lblProgress = document.getElementById("lblProgress");
    if(data.value &lt; 100){
        lblProgress.innerHTML = 'Progress: ' + data.value + '%';
    }else{
        btnSubmit.disabled = false;
        lblProgress.innerHTML = "Finish";
    }
    
}

function formSubmit() {
    socket.send("{\"start\":\"true\"}");
}</pre>
<p>La primera línea es la más importante, pues en esta se establece la conexión con el servidor, la clase WebSocket es una clase estándar que nos permitirá comunicarnos con el Servidor de una forma simple, esta clase tiene como parámetro la URL sobre la cual escucha el BackEnd, más adelante veremos cómo está formada esta URL, por lo pronto asumamos que existe un WebSocket Server que está escuchando.</p>
<p>En la línea 2 definimos la función que procesara los mensajes entrantes, es decir, cuando el BackEnd envíe un mensaje al navegador, este lo atenderá por medio del método definido, en este caso, establecemos el método <span class="lang:java decode:true crayon-inline">onMessage</span> para procesar los mensajes entrantes.</p>
<p>En la línea 4 definimos el método <span class="lang:java decode:true crayon-inline">onMessage</span> el cual implementa toda la lógica de procesamiento de los mensajes entrantes, el parámetro <span class="lang:java decode:true crayon-inline">event</span> corresponde al evento recibido y mediante event.data es posible recuperar el mensaje que envió el Servidor. Veamos qué es lo que hace. Primero que nada, en las líneas 5-6 obtenemos la referencia el botón y lo deshabilitamos para impedir que se presione mientras esta en procesamiento. En la línea 8 convertimos el mensaje enviado por el Server en un Json para poderlo procesar. En las líneas 10-11 obtenemos una referencia al progress y actualizamos el valor de la barra de progreso, para lo cual establecemos la propiedad value por el valor enviado por el Servidor. En las líneas 13-19 establecemos el valor del label, indicando el progreso recibido por el servidor, en caso de finalizar (100%), la etiqueta cambia a Finish y el botón se habilitado nuevamente.</p>
<p>Finalmente, en las últimas líneas, tenemos el método <span class="lang:java decode:true crayon-inline">formSubmit</span>, el cual es ejecutado por el botón cuando es presionado, este método manda un mensaje dummy al servidor mediante el método send del WebSocket.</p>
<h2>ServerDashboardWebSocket.java</h2>
<p>Esta es la parte principal para implementar un WebSocket con Java, ya que desde aquí es de donde se aceptan las conexiones del navegador y se procesan los mensajes de envío y recepción.</p>
<pre class="lang:java decode:true" title="ServerDashboardWebSocket.java">package com.osb.progresswebsocket.socket;

import java.util.HashSet;
import java.util.Set;
import javax.enterprise.context.ApplicationScoped;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

/**
 * @author Oscar Blancarte &lt;oscarblancarte3@gmail.com&gt;
 */
@ApplicationScoped
@ServerEndpoint("/progress")
public class ServerDashboardWebSocket {

    private Set&lt;Session&gt; sessions = new HashSet&lt;&gt;();

    @OnOpen
    public void open(Session session) {
        System.out.println("Session opened ==&gt;");
        sessions.add(session);
    }

    @OnMessage
    public void handleMessage(String message, Session session) {
        System.out.println("new message ==&gt; " + message);
        try {
            for (int c = 0; c &lt; 100; c++) {
                for (Session s : sessions) {
                    s.getBasicRemote().sendText("{\"value\" : \"" + (c + 1) + "\"}");
                }
                Thread.sleep(100);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }

    @OnClose
    public void close(Session session) {
        System.out.println("Session closed ==&gt;");
        sessions.remove(session);
    }

    @OnError
    public void onError(Throwable e) {
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}</pre>
<p>Primero que nada, observemos que esta es una clase común y corriente, no extiende ni implementa ninguna clase, sin embargo, esta anotada con <span class="lang:java decode:true crayon-inline">@ApplicationScope</span> y <span class="lang:java decode:true crayon-inline">@ServerEndpoint</span>. Si ya has trabajado con JavaEE es muy probable que conozcas la primera, la cual no pertenece al API de WebSocket, pero es utilizada para crear un Bean disponible durante toda la vida de la aplicación. La segunda, <span class="lang:java decode:true crayon-inline">@ServerEndpoint</span> es en la que debemos de poner atención, con tan solo marcar una clase con ella, le estamos diciendo al Application Server que esta se trata de un WebSocket Server el cual estará escuchando en la URL <strong>http://&lt;HOST&gt;:&lt;PORT&gt;/&lt;APPLICATION&gt;/progress</strong>, la última parte de la url (/progress) es la que definimos en la anotación <span class="lang:java decode:true crayon-inline">@ServerEndpoint</span> por lo que tenemos que tener cuidado de que coincida con la URL que definimos en el archivo <span class="lang:java decode:true crayon-inline">websocket.js</span>.</p>
<p>También podemos ver que tenemos una Set de <span class="lang:java decode:true crayon-inline">Session</span>. Las Session son objetos que representan las conexiones de los navegadores, por lo que tendremos un Set para no perder la referencia a todas las conexiones.</p>
<p>A continuación, veremos una serie de métodos anotados, estas anotaciones le dicen a Application Server que método debe de ejecutar ante cualquier evento. Veamos los diferentes métodos.</p>
<p><strong>Método open</strong>, está marcado con la anotación <span class="lang:java decode:true crayon-inline">@OnOpen</span> y se ejecutara cada vez que una nueva conexión se establezca con el servidor, el parámetro Session representa la conexión y la almacenamos en el Set de sesiones.</p>
<p><strong>Método close</strong>, esta anotado con <span class="lang:java decode:true crayon-inline">@OnClose</span> y se ejecutara cada vez que una sesión se desconecte. Recibe el objeto Session que se desconectó para poder identificarla.</p>
<p><strong>Método onError</strong>, esta anotado con <span class="lang:java decode:true crayon-inline">@OnError</span>, y se ejecutara ante cualquier error, el error es enviado como parámetro.</p>
<p><strong>Método handleMessage</strong>, anotado con <span class="lang:java decode:true crayon-inline">@OnMessage</span>, será ejecutado cada vez que llegue un nuevo mensaje de alguno de los navegadores. Este recibe como parámetro el mensaje enviado y el objeto Session que mando el mensaje. Este es el método más importante en nuestro ejemplo, porque una vez recibido un mensaje, iniciara una serie de envíos de mensajes al navegador. Observemos que haremos un ciclo del 1 al 100 y en cada interación enviaremos al Navegador un mensaje con el progreso, al finalizar cada interación, dormiremos el hilo 100 milisegundos para apreciar mejor como se llena la barra. Utilizamos el método <span class="lang:java decode:true crayon-inline">getBasicRemote()</span> para que nos regrese una implementación de envío asíncrono y seguido ejecutamos el método <span class="lang:java decode:true crayon-inline">sendText</span>, el cual se utiliza para mandar un mensaje de texto al navegador.</p>
<p><figure id="attachment_3146" aria-describedby="caption-attachment-3146" style="width: 800px" class="wp-caption aligncenter"><a href="https://codmind.com/courses/api-rest-con-spring-boot"><img loading="lazy" class="wp-image-3146 size-full" src="https://www.oscarblancarteblog.com/wp-content/uploads/2019/08/banner-lg.jpg" alt="Curso Mastering API REST con Spring boot" width="800" height="450" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2019/08/banner-lg.jpg 800w, https://www.oscarblancarteblog.com/wp-content/uploads/2019/08/banner-lg-300x169.jpg 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2019/08/banner-lg-768x432.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption id="caption-attachment-3146" class="wp-caption-text">Te invito a que veas mi curso Mastering API REST con Spring Boot</figcaption></figure></p>
<h2>Resumen:</h2>
<p>Repasemos como funciona todo, cuando entramos a la página, esta carga el archivo <span class="lang:java decode:true crayon-inline">websocket.js</span> y establece conexión inmediata con el Servidor, en este momento el método open de la clase <span class="lang:java decode:true crayon-inline">ServerDashboardWebSocket.java</span> es ejecutado para recibir la nueva sesión. Seguido, el usuario presiona el botón start y envía mediante el función <span class="lang:java decode:true crayon-inline">websocket.send</span> un mensaje al Servidor, el Servidor recibe el mensaje mediante el método <span class="lang:java decode:true crayon-inline">handleMessage</span> de la clase <span class="lang:java decode:true crayon-inline">ServerDashboardWebSocket.java</span>, el cual envía una serie de mensaje como respuesta al navegador, por su parte, el navegador procesa los mensajes entrantes mediante la función <span class="lang:java decode:true crayon-inline">onMessage</span> de JavaScript, en esta función se actualiza la barra de progreso.</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2017/02/23/websocket-con-java/">WebSocket con Java</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2017/02/23/websocket-con-java/feed/</wfw:commentRss>
			<slash:comments>22</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1427</post-id>	</item>
		<item>
		<title>Entity Manager &#038; Persistence Context</title>
		<link>https://www.oscarblancarteblog.com/2017/02/21/entitymanager-persistencecontext/</link>
					<comments>https://www.oscarblancarteblog.com/2017/02/21/entitymanager-persistencecontext/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Tue, 21 Feb 2017 12:33:40 +0000</pubDate>
				<category><![CDATA[JPA]]></category>
		<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[java]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=1392</guid>

					<description><![CDATA[<p>Hasta el momento solo hemos trabajado con el Entity Manager para realizar las operaciones básicas, pero existen detalles más finos que es necesario entender para convertirnos en expertos de JPA. Cuando trabajamos con JPA es común interactuar con el Entity Manager, ¿pero que tanto sabemos acerca de los Persistence Context en realidad? &#160; Primero que [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2017/02/21/entitymanager-persistencecontext/">Entity Manager &#038; Persistence Context</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>				<img loading="lazy" class="size-full wp-image-603 alignleft" src="https://www.oscarblancarteblog.com/wp-content/uploads/2014/07/JPAHibernate1-e1477360564109.jpg" alt="Tutorial de JPA persistence.xml" width="150" height="83" />Hasta el momento solo hemos trabajado con el Entity Manager para realizar las operaciones básicas, pero existen detalles más finos que es necesario entender para convertirnos en expertos de JPA. Cuando trabajamos con JPA es común interactuar con el Entity Manager, ¿pero que tanto sabemos acerca de los Persistence Context en realidad?</p>
<p>&nbsp;</p>
<p>Primero que nada, tenemos que saber que el Persistence Context se crea mediante un Persistence Unit y el Entity Manager se crea a partir de un Persistence Context, veamos la siguiente imagen para entender mejor:</p>
<p><img loading="lazy" class="aligncenter size-full wp-image-1394" src="https://www.oscarblancarteblog.com/wp-content/uploads/2017/02/Persistence-Context.png" alt="persistence context" width="661" height="308" /></p>
<p>&nbsp;</p>
<p>Veamos que todo parte del archivo <a href="https://www.oscarblancarteblog.com/2016/10/26/entitymanager-archivo-persistence-xml/">persistence.xml</a> del cual ya hablamos anteriormente, en este archivo se definen los Persistence Unit, y mediante estos es creado el Persistence Context, el Persistence Context tiene la finalidad de delimitar el alcance de las transacciones, pero también está delimitado a administrar las Entidades definidas por el Persistence Unit con el que fue creado.  Adicionalmente, el Entity Manager hace referencia a un Persistence Context el cual será utilizado para administrar las entidades y las transacciones.<span id="more-1392"></span></p>
<p>&nbsp;</p>
<p>Una de las ventajas de tener varios Persistence Unit, es que nos permite definir diferentes configuraciones para cada uno, de esta manera podemos delimitar las entidades de cada módulo e incluso una configuración de base de datos diferentes para cada uno.</p>
<p>&nbsp;</p>
<h2>Container-Managed Entity Manager</h2>
<p>&nbsp;</p>
<p>Básicamente existen dos formas de trabajar con JPA, la más simple es cuando lo utilizamos en aplicaciones SE o de escritorio y la segunda forma que es la que estudiaremos en esta sección, es cuando lo utilizamos en ambientes de Java EE con EJB.</p>
<p>La principal característica de utilizar Entity Manager administrado por el contenedor, es que es el mismo Container el que se encarga de abrir y cerrar las transacciones, por lo que el programador solo se preocupa por implementar la lógica de negocio despreocupándose en la totalidad de las transacciones.</p>
<p>En ambientes Java EE se suele utilizar la anotación <span class="lang:java decode:true crayon-inline ">@PersistenceContext</span>  para crear el EntityManager, como veremos en el siguiente EJB.</p>
<p>&nbsp;</p>
<pre class="lang:java decode:true" title="EmployeeDAO.java">package com.obb.jpa.jpaturorial.entitymanager;

import javax.ejb.*;
import javax.persistence.*;

/**
 * @author Oscar Blancarte
 */
@EJB
@Stateless
public class EmployeeDAO implements IEmployeeDAO{

    @PersistenceContext(unitName = "JPA_PU")
    private EntityManager manager;
}</pre>
<p>&nbsp;</p>
<p>Cuando utilizamos la anotación <span class="lang:java decode:true crayon-inline ">@PersistenceContext</span>  el contenedor inyecta de forma automática una referencia válida del EntityManager creado a partir de la Persistence Unit <strong>JPA_PU</strong>, de esta forma, el programador podrá utilizar el EntityManager en cualquier método que defina, y las transacciones será administradas de forma automática.</p>
<p>&nbsp;</p>
<p>Ahora bien, existen dos variantes de los Container-Managed, Transaction-Scope y Extended, los cuales son utilizados en circunstancias diferentes. Para utilizar una variante o la otra, es necesario definirlo en la anotación <span class="lang:java decode:true crayon-inline ">@PersistenceContext</span> <strong> </strong>mediante la propiedad <strong>type</strong>. Los valores posibles son <span class="lang:java decode:true crayon-inline">TRANSACTION</span>  y <span class="lang:java decode:true crayon-inline ">EXTENDED</span>  como veremos a continuación:</p>
<p>&nbsp;</p>
<pre class="lang:java decode:true">@PersistenceContext(unitName = "JPA_PU", type = PersistenceContextType.TRANSACTION)
@PersistenceContext(unitName = "JPA_PU", type = PersistenceContextType.EXTENDED)</pre>
<p>&nbsp;</p>
<p>En caso de no definir la propiedad type, el valor por default será TRANSACTION, lo cual está bien, porque es por lejos la variante más utilizada.</p>
<p>&nbsp;</p>
<h3>Transaction-Scope</h3>
<p>&nbsp;</p>
<p>La variante Transaction-Scope es la variante utiliza por default, por lo que no es necesario definir la propiedad type para utilizarla. Esta variante tiene la particularidad de que el contexto de persistencia solo será válido durante le ejecución de la operación de negocio, una vez que la operación termine el contexto de persistencia se destruye y todas las entidades relacionadas con el Entity Manager será descartadas.</p>
<p>Este tipo de estrategias se utiliza para EJB sin estado como los <span class="lang:java decode:true crayon-inline">@Stateless</span>, pues cada invocación a una operación de negocio se espera que realice una acción, persista y retorne un resultado, y cada ejecución tendrá un contexto de persistencia diferente, garantizando de esta forma que el servicio siempre arroje el mismo resultado para la misma entrada.</p>
<p>Veamos un ejemplo de un servicio de creación de empleados:</p>
<p>&nbsp;</p>
<pre class="lang:java decode:true">package com.obb.jpa.jpaturorial.entitymanager;
import com.obb.jpa.jpaturorial.entity.Employee; 
import javax.ejb.*; 
import javax.persistence.*; 
/** 
* @author Oscar Blancarte 
*/ 
@EJB 
@Stateless 
public class EmployeeDAO implements IEmployeeDAO{ 
@PersistenceContext(unitName = "JPA_PU", type = PersistenceContextType.TRANSACTION) 
private EntityManager manager; 

@TransactionAttribute(TransactionAttributeType.NEVER) 
public Employee getEmployeeById(Long empId){ 
//Se consulta el empleado mediante el ID 
return manager.find(Employee.class, empId); 
} 

@TransactionAttribute(TransactionAttributeType.SUPPORTS) 
public void updateEmployeeName(Long empId, String newName){ 
//El empleado es nuevamente consultado de la base de datos 
//debido a que cada invocación es un nuevo contexto de persistencia 
Employee emp = manager.find(Employee.class, empId); 
emp.setName(newName); 
//Al termina el método, el contenedor realiza un Commit automático. 
} 
}</pre>
<p>&nbsp;</p>
<p>Imaginemos el siguiente escenario, tenemos una aplicación que carga el empleado en pantalla utilizando el método <span class="lang:java decode:true crayon-inline ">getEmployeeById</span>, esta consulta al empleado mediante el ID y lo retorna, la aplicación utiliza el empleado consultado para mostrarlo en pantalla, luego, modificamos el nombre del empleado y guardamos los cambios mediante el método <span class="lang:java decode:true crayon-inline ">updateEmployeeName</span>.</p>
<p>Lo primero que hace la aplicación es consultar el empleado, hasta aquí todo bien, pero cuando actualizamos el nombre del empleado, vemos que realizamos un find mediante el ID del empleado, podríamos pensar que como ya lo hemos consultado anteriormente mediante el método <span class="lang:java decode:true crayon-inline">getEmployeeById</span> este solo lo retomará del cache sin realizar una nueva consulta a la base de datos, sin embargo, Transaction-Scope garantiza que cada ejecución crea un nuevo PersistenceContext en blanco, por lo que el empleado que anteriormente ya habíamos consultado será nuevamente consultado, debido que en la segunda llamada al método <span class="lang:java decode:true crayon-inline ">updateemployeeName</span> el Persistence Context está en blanco.</p>
<p>&nbsp;</p>
<p>No te preocupes por las anotaciones <span class="lang:java decode:true crayon-inline ">@TransactionAttribute</span>, más adelante las explicaremos por ahora pasémoslas por alto.</p>
<p>&nbsp;</p>
<h3>Extended</h3>
<p>&nbsp;</p>
<p>La segunda variante es Extended, que como su nombre nos lo indica, se trata de un Contexto de Persistencia Extendido, donde el contexto persistirá durante todo el tiempo de vida de la sesión, sin importar el número de operaciones o transacciones que se realicen.</p>
<p>A diferencia de Transaction-Scope, en esta variante todos los cambios realizados en el Persistence Context seguirán vigentes, por lo que cada ejecución que realicemos se favorecerá de las ejecuciones pasadas.</p>
<p>Este tipo de variante es utilizada cuando trabajamos con EJB con sesión como el <span class="lang:java decode:true crayon-inline">@Stateful</span>, veamos el mismo ejemplo anterior pero esta vez utilizando un EJB con sesión y la variante Extended.</p>
<p>&nbsp;</p>
<pre class="lang:java decode:true " title="EmployeeExtendedDAO.java">package com.obb.jpa.jpaturorial.entitymanager;

import com.obb.jpa.jpaturorial.entity.Employee;
import javax.ejb.*;
import javax.persistence.*;

/**
 * @author Oscar Blancarte
 */
@EJB
@Stateful
public class EmployeeExtendedDAO implements IEmployeeDAO{
    
    @PersistenceContext(unitName = "JPA_PU", type = PersistenceContextType.EXTENDED)
    private EntityManager manager;
    
    @TransactionAttribute(TransactionAttributeType.NEVER)
    public Employee getEmployeeById(Long empId){
        //Se consulta el empleado mediante el ID
        return manager.find(Employee.class, empId);
    }
    
    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    public void updateEmployeeName(Long empId, String newName){
        //El empleado no es consultado, debido a que ya fue consultado previamente
        Employee emp = manager.find(Employee.class, empId);
        emp.setName(newName);
        //Al termina el método, el contenedor realiza un Commit automático.
        //Los camibios realizados seguiran estando disponibles
    }
}</pre>
<p>&nbsp;</p>
<p>En este caso las cosas son un poco diferentes. Primero que nada, se realiza la consulta del empleado mediante el método <span class="lang:java decode:true crayon-inline">getEmployeeById</span> y el empleado es retornado, cuando la ejecución del método termina, el Persistence Context continúa existiendo, por lo que cuando se realiza la actualización del nombre del empleado y se realiza la consulta del empleado, el Entity Manager ya no consulta al empleado, pues este ya fue consultado en el método anterior. Finalmente, el nombre es actualizado y al terminar el método se hace un commit de la transacción. Al finalizar el método el Contexto de persistencia continua activo hasta que la sesión finaliza.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>Application-Managed Entity Manager</h2>
<p>&nbsp;</p>
<p>La segunda forma de trabajar con JPA es delegar al programador la responsabilidad de administrar las transacciones, este escenario se da con mucha más frecuencia en aplicaciones de escritorio, aunque existen escenarios donde es utilizado en entornos de Java EE.</p>
<p>Básicamente el programador tiene que crear el <strong>EntityManager</strong> a través del <strong>EntityManagerFactory</strong> y tiene que abrir y cerrar las transacciones cada vez que requiera.</p>
<p>Veamos cómo quedaría el escenario anteriormente planteado utilizando application-managed:</p>
<pre class="lang:java decode:true " title="EmployeeApplicationDAO.java">package com.obb.jpa.jpaturorial.entitymanager;

import com.obb.jpa.jpaturorial.entity.Employee;
import javax.ejb.*;
import javax.persistence.*;

/**
* @author Oscar Blancarte
*/
public class EmployeeApplicationDAO {

private EntityManager manager;

public EmployeeApplicationDAO() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPA_PU");
manager = emf.createEntityManager();
}

public Employee getEmployeeById(Long empId) {
return manager.find(Employee.class, empId);
}

public void updateEmployeeName(Long empId, String newName) {
//Se abre la transacción manualmente
manager.getTransaction().begin();
Employee emp = manager.find(Employee.class, empId);
emp.setName(newName);
//Se cierra la transacción manulamente
manager.getTransaction().commit();
}
}</pre>
<p>Podemos apreciar que el constructor de la clase estamos creando manualmente el EntityManager en lugar de simplemente inyectarlo como el Container-Managed, la otra diferencia es en el método <span class="lang:java decode:true crayon-inline">updateEmployeeName</span>, ya que para poder persistir los cabios tenemos que abrir y cerrar la transacción con los métodos <strong>beign</strong> y <strong>commit</strong>.</p>
<p>&nbsp;</p>
<p><center><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="https://www.oscarblancarteblog.com/2016/12/12/operaciones-basicas/">Anterior</a><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="http://www.oscarblancarteblog.com/tutoriales/java-persistence-api-jpa/">Índice</a><a class="btn btn-default read-more " style="display: inline-block; float: none; margin-right: 15px;" href="https://www.oscarblancarteblog.com/2016/12/20/introduccion-java-transaction-api-jta/">Siguiente </a></center>		</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2017/02/21/entitymanager-persistencecontext/">Entity Manager &#038; Persistence Context</a> appeared first on <a rel="nofollow" href="https://www.oscarblancarteblog.com">Oscar Blancarte - Software Architecture</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.oscarblancarteblog.com/2017/02/21/entitymanager-persistencecontext/feed/</wfw:commentRss>
			<slash:comments>15</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1392</post-id>	</item>
	</channel>
</rss>
