Spring MVC ThemeResolver

En este tutorial Spring MVC veremos como el framework nos facilita en trabajo con los temas, con ellos es fácil cambiar el estilo y diseño de nuestra aplicación web, podemos darle al usuario la opción elegir el tema que mas le guste, un tema puede estar conformado por diversos recursos como: archivos CSS, imágenes, etc., la aplicación que crearemos en este curso nos permitirá cambiar el tema solo con hacer clic en el enlace correspondiente.

Para utilizar los temas en aplicación Java Spring MVC debemos configurar los siguientes componentes:

@EnableWebMvc
@Configuration
@ComponentScan(basePackages = {"carmelo.spring.controller"})
public class WebAppConfig extends WebMvcConfigurerAdapter {

    @Bean
    public ResourceBundleThemeSource themeSource() {
        ResourceBundleThemeSource themeSource = new ResourceBundleThemeSource();
        themeSource.setBasenamePrefix("themes.tema-");
        return themeSource;
    }

    @Bean
    public CookieThemeResolver themeResolver() {
        CookieThemeResolver resolver = new CookieThemeResolver();
        resolver.setDefaultThemeName("oscuro");
        resolver.setCookieName("cookie-theme");
        return resolver;
    }

    @Bean
    public ThemeChangeInterceptor themeChangeInterceptor() {
        ThemeChangeInterceptor interceptor = new ThemeChangeInterceptor();
        interceptor.setParamName("mytheme");
        return interceptor;
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
       registry.addInterceptor(themeChangeInterceptor());
    }

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.jsp("/WEB-INF/views/", ".jsp");
    }

}

Para utilizar los temas en una aplicación web Java Spring MVC requerimos los siguientes tres componentes: ThemeSource, ThemeResolver y ThemeChangeInterceptor, a continuación se explica como definir y configurar cada uno de ellos.

Spring MVC ThemeSource

Esta interface es la encargada de resolver el tema, es decir ubicará el archivo .properties que contiene los elementos que definen el tema, por ejemplo: CSS, imágenes, etc., tendremos un archivo por cada tema que deseemos agregar a nuestra aplicación.

@Bean
public ResourceBundleThemeSource themeSource() {
    ResourceBundleThemeSource themeSource = new ResourceBundleThemeSource();
    themeSource.setBasenamePrefix("themes.tema-");
    return themeSource;
}

La propiedad basenamePrefix define el nombre y ubicación de los archivos, "themes.tema-" indica que los archivos se localizaran en el paquete themes y sus nombres empiezan por tema-, la carpeta raíz donde se iniciará la búsqueda es src/main/resources.

spring mvc themes

El contenido de estos archivos es el siguiente:

src/main/resources/themes/tema-claro.properties

stylesheet=css/claro.css
name=THEME-CLARO

src/main/resources/themes/tema-oscuro.properties

stylesheet=css/oscuro.css
name=THEME-OSCURO

Cada uno de estos archivo define los recursos usados por el respectivo tema, en este pequeño ejemplo solo usamos estilos CSS aunque podemos agregar mas recursos según el tema los necesite.

Los archivos CSS se definen de la siguiente manera:

webapp/css/oscuro.css

body {
    color: whitesmoke;
    background-color: darkgray;
}

webapp/css/claro.css

body {
    color: darkslategray;
    background-color: whitesmoke;
}

Para que la vista JSP pueda tener acceso a estos recursos es necesario hacer lo siguiente:

@Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
    }

spring mvc agregar archivos css

Hecho esto la vista JSP puede acceder a los recursos del tema usando la etiqueta <spring:theme />, por ejemplo podríamos obtener el CSS correspondiente al tema, mas adelante veremos un ejemplo de su uso.

Spring MVC ThemeResolver

Las clases que implementan esta interface establecen el método usado para almacenar y obtener el tema, tenemos:

FixedThemeResolver: permite establecer un tema de manera predeterminada, usando el método defaultThemeName("...") en donde deberemos indicar el nombre del tema que aplicaremos, por ejemplo: defaultThemeName("claro") que corresponde al archivo tema-claro.properties, con esta clase no es posible cambiar el tema.

@Bean
public FixedThemeResolver themeResolver() {
    FixedThemeResolver resolver = new FixedThemeResolver();
    resolver.setDefaultThemeName("claro");
    return resolver;
}

SessionThemeResolver: guarda el tema en una sesión HTTP, para establecer el tema que se aplicará por defecto deberemos utilizar el método setDefaultThemeName("..."), por ejemplo, setDefaultThemeName("oscuro") que corresponde al archivo tema-oscuro.properties.

@Bean
public SessionThemeResolver themeResolver() {
    SessionThemeResolver resolver = new SessionThemeResolver();
    resolver.setDefaultThemeName("oscuro");
    return resolver;
}

CookieThemeResolver: almacena el tema en una cookie, podemos usar los correspondientes métodos set para establecer el nombre, tiempo de expiración, etc., de la cookie, esta es la opción que usaremos en nuestra aplicación de ejemplo.

@Bean
public CookieThemeResolver themeResolver() {
    CookieThemeResolver resolver = new CookieThemeResolver();
    resolver.setDefaultThemeName("oscuro");
    resolver.setCookieName("cookie-theme");
    return resolver;
}

El tema que aplicamos por defecto es oscuro, el nombre de la cookie es cookie-theme.

Spring MVC ThemeChangeInterceptor

Este componente es interceptor que nos permitirá cambiar el tema, para ello se utilizara un parámetro en la URL, este debe contener el nombre del tema que deseamos aplicar, este componente se define de la siguiente manera:

@Bean
public ThemeChangeInterceptor themeChangeInterceptor() {
    ThemeChangeInterceptor interceptor = new ThemeChangeInterceptor();
    interceptor.setParamName("mytheme");
    return interceptor;
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(themeChangeInterceptor());
}

El método setParamName("mytheme") establece el nombre del parámetro para nosotros, mytheme, de modo que si deseamos cambiar el tema usaríamos por ejemplo:

  • http://localhost:8084/springtheme/?mytheme=oscuro
  • http://localhost:8084/springtheme/?mytheme=claro

Debemos registrar el interceptor para que Spring MVC puede utilizarlo.

En la vista JSP accedemos a los recursos del tema actual usando <spring:theme code="..." /> en code debemos indicar el nombre del recurso que deseamos obtener.

<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>

<html>
    <head>
        <link rel="stylesheet" href="<spring:theme code='stylesheet'/>" type="text/css" />
        <title>Spring MVC ThemeResolver</title>
    </head>
    <body>

        <h1>Spring MVC ThemeResolver</h1>
        <h3>Tema actual: <spring:theme code='name'/> </h3>
        aplicar tema: <a href="?mytheme=claro">claro</a> | <a href="?mytheme=oscuro">oscuro</a>

    </body>
</html>

El resultado final es el siguiente:

Spring MVC ThemeResolver

Spring MVC ThemeResolver

Si utilizas el motor de plantillas Thymeleaf puedes acceder a los recursos del tema usando la expresión #themes.code(...) la cual es equivalente a la etiqueta JSP <spring:theme code="..." />

Comentarios

Temas relacionados

Entradas populares de este blog

tkinter Grid

tkinter Canvas

Histogramas OpenCV Python

Python Binance API