<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Códice | Entradas sobre «bootstrap»</title><description>Feed RSS de publicaciones etiquetadas con bootstrap</description><link>https://javguerra.github.io/</link><item><title>Notificaciones con Thymeleaft</title><link>https://javguerra.github.io/blog/notificaciones-thymeleaft</link><guid isPermaLink="true">https://javguerra.github.io/blog/notificaciones-thymeleaft</guid><description>Cómo incluir avisos en Spring Boot</description><pubDate>Wed, 03 Jul 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/notificaciones.DrEXfhr5_Z1sRXMQ.webp&quot; alt=&quot;Notificaciones&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#java&lt;/em&gt;, &lt;em&gt;#spring boot&lt;/em&gt;, &lt;em&gt;#bootstrap&lt;/em&gt;, &lt;em&gt;#thymeleaft&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Cuando una aplicación realiza operaciones potencialmente críticas como editar, guardar o borrar datos de una base de datos, es conveniente notificar al usuario el éxito o fracaso de las operaciones. Esta entrada presenta una solución básica de cómo mostrar notificaciones en la plantilla Thymeleaft.&lt;/p&gt;
&lt;p&gt;Se asume que el lector tiene conocimientos generales de Spring Boot, Thymeleaft y Bootstrap para aplicar el contenido.&lt;/p&gt;
&lt;h1 id=&quot;planteamiento&quot;&gt;Planteamiento&lt;/h1&gt;
&lt;p&gt;La idea es destinar una área de la visualización en la aplicación para las notificaciones, y activar este área sólo cuando se deban mostrar, dando opción al usuario a cerrarlas una vez leídas. Este área puede crearse como un fragmento (th:fragment) e incluirse en las plantillas en las que se requiera, o en todas las plantillas asociadas a las vistas de la aplicación.&lt;/p&gt;
&lt;p&gt;Será necesaria una variable que sirva de «llave» para mostrar estas notificaciones o no, y otra para indicar el tipo de mensaje (&lt;em&gt;info&lt;/em&gt;, &lt;em&gt;danger&lt;/em&gt;…). Como enviar el mensaje desde cada método de erutado de nuestros controladores es algo trabajoso, lo adecuado es usar un filtro de sesión http que me permitirá crear las variables donde guardaré el contenido del mensaje y el tipo de mensaje a mostrar.&lt;/p&gt;
&lt;p&gt;Por último, gestionaré el borrado del contenido de la notificación para que esta deje de mostrarse al cambiar de página Para ello necesitaremos otra variable que indique si la notificación ya se ha mostrado.&lt;/p&gt;
&lt;h1 id=&quot;programando-notificaciones&quot;&gt;Programando notificaciones&lt;/h1&gt;
&lt;p&gt;Para crear las notificaciones, necesitaremos:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Crear un fragmento que servirá para incluir el texto de la notificación en nuestras vistas.&lt;/li&gt;
&lt;li&gt;Inicializar las variables de sesión que contendrán la notificación y el tipo de notificación.&lt;/li&gt;
&lt;li&gt;Actualizar el valor de las variables de notificación para que estas se muestren.&lt;/li&gt;
&lt;li&gt;Eliminar la notificación al cambiar de página.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;el-fragmento&quot;&gt;El fragmento&lt;/h2&gt;
&lt;p&gt;He creado un fragmento de código llamado &lt;code&gt;messageAlert.html&lt;/code&gt; que he incluido en mi carpeta &lt;code&gt;fragments&lt;/code&gt; dentro de templates en resources. Este es un ejemplo que puede modificarse a voluntad para adaptar su diseño a la aplicación donde se usará.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:fragment&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageAlert&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;${session.message != &apos;&apos;}&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alert alert-dismissible fade show&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; role&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alert&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        th:classappend&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;${session.messageType} == &apos;danger&apos;? &apos;alert-danger&apos; : &apos;alert-info&apos;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; xmlns&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;http://www.w3.org/2000/svg&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;none&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; viewBox&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0 0 24 24&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;1.5&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;currentColor&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;24&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;24&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linecap&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linejoin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;M14.857 17.082a23.848 23.848 0 0 0 5.454-1.31A8.967 8.967 0 0 1 18 9.75V9A6 6 0 0 0 6 9v.75a8.967 8.967 0 0 1-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 0 1-5.714 0m5.714 0a3 3 0 1 1-5.714 0M3.124 7.5A8.969 8.969 0 0 1 5.292 3m13.416 0a8.969 8.969 0 0 1 2.168 4.5&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;nbsp;&amp;amp;nbsp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;align-middle&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:text&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;${session.message}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;btn-close&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; data-bs-dismiss&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alert&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Cerrar&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con &lt;code&gt;th:if=&quot;${session.message != &apos;&apos;}&quot;&lt;/code&gt;determino si este fragmento se mostrará o no. Si el valor de la variable de sesión llamada &lt;code&gt;message&lt;/code&gt; está vacío, es que no hay nada que mostrar, de otra forma, el fragmento se mostrará.&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;th:classappend=&quot;${session.messageType} == &apos;danger&apos;? &apos;alert-danger&apos; : &apos;alert-info&apos;&quot;&lt;/code&gt; determino qué tipo de alerta de Boostrap mostrar, si una destinada a informar (recuadro con fondo azul) o una destinada a alertar de un fallo (recuadro con fondo rojo). Esto lo consigo mediante la variable de sesión &lt;code&gt;messageType&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Tras el icono SVG que se mostrará en el aviso, se incluye el mensaje de la notificación con &lt;code&gt;th:text=&quot;${session.message}&quot;&lt;/code&gt; dentro de la etiqueta &lt;code&gt;span&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Con el &lt;code&gt;button&lt;/code&gt;, ayudado por Bootstrap, el usuario puede cerrar la notificación.&lt;/p&gt;
&lt;p&gt;Para incluir este fragmento en la vista donde deseo que se muestre la notificación, uso:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:replace&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;~{fragments/messageAlert :: messageAlert}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;inicializando-las-variables-message-y-messagetype&quot;&gt;Inicializando las variables message y messageType&lt;/h2&gt;
&lt;p&gt;Como he comentado, voy a usar variables de sesión http para guardar el contenido del mensaje y el tipo de mensaje. Para ello creo un filtro de sesión que compruebe, por cada petición http, si existe una sesión y si las variables de sesión están creadas.&lt;/p&gt;
&lt;p&gt;He incluido el siguiente componente en &lt;code&gt;/Utils/SessionFilter.java&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Component&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SessionFilter&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; implements&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Filter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; init&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(FilterConfig &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;filterConfig&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throws&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ServletException {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; doFilter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(ServletRequest &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, ServletResponse &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;response&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, FilterChain &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;chain&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            throws&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IOException, ServletException {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpServletRequest httpRequest &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (HttpServletRequest) request;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpServletResponse httpResponse &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (HttpServletResponse) response;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpSession session &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; httpRequest.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getSession&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // Variables para las notificaciones&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageType&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageType&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;                // Valores: &quot;danger&quot; u otro cualquiera = &quot;info&quot;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        chain.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;doFilter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(request, response);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; destroy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con &lt;code&gt;HttpSession session = httpRequest.getSession(true);&lt;/code&gt; Obtengo la sesión, y si no existe, se creará una nueva. Esto ocurre porque he incluido el valor &lt;code&gt;true&lt;/code&gt; en &lt;code&gt;.getSession(true)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Si existe la sesión (que, salvo error, ya debería existir), compruebo que las variables &lt;code&gt;message&lt;/code&gt; y &lt;code&gt;messageType&lt;/code&gt; estén inicializadas, y si no lo están las inicializo a &lt;code&gt;&quot;&quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Tras esto, ya podremos usar &lt;code&gt;session.getAttribute()&lt;/code&gt; y &lt;code&gt;session.setAttribute()&lt;/code&gt; para leer y para actualizar el valor de las variables de sesión desde nuestros servicios o controladores, como veremos.&lt;/p&gt;
&lt;h2 id=&quot;usando-mensajes&quot;&gt;Usando mensajes&lt;/h2&gt;
&lt;p&gt;Pensemos en un servicio que guarde el contenido de un formulario para crear un cine. Sería algo similar a esto:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Slf4j&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;RequiredArgsConstructor&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Service&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; CinemaServiceImpl&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; implements&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ICinemaService&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    private&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; final&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; CinemaRepository cinemaRepo;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Otras propiedades y métodos de la clase aquí&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Transactional&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Cinema &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;save&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(Cinema &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;cinema&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        log.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;save {}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, cinema);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; cinemaRepo.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;save&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(cinema);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (Exception &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            log.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Error al guardar el cine: &quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, e);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Como se ve, la clase &lt;code&gt;CinemaServiceImpl&lt;/code&gt; implementa la interfaz &lt;code&gt;ICinemaService&lt;/code&gt;, inyecta el repositorio &lt;code&gt;CinemaRepository&lt;/code&gt; y tiene un método que guarda un cine. &lt;code&gt;cinema&lt;/code&gt; es enviado al método &lt;code&gt;save&lt;/code&gt; desde el controlador que lo usa, y el método devuelve el cine guardado o null si se produjo un error.&lt;/p&gt;
&lt;p&gt;A continuación muestro cómo se verá el método al incluir los mensajes de éxito o error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Slf4j&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;RequiredArgsConstructor&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Service&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; CinemaServiceImpl&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; implements&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ICinemaService&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    private&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; final&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; HttpSession session;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    private&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; final&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; CinemaRepository cinemaRepo;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Otras propiedades y métodos de la clase aquí&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Transactional&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Cinema &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;save&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(Cinema &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;cinema&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        log.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;save {}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, cinema);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            Cinema newCinema &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; cinemaRepo.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;save&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(cinema);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            String message &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;Cine &quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; newCinema &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot; guardado.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, message);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageType&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;info&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; newCinema;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (Exception &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            log.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Error al guardar el cine: &quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, e);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;El cine no ha podido guardarse.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageType&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;danger&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con &lt;code&gt;session.setAttribute(&quot;message&quot;, message);&lt;/code&gt; se cambia el valor de la variable &lt;code&gt;message&lt;/code&gt;, y con &lt;code&gt;session.setAttribute(&quot;messageType&quot;, &quot;info&quot;);&lt;/code&gt; se hace lo propio con la variable &lt;code&gt;messageType&lt;/code&gt;. Lo mismo ocurre en caso de error.&lt;/p&gt;
&lt;p&gt;A tener en cuenta: en &lt;code&gt;String message = &quot;Cine &quot; + newCinema + &quot; guardado correctamente.&quot;;&lt;/code&gt; hay que estar seguro de que la entidad &lt;code&gt;Cinema&lt;/code&gt; sobrescribe (@Override) el método &lt;code&gt;toString()&lt;/code&gt; para poder usarlo como String.&lt;/p&gt;
&lt;p&gt;El resultado es algo como lo que se muestra a continuación.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Notificación activa&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/notificaciones.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;Lo que se ve es lo que hemos definido en el fragmento &lt;code&gt;messageAlert.html&lt;/code&gt; que hemos incluido en la plantilla de la vista.&lt;/p&gt;
&lt;h2 id=&quot;mensajes-encadenados&quot;&gt;Mensajes encadenados&lt;/h2&gt;
&lt;p&gt;Si realizamos más de una gestión crítica desde un mismo controlador, como, por ejemplo, actualizar la información de un cine, y si este no está está operativo (p.ej. si ha cerrado temporalmente), entonces desactivar todas las salas de ese cine para que no se muestren en la aplicación, podemos encadenar los mensajes de ambos servicios. Para ello debemos leer el valor de la variable &lt;code&gt;message&lt;/code&gt; en el segundo servicio, el que se ocupe de desactivar las salas, y añadir el aviso al nuevo mensaje, ya que sólo disponemos de un mensaje que puede ser mostrado a la vez:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;String message &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (String) session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, message &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot; Salas desactivadas correctamente.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;cerrando-la-notificación-al-cambiar-de-página&quot;&gt;Cerrando la notificación al cambiar de página&lt;/h2&gt;
&lt;p&gt;Como sabemos, la notificación puede cerrarse haciendo clic en la &lt;code&gt;X&lt;/code&gt; de cierre, o bien cerrarse cuando cambiamos de página. Al cambiar de página, el filtro &lt;code&gt;SessionFilter&lt;/code&gt; se ejecutará, y para que ocurra lo que queremos es necesario incluir una nueva variable y mas comprobaciones, como se muestra a continuación:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Component&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SessionFilter&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; implements&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Filter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; init&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(FilterConfig &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;filterConfig&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throws&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ServletException {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; doFilter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(ServletRequest &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, ServletResponse &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;response&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, FilterChain &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;chain&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            throws&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IOException, ServletException {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpServletRequest httpRequest &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (HttpServletRequest) request;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpServletResponse httpResponse &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (HttpServletResponse) response;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpSession session &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; httpRequest.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getSession&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // Variables para las notificaciones&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageType&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageType&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;                // Valores: &quot;danger&quot; u otro cualquiera = &quot;info&quot;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // Cierre de notificaciones al cambiar de página&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ((&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;boolean&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Objects.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;equals&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((String) session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;), &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        chain.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;doFilter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(request, response);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; destroy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En estos tres nuevos bloques de sentencias &lt;code&gt;if&lt;/code&gt; , primero compruebo que la variable de sesión &lt;code&gt;messageActivated&lt;/code&gt; está inicializada, como hacía con las otras variables de sesión, y si no lo está, la inicializo a false.&lt;/p&gt;
&lt;p&gt;Como cada vez que se muestra una página en la aplicación se lanza &lt;code&gt;SessionFilter&lt;/code&gt;, en el siguiente bloque de sentencias compruebo si &lt;code&gt;messageActivated&lt;/code&gt; está activado (&lt;code&gt;true&lt;/code&gt;), y si lo está, la desactivo, y vacío &lt;code&gt;message&lt;/code&gt; para que no vuelva a mostrarse la notificación. Recordemos que el fragment &lt;code&gt;messageAlert.html&lt;/code&gt; sólo muestra la notificación si su contenido no es &lt;code&gt;&quot;&quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;En el último bloque, si &lt;code&gt;message&lt;/code&gt; contiene texto y es la primera vez que se va a mostrar la notificación, el bloque anterior no la habrá borrado. Entonces activo &lt;code&gt;messageActivated&lt;/code&gt; para que la notificación pueda ser eliminada la siguiente vez que se muestre una página.&lt;/p&gt;
&lt;p&gt;Como se aprecia, &lt;code&gt;messageActivated&lt;/code&gt; actúa como indicador de borrado, y en este proceso es determinante el orden en el que se hacen las comprobaciones.&lt;/p&gt;
&lt;p&gt;Con esto, ya tenemos activo nuestro propio sistema de notificaciones para Thymeleaft.&lt;/p&gt;
&lt;p&gt;Adaptando este método sería posible, por ejemplo, generar notificaciones que permitan consultar al usuario si quiere llevar a cabo o no una tarea determinada, como p.ej. &lt;code&gt;&quot;¿Desea borrar el cine? [Sí] [No]&quot;&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;bonus-aviso-de-cookies&quot;&gt;BONUS: Aviso de cookies&lt;/h1&gt;
&lt;p&gt;Es fácil realizar los cambios para, por ejemplo, notificar un aviso de cookies con un botón de aceptar que permanezca abierto hasta que el usuario lo cierre, o incluso poner un banner, o cualquier aviso temporal que requiera nuestra aplicación. Hagamos el proceso de ejemplo de un aviso de cookies.&lt;/p&gt;
&lt;p&gt;El planteamiento cambia un poco. Si vamos a emplear ambos métodos, el de notificar lo que ocurre en la aplicación y el aviso de cookies, debemos usar una variable propia que actúe de «llave» para la cookie.&lt;/p&gt;
&lt;p&gt;La notificación estará disponible en la vista actual y en todas aquellas vistas que tengan el fragmento de código de la cookie incluido en la plantilla hasta que se lo indiquemos. Como no podemos eliminar el contenido de la notificación desde Thymeleaft, y no sabemos el momento en el que el usuario eliminará la ventana de notificación, la variable de sesión que guarda la notificación se manejará desde el &lt;em&gt;backend&lt;/em&gt;, mediante un controlador y una ruta que nos permita cambiar su valor.&lt;/p&gt;
&lt;h2 id=&quot;el-filtro&quot;&gt;El filtro&lt;/h2&gt;
&lt;p&gt;Comienzo añadiendo la nueva variable &lt;code&gt;cookieWarning&lt;/code&gt; de sesión al filtro:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Component&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SessionFilter&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; implements&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Filter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; init&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(FilterConfig &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;filterConfig&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throws&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ServletException {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; doFilter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(ServletRequest &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, ServletResponse &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;response&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, FilterChain &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;chain&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            throws&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IOException, ServletException {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpServletRequest httpRequest &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (HttpServletRequest) request;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpServletResponse httpResponse &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (HttpServletResponse) response;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpSession session &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; httpRequest.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getSession&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // Variables para las notificaciones&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageType&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageType&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;                // Valores: &quot;danger&quot; u otro cualquiera = &quot;info&quot;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // Cierre de notificaciones al cambiar de página&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ((&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;boolean&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Objects.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;equals&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((String) session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;), &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // Gestión de la cookie&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cookieWarning&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cookieWarning&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        chain.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;doFilter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(request, response);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; destroy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En este caso, la variable tendrá valor &lt;code&gt;true&lt;/code&gt; por defecto, lo que indica que el fragmento de aviso de cookies debe mostrarse. Cuando la cerremos, este valor cambiará a &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;el-fragmento-1&quot;&gt;El fragmento&lt;/h2&gt;
&lt;p&gt;Podemos llamar al fragmento que mostrará la notificación &lt;code&gt;cookieWarnig.html&lt;/code&gt;, e incluirlo en todas nuestras páginas mediante:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:replace&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;~{fragments/cookieWarning :: cookieWarning}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Este es su código:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:fragment&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cookieWarning&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;${session.cookieWarning}&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;container mt-3 sticky-top&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:action&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;@{/cookie}&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; method&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;POST&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hidden&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;returnUrl&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;${returnUrl}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alert alert-warning alert-dismissible fade show shadow d-flex justify-content-between&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; role&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alert&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; xmlns&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;http://www.w3.org/2000/svg&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;none&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; viewBox&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0 0 24 24&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;1.5&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;currentColor&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;24&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;24&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linecap&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linejoin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;M10.34 15.84c-.688-.06-1.386-.09-2.09-.09H7.5a4.5 4.5 0 1 1 0-9h.75c.704 0 1.402-.03 2.09-.09m0 9.18c.253.962.584 1.892.985 2.783.247.55.06 1.21-.463 1.511l-.657.38c-.551.318-1.26.117-1.527-.461a20.845 20.845 0 0 1-1.44-4.282m3.102.069a18.03 18.03 0 0 1-.59-4.59c0-1.586.205-3.124.59-4.59m0 9.18a23.848 23.848 0 0 1 8.835 2.535M10.34 6.66a23.847 23.847 0 0 0 8.835-2.535m0 0A23.74 23.74 0 0 0 18.795 3m.38 1.125a23.91 23.91 0 0 1 1.014 5.395m-1.014 8.855c-.118.38-.245.754-.38 1.125m.38-1.125a23.91 23.91 0 0 0 1.014-5.395m0-3.46c.495.413.811 1.035.811 1.73 0 .695-.316 1.317-.811 1.73m0-3.46a24.347 24.347 0 0 1 0 3.46&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;nbsp;&amp;amp;nbsp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;align-middle&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;strong&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Atención:&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;strong&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; Este sitio usa cookies. Lea la Política de privacidad.&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;submit&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;btn btn-sm btn-outline-primary&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; data-bs-dismiss&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alert&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Confirmar&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;OK&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nuestra notificación de cookie se verá así:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Notificación de cookie&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/notificaciones-cookie.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;La comprobación &lt;code&gt;th:if=&quot;${session.cookieWarning}&quot;&lt;/code&gt; hará que se muestre o no este fragmento, osea, que se muestre o no la notificación de cookies.&lt;/p&gt;
&lt;p&gt;Como se aprecia, se incluye un formulario que actuará cuando el usuario cierre la notificación. Con el botón &lt;code&gt;button type=&quot;submit&quot;&lt;/code&gt;, mediante el formulario, llamo al controlador que va a desactivar la notificación de cookie a través la ruta indicada en el formulario: &lt;code&gt;&amp;lt;form th:action=&quot;@{/cookie}&quot; method=&quot;POST&quot;&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;&amp;lt;input type=&quot;hidden&quot; th:name=&quot;returnUrl&quot; th:value=&quot;${returnUrl}&quot;&amp;gt;&lt;/code&gt; indico, a través de la respuesta de formulario al controlador, a qué página debo dirigirme después de realizar la operación, pues, como dije, no sabemos en qué momento el usuario cerrará la notificación. Esto me permitirá volver a la página donde estaba una vez se procese el cambio del valor de la variable de sesión de la cookie.&lt;/p&gt;
&lt;p&gt;Suelo usar de forma genérica &lt;code&gt;returnUrl&lt;/code&gt; para indicar la ruta porque es útil para, por ejemplo, cuando llamo a un formulario y quiero saber dónde debo ir una vez enviado el contenido del formulario, como en este caso. Por ejemplo, si nuestra aplicación maneja cines, y añadimos, editamos o borramos un cine, mediante &lt;code&gt;returnUrl&lt;/code&gt; puedo indicar al método &lt;code&gt;@PostMapping&lt;/code&gt; qué vista mostrar tras realizar estas operaciones. Para poder hacerlo, cuando usé las vistas de crear, editar o borrar mencionadas, añado esta variable al modelo con:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;addAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;returnUrl&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cinemas&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;donde cinemas es la ruta a la que se debe llegar una vez el formulario de la ruta a la que vamos se procese. El método se vería así:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;GetMapping&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/create&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; String &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;createForm&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(Model model) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    model.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;addAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cinema&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Cinema&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    model.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;addAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;returnUrl&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cinemas&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;cinema/cinema-form&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;cerrando-la-notificación-de-cookie&quot;&gt;Cerrando la notificación de cookie&lt;/h2&gt;
&lt;p&gt;En la carpeta &lt;code&gt;controllers&lt;/code&gt;, creo el controlador &lt;code&gt;CookieController&lt;/code&gt; siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Controller&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; CookieController&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;PostMapping&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/cookie&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; String &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;closeCookiePolicy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(HttpSession &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;session&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;RequestParam&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;returnUrl&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;required&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) String &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;returnUrl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cookieWarning&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;stringIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(returnUrl)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;redirect:&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; returnUrl;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;redirect:/&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Así, a través de la ruta &lt;code&gt;/cookie&lt;/code&gt; puedo cambiar el valor de &lt;code&gt;cookieWarning&lt;/code&gt; con: &lt;code&gt;session.setAttribute(&quot;cookieWarning&quot;, false);&lt;/code&gt; y luego volver a la ruta deseada si hemos pasado el parámetro &lt;code&gt;returnUrl&lt;/code&gt;. Ahora la notificación ya no se mostrará más.&lt;/p&gt;
&lt;p&gt;Es importante que la ruta &lt;code&gt;/cookie&lt;/code&gt; esté definida en nuestra configuración de seguridad. Si estamos usando Spring Security, en &lt;code&gt;SecurityConfig.class&lt;/code&gt; debe haber algo como esto:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Bean&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; SecurityFilterChain &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;securityFilterChain&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(HttpSecurity http) throws Exception {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    http&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;authorizeHttpRequests&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(authRequest &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; authRequest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // otras configuraciones&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;requestMatchers&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(HttpMethod.POST, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/cookie&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;permitAll&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // otras configuraciones&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;anyRequest&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;authenticated&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // otras configuraciones&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; http.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;build&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con &lt;code&gt;.requestMatchers(HttpMethod.POST, &quot;/cookie&quot;).permitAll()&lt;/code&gt; la ruta &lt;code&gt;/cookie&lt;/code&gt; es ahora visible y ya podemos usarla desde el fragmento para cerrar nuestra notificación.&lt;/p&gt;
&lt;h1 id=&quot;un-ejemplo&quot;&gt;Un ejemplo&lt;/h1&gt;
&lt;p&gt;Puedes ver el código que implementan estos métodos, tanto las notificaciones como los mensajes fijos de cookies, en el repositorio de la aplicación &lt;a href=&quot;/blog/cartelera-daw&quot;&gt;Cartelera DAW&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/cartelera-daw&quot;&gt;Repositorio de Cartelera DAW&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/notificaciones.DrEXfhr5_Z1sRXMQ.webp"/><category>código</category><category>java</category><category>spring boot</category><category>bootstrap</category><category>thymeleaft</category><author>JavGuerra</author></item><item><title>Buscaminas en JavaScript</title><link>https://javguerra.github.io/blog/buscaminas</link><guid isPermaLink="true">https://javguerra.github.io/blog/buscaminas</guid><description>Pequeño juego online para manejo de eventos</description><pubDate>Thu, 28 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/buscaminas.BEDLb0fd_265uBE.webp&quot; alt=&quot;Buscaminas&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#bootstrap&lt;/em&gt;, &lt;em&gt;#jquery&lt;/em&gt;, &lt;em&gt;#juego&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Programé &lt;a href=&quot;https://javguerra.github.io/BuscaminasJS/index.html&quot;&gt;Buscaminas en JavaScript&lt;/a&gt; como un juego atípico que no consiste en evitar las minas, como estamos acostumbrados en los juegos de escritorio del mismo nombre, sino en hacerlas estallar.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/BuscaminasJS/index.html&quot;&gt;&lt;button&gt;Jugar a Buscaminas&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Una vez se genera el tablero con las dimensiones que deseemos, tendremos una serie de intentos para acertar la posición de las minas. Cada fallo cuenta, así como cada acierto. Termina la partida cuando se han superado el número de fallos posibles o cuando se encuentran todas las minas.&lt;/p&gt;
&lt;p&gt;Realicé este juego durante una semana, como práctica de programación de la asignatura de Desarrollo Web en Entorno Cliente de Formación Profesional de Grado Superior de Desarrollo de Aplicaciones Web (DAW).&lt;/p&gt;
&lt;p&gt;La aplicación, programada en JavaScript, usa Bootstrap y JQuery, es &lt;em&gt;cross-browser&lt;/em&gt; y compatible con navegadores antiguos, tiene diseño &lt;em&gt;responsive&lt;/em&gt;, cumple con los estándares W3C, de accesibilidad web y de accesibilidad de contenidos dinámicos (WAI-ARIA).&lt;/p&gt;
&lt;p&gt;Como ejercicio de programación, es un buen ejemplo de manejo de eventos en JavaScript para interactuar con las casillas del tablero.&lt;/p&gt;
&lt;h2 id=&quot;te-apetece-una-partidita&quot;&gt;¿Te apetece una partidita?&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/BuscaminasJS/index.html&quot;&gt;&lt;button&gt;Jugar a Buscaminas&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/JavGuerra/BuscaminasJS&quot;&gt;Ver el codigo fuente en Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;PS.: La ayuda depara alguna sorpresa… pero intenta jugar sin hacer trampa.&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/buscaminas.BEDLb0fd_265uBE.webp"/><category>portfolio</category><category>web</category><category>código</category><category>css</category><category>html</category><category>javascript</category><category>bootstrap</category><category>jquery</category><category>juego</category><author>JavGuerra</author></item><item><title>Carousel con Bootstrap</title><link>https://javguerra.github.io/blog/galeria-carousel</link><guid isPermaLink="true">https://javguerra.github.io/blog/galeria-carousel</guid><description>Una pequeña galería de fotos de ejemplo</description><pubDate>Fri, 29 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/galeria-vnzla.-8Rqrg6B_Z1gNkrA.webp&quot; alt=&quot;Galería Venezuela&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#viaje&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#bootstrap&lt;/em&gt;, &lt;em&gt;#fotografía&lt;/em&gt;, &lt;em&gt;#edición&lt;/em&gt;, &lt;em&gt;#venezuela&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Las primeras veces que viajé a Venezuela quedé impactado por su belleza y las gentes que allí conocí. Me inspiró para realizar esta &lt;a href=&quot;https://badared.com/javguerra/daw/galeria/&quot;&gt;galería de fotos&lt;/a&gt; de ejemplo para la asignatura de Diseño de Interfaces Web de Formación Profesional de Grado Superior de Desarrollo de Aplicaciones Web (DAW).&lt;/p&gt;
&lt;p&gt;La galería muestra un carousel de imágenes con Boortrap y JavaScript, es &lt;em&gt;responsive&lt;/em&gt; y cumple con los estándares web y de accesibilidad.&lt;/p&gt;
&lt;p&gt;Es un buen ejercicio para mostrar las posibilidades del diseño web con HTML y CSS.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://badared.com/javguerra/daw/galeria/&quot;&gt;&lt;button&gt;visita la galería de fotos&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La foto de esta entrada es un montaje que realicé con Gimp tomando como base las tres fotos de la galería componiendo con ellas un collage y aplicando filtros de envejecido.&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/galeria-vnzla.-8Rqrg6B_Z1gNkrA.webp"/><category>portfolio</category><category>web</category><category>viaje</category><category>código</category><category>css</category><category>html</category><category>javascript</category><category>bootstrap</category><category>fotografía</category><category>edición</category><category>venezuela</category><author>JavGuerra</author></item><item><title>Cartelera DAW</title><link>https://javguerra.github.io/blog/cartelera-daw</link><guid isPermaLink="true">https://javguerra.github.io/blog/cartelera-daw</guid><description>Proyecto final de FPGS DAW con Java y Spring Boot</description><pubDate>Thu, 20 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/cartelera-daw.CwIRaY5E_xNKzt.webp&quot; alt=&quot;Logo cartelera DAW&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#java&lt;/em&gt;, &lt;em&gt;#spring boot&lt;/em&gt;, &lt;em&gt;#bootstrap&lt;/em&gt;, &lt;em&gt;#thymeleaft&lt;/em&gt;, &lt;em&gt;#spring security&lt;/em&gt;, &lt;em&gt;#accesibilidad&lt;/em&gt;, &lt;em&gt;#responsive&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Recientemente he presentado mi proyecto fin de estudios de Formación Profesional de Grado Superior DAW. Era algo que llevaba aparcado durante demasiado tiempo y finalmente esta etapa se ha cerrado.&lt;/p&gt;
&lt;p&gt;El proyecto  ha consistido en una aplicación web monolítica, desarrollada en Java, usando el framework Spring Boot, y ha sido desplegada en el servicio de Railway.com.&lt;/p&gt;
&lt;h2 id=&quot;el-proyecto&quot;&gt;El proyecto&lt;/h2&gt;
&lt;p&gt;El proyecto Cartelera DAW desarrolla una plataforma web para mostrar información cinematográfica cuyos usuarios potenciales son los espectadores y las distribuidoras de películas, cines y salas de proyección.&lt;/p&gt;
&lt;p&gt;La plataforma, que está basada en &lt;strong&gt;Java&lt;/strong&gt; y &lt;strong&gt;Spring Boot&lt;/strong&gt;, utiliza un patrón Modelo-Vista-Controlador y una arquitectura cliente-servidor, haciendo uso del IDE &lt;strong&gt;IntelliJ IDEA&lt;/strong&gt;, de &lt;strong&gt;Maven&lt;/strong&gt; para la gestión del proyecto, de &lt;strong&gt;Git&lt;/strong&gt; y &lt;strong&gt;GitHub&lt;/strong&gt; para el versionado de código, de &lt;strong&gt;MySQL&lt;/strong&gt; e &lt;strong&gt;Hibernate&lt;/strong&gt; para la gestión de la base de datos y de una &lt;strong&gt;configuración LAMP dockerizada&lt;/strong&gt; para las pruebas. Para el despliegue se utilizaron tecnologías como &lt;strong&gt;Docker&lt;/strong&gt; y metodologías &lt;strong&gt;CI/CD&lt;/strong&gt;. Para el frontend se ha empleado el gestor de plantillas &lt;strong&gt;Tymeleaft&lt;/strong&gt; y &lt;strong&gt;Bootstrap&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Adicionalmente se proponen una serie de estrategias comerciales para garantizar la sostenibilidad del modelo empresarial del proyecto.&lt;/p&gt;
&lt;p&gt;Se elaboró una memoria de 70 páginas y una presentación.&lt;/p&gt;
&lt;p&gt;El objetivo era aprender y usar tecnologías nuevas no estudiadas en DAW.&lt;/p&gt;
&lt;p&gt;La calificación final ha sido de 9 de 10, y se ha llevado a cabo en un periodo de tres semanas.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/JavGuerra/cartelera-daw/main/src/main/resources/static/img/banner.png&quot; alt=&quot;Pantalla Cartelera DAW&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://cartelera-daw.up.railway.app/&quot;&gt;&lt;button&gt;Ver Cartelera DAW en línea&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;la-formación-previa&quot;&gt;La formación previa&lt;/h2&gt;
&lt;p&gt;Pero el proyecto no partía de cero. Durante los meses de enero y febrero, y hasta el 9 de marzo de 2023, participé en un curso de especialización en Java + Spring de la Fundación Adecco dentro del Proyecto Digital School Erasmus+&lt;/p&gt;
&lt;p&gt;Se trataba de una formación mentorizada que incluía un trabajo en grupo para desarrollar una aplicación web. En mi grupo de trabajo me encargué de la coordinación del equipo mediante Trello y de la planificación de las funcionalidades de la aplicación y las propuesta de mejora de la app. El grupo se llamaba Cinéfilos, y Cartelera DAW bebe de la estructura simple de aquella práctica que me sirvió para entender cómo funciona el framework.&lt;/p&gt;
&lt;p&gt;El proyecto ahora presentado ha cambiado mucho desde aquella versión, tanto en su estructura como en su diseño. Partía de un código inconcluso donde sólo se habían implementado los CRUDs básicos, con fallos de integridad y sin funcionalidades mínimas, pero ahora la aplicación ha sido probada y revisada en profundidad, y cuenta con características que refuerzan sus funcionalidades.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/JavGuerra/cartelera-daw&quot;&gt;&lt;button&gt;Ir al repositorio del proyecto&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En el curso, así como en la práctica, obtuve una calificación de 10/10.&lt;/p&gt;
&lt;h2 id=&quot;características&quot;&gt;Características&lt;/h2&gt;
&lt;p&gt;Además de los requisitos solicitados para el MVP, en la app se ha implementado:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Seguridad de rutas&lt;/li&gt;
&lt;li&gt;Registros de usuario&lt;/li&gt;
&lt;li&gt;Validaciones de formularios&lt;/li&gt;
&lt;li&gt;Automatizaciones&lt;/li&gt;
&lt;li&gt;Documentación con JavaDoc&lt;/li&gt;
&lt;li&gt;Implementación de Logs&lt;/li&gt;
&lt;li&gt;Notificaciones&lt;/li&gt;
&lt;li&gt;Despliegue dockerizado&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cuenta con:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Portada dinámica&lt;/li&gt;
&lt;li&gt;Diseño responsive&lt;/li&gt;
&lt;li&gt;Diseño accesible&lt;/li&gt;
&lt;li&gt;Aviso legal y privacidad&lt;/li&gt;
&lt;li&gt;Aviso de cookies&lt;/li&gt;
&lt;li&gt;Ayuda en línea&lt;/li&gt;
&lt;li&gt;Spinner loader&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Logo Cartelera-DAW&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/cartelera-daw.svg&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;desarrollo-y-despliegue&quot;&gt;Desarrollo y despliegue&lt;/h2&gt;
&lt;p&gt;Tanto en el desarrollo como en el despliegue ha jugado un papel importante Docker.&lt;/p&gt;
&lt;p&gt;La BBDD MySQL y PHPMyAdmin han sido lanzados usando contenedores gestionados con la herramienta Portainer.&lt;/p&gt;
&lt;p&gt;El despliegue se lleva a cabo tomando el código fuente y, mediante un dockerfile, construyendo la imagen del contenedor que es lanzado en el servidor.&lt;/p&gt;
&lt;p&gt;Spring Boot contiene un servidor Tomcat encargado de servir las páginas de la aplicación.&lt;/p&gt;
&lt;h2 id=&quot;indicaciones-de-instalación&quot;&gt;Indicaciones de instalación&lt;/h2&gt;
&lt;p&gt;Tras clonar el repositorio, es necesario crear un usuario en la BBDD relacional llamado «cartelera-daw» con el password que deseemos. Estos datos, así como el puerto por defecto de la app (8082), pueden ser introducidos en el fichero «aplication.propieties», en la carpeta resources.&lt;/p&gt;
&lt;p&gt;Cada vez que se inicia la aplicación, esta recarga los datos en la BBDD.&lt;/p&gt;
&lt;p&gt;Una vez iniciada la aplicación en local, se puede acceder a ella en la dirección: &lt;code&gt;http://localhost:8082&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;El acceso al panel de administración requiere de usuario y contraseña. Por defecto, la aplicación tiene un usuario «admin» y su contraseña es «admin».&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ADVERTENCIA&lt;/strong&gt;: Se recomienda que, tras el primer acceso, la contraseña de admin sea cambiada o se cree una nueva cuenta de usuario desde la que eliminar la cuenta «admin».&lt;/p&gt;
&lt;h2 id=&quot;licencia&quot;&gt;Licencia&lt;/h2&gt;
&lt;p&gt;Sobre el código fuente: GNU GENERAL PUBLIC LICENSE Version 3&lt;/p&gt;
&lt;h2 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/JavGuerra/cartelera-daw/a79cd41c51299dd3897d989ea8e045ea5f894ac7/src/main/resources/static/img/qr-app.svg&quot; alt=&quot;QR enlace a la Aplicación&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://cartelera-daw.up.railway.app/&quot;&gt;Aplicación&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/cartelera-daw&quot;&gt;Repositorio&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/cartelera-daw.CwIRaY5E_xNKzt.webp"/><category>portfolio</category><category>web</category><category>java</category><category>spring boot</category><category>bootstrap</category><category>thymeleaft</category><category>spring security</category><category>accesibilidad</category><category>responsive</category><author>JavGuerra</author></item><item><title>Recursos TIC</title><link>https://javguerra.github.io/blog/recursos-tic</link><guid isPermaLink="true">https://javguerra.github.io/blog/recursos-tic</guid><description>Proyecto final del curso de Java, Spring Boot y testing.</description><pubDate>Wed, 11 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/recursos-tic.DMmpqNPg_ZqU5V8.webp&quot; alt=&quot;Banner Recursos TIC&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#java&lt;/em&gt;, &lt;em&gt;#spring boot&lt;/em&gt;, &lt;em&gt;#bootstrap&lt;/em&gt;, &lt;em&gt;#thymeleaft&lt;/em&gt;, &lt;em&gt;#spring security&lt;/em&gt;, &lt;em&gt;#accesibilidad&lt;/em&gt;, &lt;em&gt;#responsive&lt;/em&gt;, &lt;em&gt;#selenium&lt;/em&gt;, &lt;em&gt;#api&lt;/em&gt;, &lt;em&gt;#swagger&lt;/em&gt;, &lt;em&gt;#javadoc&lt;/em&gt;, &lt;em&gt;#junit&lt;/em&gt;, &lt;em&gt;#mockito&lt;/em&gt;, &lt;em&gt;#docker&lt;/em&gt;, &lt;em&gt;#jacoco&lt;/em&gt;, &lt;em&gt;#github actions&lt;/em&gt;, &lt;em&gt;#ci-cd&lt;/em&gt;, &lt;em&gt;#sonarqube&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Recientemente he cursado una formación con Adecco, y este es mi proyecto fin de estudios, que ha consistido en desarrollar una aplicación que permita gestionar recursos TIC y listas de recursos, para realizar los tests correspondientes, aplicando los conocimientos aprendidos, y que ha sido desplegada en el servicio de Railway.com.&lt;/p&gt;
&lt;h2 id=&quot;el-proyecto&quot;&gt;El proyecto&lt;/h2&gt;
&lt;p&gt;La plataforma, que está basada en &lt;strong&gt;Java&lt;/strong&gt; y &lt;strong&gt;Spring Boot&lt;/strong&gt;, utiliza un patrón Modelo-Vista-Controlador y una arquitectura cliente-servidor, haciendo uso del IDE &lt;strong&gt;IntelliJ IDEA&lt;/strong&gt;, de &lt;strong&gt;Maven&lt;/strong&gt; para la gestión del proyecto, de &lt;strong&gt;Git&lt;/strong&gt; y &lt;strong&gt;GitHub&lt;/strong&gt; para el versionado de código, de &lt;strong&gt;MySQL&lt;/strong&gt;, &lt;strong&gt;H2&lt;/strong&gt; y el ORM &lt;strong&gt;Hibernate&lt;/strong&gt; para la gestión de la base de datos y de una &lt;strong&gt;configuración LAMP dockerizada&lt;/strong&gt; para las pruebas.&lt;/p&gt;
&lt;p&gt;Para el frontend se ha empleado el gestor de plantillas &lt;strong&gt;Tymeleaft&lt;/strong&gt; y &lt;strong&gt;Bootstrap&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Para los tests se ha usado &lt;strong&gt;JUnit&lt;/strong&gt;, &lt;strong&gt;Mockito&lt;/strong&gt;, &lt;strong&gt;Selenium&lt;/strong&gt;. la API se ha probado con &lt;strong&gt;Swagger&lt;/strong&gt; y las estadísticas se han generado con &lt;strong&gt;JaCoCo&lt;/strong&gt; y &lt;strong&gt;SonarQube&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Para el despliegue se utilizaron tecnologías como &lt;strong&gt;Docker&lt;/strong&gt; y metodologías &lt;strong&gt;CI/CD&lt;/strong&gt; con &lt;strong&gt;GitHub Actions&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;La planificación y codificación se han llevado a cabo usando &lt;strong&gt;Trello&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://recursos-tic.up.railway.app&quot;&gt;&lt;button&gt;Ver Recursos TIC en línea&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;destacados&quot;&gt;Destacados&lt;/h2&gt;
&lt;p&gt;Además de los requisitos del MVP, se han incluido las siguientes funcionalidades:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Diseño responsive, “mobile first”&lt;/li&gt;
&lt;li&gt;Web accesible AA. Testada con WAVE&lt;/li&gt;
&lt;li&gt;Seguridad por diseño&lt;/li&gt;
&lt;li&gt;Confirmaciones de borrado&lt;/li&gt;
&lt;li&gt;Implementación de login de usuarios&lt;/li&gt;
&lt;li&gt;Integra el editor TinyMCE&lt;/li&gt;
&lt;li&gt;Provee API REST e interfaz Swagger&lt;/li&gt;
&lt;li&gt;Incluye aviso legal, privacidad y cookies&lt;/li&gt;
&lt;li&gt;Documentación la aplicación con JavaDoc&lt;/li&gt;
&lt;li&gt;Usa el protocolo OpenGraph para RR.SS.&lt;/li&gt;
&lt;li&gt;Manifest para móviles (PWA)&lt;/li&gt;
&lt;li&gt;Desarrollada con Linux + Docker LAMP&lt;/li&gt;
&lt;li&gt;Despliegue&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;video&quot;&gt;Video&lt;/h1&gt;
&lt;p&gt;El proyecto fue presentado a empresas de tecnología, y se puede ver en el vídeo de la presentación del proyecto aquí:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/d_SeaUuKrMg&quot;&gt;&lt;button&gt;Video de la presentación&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;indicaciones-de-uso&quot;&gt;Indicaciones de uso&lt;/h1&gt;
&lt;h2 id=&quot;requisitos&quot;&gt;Requisitos&lt;/h2&gt;
&lt;p&gt;Para ejecutar el proyecto se requiere:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Java 23 o superior&lt;/li&gt;
&lt;li&gt;Maven&lt;/li&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;configuración&quot;&gt;Configuración&lt;/h2&gt;
&lt;p&gt;Actualmente la aplicación se ejecuta localmente en el puerto 8082.&lt;/p&gt;
&lt;p&gt;Puede construirse un contenedor Docker con la imagen de la aplicación ejecutando el fichero &lt;code&gt;docker.sh&lt;/code&gt; que hace uso de docker-compose para lanzar la aplicación y la BBDD que requiere.&lt;/p&gt;
&lt;p&gt;Para generar un informe de cobertura de testing, se puede ejecutar el comando &lt;code&gt;mvn site&lt;/code&gt; y acceder a él en el directorio &lt;code&gt;target/site/jacoco/index.html&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;autores&quot;&gt;Autores&lt;/h1&gt;
&lt;p&gt;Desarrollado por &lt;a href=&quot;https://github.com/JavGuerra&quot;&gt;Javier&lt;/a&gt; y &lt;a href=&quot;https://github.com/kevinzamoraa&quot;&gt;Kevin&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;licencia&quot;&gt;Licencia&lt;/h2&gt;
&lt;p&gt;Sobre el código fuente: GNU GENERAL PUBLIC LICENSE Version 3&lt;/p&gt;
&lt;h2 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/JavGuerra/recursos-tic-testing/refs/heads/main/src/main/resources/static/img/qr.svg&quot; alt=&quot;QR enlace a la Aplicación&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://recursos-tic.up.railway.app&quot;&gt;Aplicación&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://recursos-tic.up.railway.app/swagger-ui/index.html&quot;&gt;API REST&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/recursos-tic-testing&quot;&gt;Repositorio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/d_SeaUuKrMg&quot;&gt;Ver el vídeo de la presentación del proyecto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://recursos-tic.up.railway.app/doc/presentacion-recursos_tic.pdf&quot;&gt;Ver el PDF de la presentación&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://javguerra.github.io/blog/loader-thymeleaft/&quot;&gt;Spinner loader en Thymeleaft&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/recursos-tic.DMmpqNPg_ZqU5V8.webp"/><category>portfolio</category><category>web</category><category>java</category><category>spring boot</category><category>bootstrap</category><category>thymeleaft</category><category>spring security</category><category>accesibilidad</category><category>responsive</category><category>selenium</category><category>api</category><category>swagger</category><category>javadoc</category><category>junit</category><category>mockito</category><category>docker</category><category>jacoco</category><category>github actions</category><category>ci-cd</category><category>sonarqube</category><author>JavGuerra</author></item></channel></rss>