<?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/category/java/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.oscarblancarteblog.com</link>
	<description>Software Architect &#38; FullStack developer</description>
	<lastBuildDate>Thu, 13 Aug 2020 05:29:35 +0000</lastBuildDate>
	<language>es-MX</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.5.17</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>Spring boot – Inyectar propiedades con @Value</title>
		<link>https://www.oscarblancarteblog.com/2020/08/13/spring-boot-inyectar-propiedades-con-value/</link>
					<comments>https://www.oscarblancarteblog.com/2020/08/13/spring-boot-inyectar-propiedades-con-value/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Thu, 13 Aug 2020 05:14:03 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[spring boot]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=3227</guid>

					<description><![CDATA[<p>La anotación @Value permite inyectar propiedades del archivo application.properties</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2020/08/13/spring-boot-inyectar-propiedades-con-value/">Spring boot – Inyectar propiedades con @Value</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="925" height="518" src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/inyección-de-propiedades-con-@value.jpg" alt="@Value de Spring boot" class="wp-image-3229" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/inyección-de-propiedades-con-@value.jpg 925w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/inyección-de-propiedades-con-@value-300x168.jpg 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/08/inyección-de-propiedades-con-@value-768x430.jpg 768w" sizes="(max-width: 925px) 100vw, 925px" /></figure>



<p>La configuración es una de las partes más importantes de cualquier aplicación, pues permite que se pueda configurar según el entorno de ejecución o el ambiente en el que se desplegará, por suerte Spring boot cuenta con el archivo <code>application.properties</code>, en el cual podemos guardar todos aquellos valores que pueden cambiar con el tiempo, lo que evita la mala práctica de crear código hardcode o código duro.</p>



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



<p>Pero la pregunta es, como podemos acceder a estar propiedades desde una aplicación, pues bien, gracias a la inyección de dependencias que caracteriza a Spring Boot, es posible inyectar cualquier propiedad mediante la anotación <code>@Value</code>, tal como se puede ver a c continuación:</p>



<pre class="wp-block-code"><code lang="java" class="language-java line-numbers">@Configuration
public class ConverterConfig {
	@Value("${path.to.prop.name }")
	private String myProp;
}</code></pre>



<p>Y el archive <code>application.properties</code> quedaría de la siguiente forma:</p>



<pre class="wp-block-code"><code lang="properties" class="language-properties line-numbers">path.to.prop.name=my value</code></pre>



<p>Esto aplica exactamente igual cuando con un archivo <code>application.yml</code>:</p>



<pre class="wp-block-code"><code lang="yaml" class="language-yaml line-numbers">path:
 to:
  prop:
   name:my value</code></pre>



<p>Mediante esta técnica ya no necesitarás poner código duro nunca más.</p>



<figure class="wp-block-image"><a href="https://codmind.com/courses/api-rest-con-spring-boot"><img loading="lazy" width="800" height="450" src="https://www.oscarblancarteblog.com/wp-content/uploads/2019/08/banner-lg.jpg" alt="" class="wp-image-3146" 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>¿Quieres aprender a crear un API REST completa con Spring boot? te invito a curso de Mastering API REST con Spring Boot.</figcaption></figure>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2020/08/13/spring-boot-inyectar-propiedades-con-value/">Spring boot – Inyectar propiedades con @Value</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/2020/08/13/spring-boot-inyectar-propiedades-con-value/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3227</post-id>	</item>
		<item>
		<title>Crea tu primer API REST con Spring Boot</title>
		<link>https://www.oscarblancarteblog.com/2019/08/28/crea-tu-primer-api-rest-con-spring-boot/</link>
					<comments>https://www.oscarblancarteblog.com/2019/08/28/crea-tu-primer-api-rest-con-spring-boot/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Wed, 28 Aug 2019 03:33:09 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Sin categoría]]></category>
		<category><![CDATA[microservicios]]></category>
		<category><![CDATA[spring boot]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2854</guid>

					<description><![CDATA[<p>Spring boot se ha convertido en una de las tecnologías más importantes del desarrollo de Microservicios en Java, pues permite crear aplicaciones de forma muy rápida y con una auto configuración sorprendente. En el siguiente video aprenderás como crear tu primer API REST utilizando JPA para el mapeo Objeto relacional y Swagger para auto documentar [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/08/28/crea-tu-primer-api-rest-con-spring-boot/">Crea tu primer API REST con Spring Boot</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="800" height="450" src="https://www.oscarblancarteblog.com/wp-content/uploads/2019/08/banner-lg.jpg" alt="" class="wp-image-3146" 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" /></figure>



<p>Spring boot se ha convertido en una de las tecnologías más importantes del desarrollo de Microservicios en Java, pues permite crear aplicaciones de forma muy rápida y con una auto configuración sorprendente. </p>



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



<hr class="wp-block-separator"/>



<p>En el siguiente video aprenderás como crear tu primer API REST utilizando JPA para el mapeo Objeto relacional y Swagger para auto documentar el API, te invito a que veas este video que hice como invitado a Init, pero tambien te invito a que te suscribas a nuestro <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://www.youtube.com/channel/UCaDtXOU301UgSghUuHwkelw?sub_confirmation=1" target="_blank">Canal de Youtube</a> y visitar nuestra página oficial <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://codmind.com/" target="_blank">Codmind</a> para ver más cursos.</p>



<p>También puedes ver nuestro curso completo de <a href="https://codmind.com/courses/api-rest-con-spring-boot">Mastering API REST con Spring Boot</a></p>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe class='youtube-player' width='648' height='365' src='https://www.youtube.com/embed/K-KUfg-Cuc8?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>
</div></figure>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/08/28/crea-tu-primer-api-rest-con-spring-boot/">Crea tu primer API REST con Spring Boot</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/08/28/crea-tu-primer-api-rest-con-spring-boot/feed/</wfw:commentRss>
			<slash:comments>40</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2854</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>Path params con @FormParam</title>
		<link>https://www.oscarblancarteblog.com/2019/01/07/path-params-con-formparam/</link>
					<comments>https://www.oscarblancarteblog.com/2019/01/07/path-params-con-formparam/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Mon, 07 Jan 2019 20:22:07 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[API REST]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2699</guid>

					<description><![CDATA[<p>Una de las cosas que pocos saben, es que REST nos permite crear servicios que se integren a la perfección con los formularios HTML, de tal forma que podemos lugar una etiqueta &#60;form&#62; directamente con un servicio REST. para ello, JAX-RS nos proporciona la anotación @FormParam. La diferencia fundamental que tienen los form params con [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/07/path-params-con-formparam/">Path params con @FormParam</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/formparam-1024x575.jpg" alt="" class="wp-image-2701"/></figure>



<p>Una de las cosas que pocos saben, es que REST nos permite crear servicios que se integren a la perfección con los formularios HTML, de tal forma que podemos lugar una etiqueta <code>&lt;form&gt;</code> directamente con un servicio REST. para ello, JAX-RS nos proporciona la anotación <code>@FormParam</code>.</p>



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



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



				
<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>
		


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



<p>La diferencia fundamental que tienen los form params con respecto a los demás, es que se obtiene directamente los campo asociados al formulario desde el cual se ejecuta, pero para entender mejor, veamos el siguiente ejemplo:</p>



<pre class="wp-block-code lang:xhtml decode:true"><code>&lt;html>
	&lt;body>
		&lt;p>Customer form&lt;/p>
		&lt;form action="http://localhost:8080/api-0.0.1-SNAPSHOT/customers" 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>En este ejemplo debemos poner atención en la etiqueta <code>&lt;form&gt;</code>, la cual está apuntando a un servicios REST mediante la etiqueta <code>action</code>, con lo cual le estamos diciendo al navegador que envíe el formulario a nuestro servicio REST.</p>



<p>Otra de las cosas a tomar en cuenta son los campos dentro del form, como lo son el nombre, apellido y estatus, los cuales serán los que sean enviados al servicio REST.</p>



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



<p>Una vez explicado lo anterior, pasemos a la implementación en JAX-RS para recuperar estos parámetros:</p>



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

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(
			@FormParam("firstname") String firstname, 
			@FormParam("lastname") String lastname, 
			@FormParam("status") String status) {
		
		String result = String.format("firstname = %s, lastname = %s, status = %s", new String[]{firstname, lastname, status});
		return Response.ok(result).build();
	}
}</code></pre>



<p>Veamos como hemos definido una anotación <code>@FormParam</code> para cada uno de los parámetros esperados del formulario, los cuales serán mapeados a cada uno de los parámetros del método en Java.</p>



<p>Las anotaciones @Consumes la utilizamos definir que esperamos el payload como un formulario.</p>



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



<h2>Probando el servicio</h2>



<p>Lo primero será abrir el la página HTML para verlo de la siguiente manera:</p>



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



<p>Una vez capturado el formulario, la damos grabar, lo que detonará el submit del formulario y la ejecución del servicio REST, lo que dará como resultado lo siguiente:</p>



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



<p>Podemos ver como el servicio REST ha recibido todos los parámetros y los ha regresado como una cadena de texto.</p>



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



<p>Mediante la anotación <code>@FormParam</code> es fácil recuperar los valores de un formulario, pues los mapeamos a una parámetro especifico del método Java, sin embargo, esta forma tiene la limitación de que requerimos N parámetros en Java para mapear los N form params, lo que puede llegar a ser complicado en formularios grandes o donde los nombres de los parámetros pudieran variar, en tales casos, podemos implementarlos de la siguiente manera para recuperar todos los form params como un colección:</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 getFormDataUsingMultivaluedMap(MultivaluedMap&lt;String, String> formParams) {
		String result = "";
		for(Map.Entry entry: formParams.entrySet() ) {
			result += entry.getKey() + "=" + entry.getValue() + ", ";
		}
		
		return Response.ok(result).build();
	}
}</code></pre>



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



<h2>Conclusiones</h2>



<p>Los <code>@FormParam</code> pueden ser una buena alternativa cuando queremos ligar directamente un formulario con servicios REST, evitando tener que construir un request especifico. </p>



<p>Como inconveniente, tenemos que el servicio REST deberá retornar la estructura HTML de la siguiente página que verá el usuario, o en su defecto, podemos redireccionar al usuario a la siguiente página.</p>
		<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/07/path-params-con-formparam/">Path params con @FormParam</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/07/path-params-con-formparam/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2699</post-id>	</item>
		<item>
		<title>Query params con @QueryParam</title>
		<link>https://www.oscarblancarteblog.com/2019/01/03/java-query-param/</link>
					<comments>https://www.oscarblancarteblog.com/2019/01/03/java-query-param/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Thu, 03 Jan 2019 16:00:44 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[API REST]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2683</guid>

					<description><![CDATA[<p>Otra de las formas que tenemos para enviar parámetros al API REST son los Query Params, los cuales son una serie de clave-valor que se agregan al final de la URL, justo después del signo de interrogación (?). Para comprender mejor que es un Query param a analizar la siguiente URL para consultar los clientes [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2019/01/03/java-query-param/">Query params con @QueryParam</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/queryparam-1024x575.jpg" alt="" class="wp-image-2684"/></figure>



<p>Otra de las formas que tenemos para enviar parámetros al API REST son los Query Params, los cuales son una serie de clave-valor que se agregan al final de la URL, justo después del signo de interrogación (<code>?</code>).</p>



<p><br><br></p>



<span id="more-2683"></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><br>Para comprender mejor que es un Query param a analizar la siguiente URL para consultar los clientes por medio del nombre:</p>



<p><em>http://myapi.com/customers?<strong>name=oscar</strong></em></p>



<p><br>El query param es la clave valor <code>name=oscar</code> que vemos al final de la URL, y como regla, siempre deberán estar después del símbolo de interrogación. Además, una URL puede tener N query params, cómo el siguiente ejemplo:</p>



<p>http://myapi.com/customers?<strong>firstname=oscar</strong>&amp;l<strong>astname=blancarte</strong>&amp;<strong>status=active</strong></p>



<p><br>Esta URL la podemos utilizar para buscar a todos los clientes donde su nombre es oscar, su apellido es blancarte y su estatus es activo. Cuando utilizamos más de un Query param, es importante separar cada uno mediante el simbolo <code>&amp;</code>.</p>



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



<h2>Recuperar los Query params con JAX-RS</h2>



<p>Una vez explicado lo anterior, vamos a pasar a explicar como podemos recuperar los query params mediante el API JAX-RS de Java.</p>



<p>La forma más simple de recuperar un Query param es anotar los parámetros de los métodos con <code>@QueryParam</code>, de tal forma que deberemos tener un parámetro por cada query param esperado. Veamos el siguiente ejemplo:</p>



<pre class="wp-block-code"><code>@GET
@Path("customers")
public Response getCustomers(
		@QueryParam("firstname") String firstname, 
		@QueryParam("lastname") String lastname, 
		@QueryParam("status") String status) {
	String result = String.format("firstname = %s, lastname = %s, status = %s", new String[]{firstname, lastname, status});
	return Response.ok(result).build();
}</code></pre>



<p><br>Podemos observar que hemos definido la anotación <code>@QueryParam</code> en cada parámetro sobre el cual queremos mapear el parámetro. </p>



<p>Veamos ahora un ejemplo del ejecución de este método:</p>



<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/invoke-1-1024x652.jpg" alt="" class="wp-image-2694"/></figure>



<p>Como resultado podemos ver que hemos recibido los parámetros desde Java y devueltos como parte de la respuesta, lo que demuestra que hemos logrado mapear los query params con los parámetros del método Java.</p>



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



<p>El ejemplo anterior es la forma más simple de recuperar los query params, sin embargo, tiene el inconveniente de que debemos definir un parámetro en Java para cada query param que esperamos recibir, lo que puede ser complicado si tenemos muchos o los nombre de los query params pueden variar, pues no tendremos forma de predecirlos para mapearlos a un parámetro en Java. </p>



<p>Para solucionar estos casos tenemos la clase <code>UriInfo</code>, la cual debemos de inyectar al método en lugar de los <code>@QueryParam</code>, veamos el siguiente ejemplo:</p>



<pre class="wp-block-code"><code>@GET
@Path("customers2")
public Response getCustomers(
		@Context UriInfo uriInfo) {
	String result = "";
	for(Map.Entry entry: uriInfo.getQueryParameters().entrySet() ) {
		result += entry.getKey() + "=" + entry.getValue() + ", ";
	}
	return Response.ok(result).build();
}</code></pre>



<p><br>En este nuevo ejemplo podemos apreciar que hemos inyectado la clase UriInfo mediante la anotación <code>@Context</code> y por medio de esta clase podemos recuperar todos los query params, sin importar la cantidad que nos envíen e incluso si lo esperamos o no. La ventaja de este método es que podemos recuperar todos los query params como un <code>Set</code> e iterar todos los query params enviados.</p>



<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/invoke2-1024x599.jpg" alt="" class="wp-image-2695"/></figure>



<p>Observemos en esta última prueba que hemos enviado los query params de siempre y hemos agregado el param date.</p>



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



<h2>Conclusiones</h2>



<p>Hemos comprobado lo fácil que es recuperar los query params con <code>@QueryParam</code>, he incluso, recuperarlos mediante la clase <code>UriInfo</code>, pero hay que tener cuidado al momento de utilizarlos, pues en muchos de los casos, podríamos pasar los parámetros mediante <code>@PathParam</code>. </p>



<p>Por lo general, los <code>@QueryParam</code> se utilizan para complementar las búsquedas y los <code>@PathParam</code> para establecer el contexto de la búsqueda, es decir, mediante <code>@PathParam</code> decimos lo que estamos buscando y los <code>@QueryParam</code> como los queremos o los filtros de la selección.</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/03/java-query-param/">Query params con @QueryParam</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/03/java-query-param/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2683</post-id>	</item>
		<item>
		<title>Relaciónes @ManyToMany</title>
		<link>https://www.oscarblancarteblog.com/2018/12/27/relaciones-manytomany/</link>
					<comments>https://www.oscarblancarteblog.com/2018/12/27/relaciones-manytomany/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Thu, 27 Dec 2018 16:00:22 +0000</pubDate>
				<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[jpa]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2579</guid>

					<description><![CDATA[<p>Las relaciones Mucho a Muchos (@ManyToMany) se caracterízan por Entidades que están relacionadas con a muchos elementos de un tipo determinado, pero al mismo tiempo, estos últimos registros no son exclusivos de un registro en particular, si no que pueden ser parte de varios, por lo tanto, tenemos una Entidad A, la cual puede estar [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2018/12/27/relaciones-manytomany/">Relaciónes @ManyToMany</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/jpa-manytomany-1024x575.jpg" alt="" class="wp-image-2586"/></figure>



<p>Las relaciones Mucho a Muchos (@ManyToMany) se caracterízan por Entidades que están relacionadas con a muchos elementos de un tipo determinado, pero al mismo tiempo, estos últimos registros no son exclusivos de un registro en particular, si no que pueden ser parte de varios, por lo tanto, tenemos una Entidad A, la cual puede estar relacionada como muchos registros de la Entidad B, pero al mismo tiempo, la Entidad B puede pertenecer a varias instancias de la Entidad A.</p>



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



<p>Algo muy importante a tomar en cuenta cuando trabajamos con relaciones <code>@ManyToMany</code>, es que en realidad este tipo de relaciones no existen físicamente en la base de datos, y en su lugar, es necesario crear una tabla intermedia que relaciones las dos Entidades, veremos más adelante como resolvemos eso.</p>



<p>Un ejemplo clásico de estas relaciones son los libros con sus autores, de esta forma, un libro puede tener varios autores, y a su vez, los autores puede tener muchos libros. Pero para que quede más claro, veamos como quedarían las Entidades de Autor (<code>Author</code>), Libro (<code>Book</code>):<br></p>



<p><br><strong>Entidad Book:</strong></p>



<pre class="wp-block-code"><code class="">package com.oscarblancarteblog;

import java.util.ArrayList;
import java.util.List;
import javax.persistence.*;

@Entity
@Table(name = "books")
public class Book {
    @Id
    @Column(name="ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "NAME", nullable = false)
    private String name;
    
    @JoinTable(
        name = "rel_books_auths",
        joinColumns = @JoinColumn(name = "FK_BOOK", nullable = false),
        inverseJoinColumns = @JoinColumn(name="FK_AUTHOR", nullable = false)
    )
    @ManyToMany(cascade = CascadeType.ALL)
    private List&lt;Author> authors;
   
    public void addAuthor(Author author){
        if(this.authors == null){
            this.authors = new ArrayList&lt;>();
        }
        
        this.authors.add(author);
    }

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



<p>Como podemos apreciar, hemos creado una lista de tipo <code>Author</code>, la cual es anotada con <code>@ManyToMany</code>, adicional, hemos definido la anotación <code>@JoinTable</code>, la cual nos sirve para definir la estructura de la tabla intermedia que contendrá la relación entre los libros y los autores.</p>



<p>La anotación <code>@JoinTable</code> no es obligatoria en sí, ya que en caso de no definirse JPA asumirá el nombre de la tabla, columnas, longitud, etc. Para no quedar a merced de la implementación de JPA, siempre es recomendable definirla, así, tenemos el control total sobre ella.<br><br>Hemos definidos las siguientes propiedades de la anotación <code>@JoinTable</code>:<br></p>



<ul><li><strong>name</strong>: Nombre de la tabla que será creada físicamente en la base de datos.</li><li><strong>joinColumns</strong>: Corresponde al nombre para el ID de la Entidad Book.</li><li><strong>inverseJoinColumns</strong>: Corresponde al nombre para el ID de la Entidad Author</li></ul>



<p><br><strong>Entidad&nbsp;<code>Author</code>:</strong></p>



<pre class="wp-block-code"><code class="">package com.oscarblancarteblog;

import java.util.ArrayList;
import java.util.List;
import javax.persistence.*;

@Entity
@Table(name="authors")
public class Author {
    
    @Id
    @Column(name="ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name="NAME", nullable = false)
    private String name;
    
    @ManyToMany(mappedBy = "authors")
    private List&lt;Book> books;

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



<p>El caso de la Entidad <code>Author</code> es más simple, pues solo marcamos la colección con <code>@ManyToMany</code>, pero en este caso ya no es necesario definir la anotación <code>@JoinTable</code>, en su lugar, definimos la propiedad <code>mappedBy</code> para indicar la relación bidireccional y al mismo tiempo, JPA puede tomar la configuración del <code>@JoinTable</code> de Books.</p>



<p>Como resultado de estas Entidades, tendremos las siguientes tablas auto generadas:</p>



<figure class="wp-block-image"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/manytomany-tables.jpg" alt="" class="wp-image-2583"/></figure>



<p>Notemos en la tabla <em>authors </em>no tiene una columna que haga referencia a <em>books</em>, ni <em>books </em>a <em>authors</em>, si no que es necesario tener una tabla intermedia que haga el cruce entre las dos tablas. </p>



<p>La tabla intermedia (<em>rel_book_auths</em>) es generada por la anotación <code>@JoinTable</code> y sus dos columnas son llaves foraneas a las tablas <em>books</em> y <em>authors</em>.<br><br><br></p>



<h2>Prueba de validación</h2>



<p>Para comprobar que todo funciona como lo hemos dicho, vamos a realizar una prueba, la cual se ve de la siguiente manera:</p>



<pre class="wp-block-code"><code class="">public static void main(String[] args) {
        
	//Authors
	Author author1 = new Author();
	author1.setName("Juan Perez");
	
	Author author2 = new Author();
	author2.setName("Oscar Blancarte");
	
	Author author3 = new Author();
	author3.setName("Arturo Martinez");
	
	
	//Books
	Book book1 = new Book();
	book1.setName("El lago y el pato");
	book1.addAuthor(author1);
	book1.addAuthor(author2);
	book1.addAuthor(author3);
	
	Book book2 = new Book();
	book2.setName("Una mañana de verano");
	book2.addAuthor(author1);
	book2.addAuthor(author2);
	book2.addAuthor(author3);
	
	EntityManager em = EntityManagerUtil.getEntityManager();
	em.getTransaction().begin();
	em.persist(book1);
	em.persist(book2);
	em.getTransaction().commit();
	
	System.out.println("FIN");
}</code></pre>



<p>Hemos creados dos libros y tres autores, y luego hemos asociado a los autores a los libros, con la intención de que los autores estén en dos libros y los libros tengan varios autores.</p>



<p><strong>Tambíen los quiero invitar a ver mi curso de JPA, donde explico todos estos temas aplicados con API REST,&nbsp;</strong><a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener"><strong>https://codmind.com/courses/jpa</strong></a></p>



<figure class="wp-block-image"><a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener"><img loading="lazy" width="800" height="450" src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg" alt="" class="wp-image-3085" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg 800w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md-300x169.jpg 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md-768x432.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption>&nbsp;Los invito a mi&nbsp;<a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener">Curso de Mastering JPA</a>, donde habla de todos estos temas y crearemos un API REST para probar todos los conceptos de persistencia.<br></figcaption></figure>



<p>Ahora veamos como se ven las tablas <em>authors</em>, <em>books </em>y <em>rel_books_auths</em>:<br></p>



<div class="wp-block-image"><figure class="aligncenter"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/authors-table-2.jpg" alt="" class="wp-image-2593"/></figure></div>



<div class="wp-block-image"><figure class="aligncenter"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/book-table.jpg" alt="" class="wp-image-2592"/></figure></div>



<div class="wp-block-image"><figure class="aligncenter"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/rel-books-auths-table.jpg" alt="" class="wp-image-2594"/></figure></div>



<p>Para poder obtener la relación entre libros y autores solo faltaría hacer la unión entre las dos tablas.<br><br></p>



<h2>Conclusiones</h2>



<p>Para concluir solo faltaría resaltar que en las relaciones <code>@ManyToMany</code> los registros son independientes de los registros a los que son relacionados, por lo que en este caso, podrían existir los autores si no existieran los libros, y al revés.</p>



<center><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="https://www.oscarblancarteblog.com/2018/12/20/relaciones-onetomany/">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 disabled" 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>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2018/12/27/relaciones-manytomany/">Relaciónes @ManyToMany</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/2018/12/27/relaciones-manytomany/feed/</wfw:commentRss>
			<slash:comments>54</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2579</post-id>	</item>
		<item>
		<title>Relaciones @OneToMany</title>
		<link>https://www.oscarblancarteblog.com/2018/12/20/relaciones-onetomany/</link>
					<comments>https://www.oscarblancarteblog.com/2018/12/20/relaciones-onetomany/#comments</comments>
		
		<dc:creator><![CDATA[oblancarte]]></dc:creator>
		<pubDate>Thu, 20 Dec 2018 16:00:27 +0000</pubDate>
				<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[jpa]]></category>
		<guid isPermaLink="false">https://www.oscarblancarteblog.com/?p=2555</guid>

					<description><![CDATA[<p>Las relaciones uno a muchos (@OneToMany) se caracterizan por Entidad donde tenemos un objeto principal y colección de objetos de otra Entidad relacionados directamente. Estas relaciones se definen mediante colecciones, pues tendremos una serie de objetos pertenecientes al objeto principal. Este articulo es parte de un guia completa de JPA, para ver el contenido completo [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2018/12/20/relaciones-onetomany/">Relaciones @OneToMany</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/jpa-onetomany-1024x575.jpg" alt="JPA relaciones @OneToMany" class="wp-image-2556"/></figure>



<p>Las relaciones uno a muchos (@OneToMany) se caracterizan por Entidad donde tenemos un objeto principal y  colección de objetos de otra Entidad relacionados directamente. Estas relaciones se definen mediante colecciones, pues tendremos una serie de objetos pertenecientes al objeto principal.<br><br></p>



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



<blockquote class="wp-block-quote"><p>Este articulo es parte de un guia completa de JPA, para ver el contenido completo puedes ir a <a href="https://www.oscarblancarteblog.com/tutoriales/java-persistence-api-jpa/">Java Persistence API (JPA)</a></p></blockquote>



<p><br>Un ejemplo clásico para entender este tipo de relaciones son las facturas, pues tendremos una Entidad cabecera donde tengamos los datos principales de la factura, como podría ser serie, cliente, total, fecha de expedición, etc. Por otra parte, la factura tendrá una serie de líneas que representa cada uno de los productos vendidos.&nbsp;</p>



<p>Veamos como quedaría la entidad <code>Invoice</code> (factura):</p>



<pre class="wp-block-code"><code class="">package com.obb.jpa.jpaturorial.entity;

import java.util.Calendar;
import java.util.List;
import javax.persistence.*;

@Entity
@Table(name="INVOICES")
public class Invoice {
    
    @Id
    @Column(name="ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    
    @Column(name = "STATUS", length = 20, nullable = false)
    @Enumerated(EnumType.STRING)
    private Status status;
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "REGIST_DATE", nullable = false)
    private Calendar registDate;
    
    @JoinColumn(name = "FK_CUSTOMER", nullable = false)
    @ManyToOne(optional = false, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Customer customer;
    
    @OneToOne(mappedBy = "invoice", cascade = CascadeType.ALL)
    private Payment payment;
    
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "invoice")
    private List&lt;InvoiceLine> lines;

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



<p><br>Podemos apreciar como hemos definido la propiedad lines como una lista (<code>List</code>), lo cual nos permite relacionar la factura con un número indeterminado de líneas, por otro lado, hemos definido la propiedad <code>mappedBy</code> para indicar que es una relación bidireccional, es decir, la Entidad <code>InvoiceLine</code> tendrá también una relación hacia la Entidad <code>Invoice</code>.</p>



<p>La Entidad <code>InvoiceLine</code> se verá de la siguiente manera:</p>



<pre class="wp-block-code"><code class="">package com.obb.jpa.jpaturorial.entity;

import javax.persistence.*;

@Entity
@Table(name = "invoice_lines")
public class InvoiceLine {
    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "PRODUCT", nullable = false)
    private String product;
    
    @Column(name = "PRICE", nullable = false)
    private double price;
    
    @Column(name = "TOTAL", nullable = false)
    private double quantity;
    
    @ManyToOne
    @JoinColumn(name = "FK_INVOICE", nullable = false, updatable = false)
    private Invoice invoice;
    
    /** GET and SET */

}</code></pre>



<p><br>Como dijimos hace un momento, la Entidad <code>InvoiceLine</code> tiene una propiedad de tipo <code>Invoice</code> para poderla hacer bidireccional, observemos que el nombre de la propiedad <code>invoice</code> corresponde con el valor del <code>mappedBy</code> definido en la Entidad <code>Invoice</code>, ya que de lo contrario JPA nos arrojará un error.</p>



<p><strong>Tambíen los quiero invitar a ver mi curso de JPA, donde explico todos estos temas aplicados con API REST,&nbsp;</strong><a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener"><strong>https://codmind.com/courses/jpa</strong></a></p>



<figure class="wp-block-image"><a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener"><img loading="lazy" width="800" height="450" src="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg" alt="" class="wp-image-3085" srcset="https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md.jpg 800w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md-300x169.jpg 300w, https://www.oscarblancarteblog.com/wp-content/uploads/2020/06/banner-md-768x432.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption>&nbsp;Los invito a mi&nbsp;<a href="https://codmind.com/courses/jpa" target="_blank" rel="noreferrer noopener">Curso de Mastering JPA</a>, donde habla de todos estos temas y crearemos un API REST para probar todos los conceptos de persistencia.<br></figcaption></figure>



<p><br>En este imagen podemos apreciar que la tabla <em>invoice_lines</em> tiene la columna <em>FK_INVOICE</em> que será utilizada para realizar el <em>JOIN</em> con la tabla <em>invoices</em>, de tal forma que cada registro de <em>invoice_lines</em> que sea encontrado será convertido en una instancia de la Entidad <code>InvoiceLine</code>.</p>



<pre class="wp-block-code"><code class="">public static void main(String[] args) {
    Invoice invoice = new Invoice();

    List&lt;InvoiceLine> lines = new ArrayList&lt;>();
    for(int c = 0; c&lt;10; c++){
        InvoiceLine line = new InvoiceLine();
        line.setInvoice(invoice);
        line.setPrice(10);
        line.setProduct("Product " + (c+1));
        line.setQuantity(c+1);
        lines.add(line);
    }

    Customer customer = new Customer();
    customer.setName("Oscar Blancarte");

    invoice.setCustomer(customer);
    invoice.setLines(lines);
    invoice.setRegistDate(Calendar.getInstance());
    invoice.setStatus(Status.ACTIVE);

    EntityManager em = EntityManagerUtil.getEntityManager();
    em.getTransaction().begin();
    em.persist(invoice);
    em.getTransaction().commit();
}</code></pre>



<p><br>Dando como resultado los siguientes registros en la base de datos:</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/invoices-select-1.jpg" alt="JPA relaciones @OneToMany tabla invoices" class="wp-image-2558"/><figcaption>Tabla invoices</figcaption></figure></div>



<div class="wp-block-image"><figure class="aligncenter"><img src="https://www.oscarblancarteblog.com/wp-content/uploads/2018/12/invoice-lines-select.jpg" alt="JPA relaciones @OneToMany tabla invoice_lines" class="wp-image-2559"/><figcaption>Tabla invoice_lines</figcaption></figure></div>



<p>Ahora si podemos ver todo materializado y nos queda más la forma en que la información es almacenada.&nbsp;<br><br><br></p>



<h2>Conclusiones</h2>



<p>Hemos comprobado lo simple que es crear relaciones <code>@OneToMany</code> y hemos podido comprobar como&nbsp; la información es almacenada, solo faltaría resaltar que JPA no garantiza el orden en que los elementos de la colección son insertados, es por ello, que siempre se aconseja tener una columna que indique el orden natural de los elementos para sobre esa columna hacer el ordenamiento, esto claro si nos interesa mantener el ordenamiento, en caso podemos ignorarlo.</p>



<center><a class="btn btn-default read-more" style="display: inline-block; float: none; margin-right: 15px;" href="https://www.oscarblancarteblog.com/2018/12/14/relaciones-onetoone/">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/2018/12/27/relaciones-manytomany/">Siguiente </a></center>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
<p>The post <a rel="nofollow" href="https://www.oscarblancarteblog.com/2018/12/20/relaciones-onetomany/">Relaciones @OneToMany</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/2018/12/20/relaciones-onetomany/feed/</wfw:commentRss>
			<slash:comments>18</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2555</post-id>	</item>
	</channel>
</rss>
