Spring MVC + Thymeleaf 3.0: Novos Recursos

Spring MVC + Thymeleaf 3.0: Novos Recursos

*1. Introdução *

Thymeleaf é um mecanismo de modelo Java para processar e criar HTML, XML, JavaScript, CSS e texto sem formatação. Para uma introdução ao Thymeleaf e Spring, dê uma olhada no link:/thymeleaf-in-spring-mvc [este artigo].

Neste artigo, discutiremos* novos recursos do Thymeleaf 3.0 *no Spring MVC com o aplicativo Thymeleaf. A versão 3 vem com novos recursos e muitas melhorias ocultas. Para ser mais específico, abordaremos os tópicos de processamento natural e embutimento de Javascript.

O Thymeleaf 3.0 inclui três novos modos de modelo de texto: TEXT, JAVASCRIPT e CSS - que devem ser usados ​​para processar modelos simples, JavaScript e CSS, respectivamente.

===* 2. Dependências do Maven *

Primeiro, vamos ver as configurações necessárias para integrar o Thymeleaf ao Spring; A biblioteca thymeleaf-spring é necessária em nossas dependências:

<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf</artifactId>
    <version>3.0.9.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring4</artifactId>
    <version>3.0.9.RELEASE</version>
</dependency>

Observe que, para um projeto do Spring 4, a biblioteca thymeleaf-spring4 deve ser usada em vez de thymeleaf-spring5. A versão mais recente das dependências pode ser encontrada https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.thymeleaf%22%20AND%20a%3A%22thymeleaf-spring5%22 [ aqui].

===* 3. Configuração Java Thymeleaf *

Primeiro, precisamos configurar o novo mecanismo de modelos, a exibição e os resolvedores de modelos. Para fazer isso, precisamos atualizar a classe de configuração Java, criada

Para fazer isso, precisamos atualizar a classe de configuração Java, criada no link:/thymeleaf-in-spring-mvc [aqui]. Além dos novos tipos de resolvedores, nossos modelos estão implementando a interface Spring ApplicationContextAware:

@Configuration
@EnableWebMvc
@ComponentScan({ "com..thymeleaf" })
public class WebMVCConfig implements WebMvcConfigurer, ApplicationContextAware {

    private ApplicationContext applicationContext;

   //Java setter

    @Bean
    public ViewResolver htmlViewResolver() {
        ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        resolver.setTemplateEngine(templateEngine(htmlTemplateResolver()));
        resolver.setContentType("text/html");
        resolver.setCharacterEncoding("UTF-8");
        resolver.setViewNames(ArrayUtil.array("*.html"));
        return resolver;
    }

    @Bean
    public ViewResolver javascriptViewResolver() {
        ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        resolver.setTemplateEngine(templateEngine(javascriptTemplateResolver()));
        resolver.setContentType("application/javascript");
        resolver.setCharacterEncoding("UTF-8");
        resolver.setViewNames(ArrayUtil.array("*.js"));
        return resolver;
    }

    @Bean
    public ViewResolver plainViewResolver() {
        ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        resolver.setTemplateEngine(templateEngine(plainTemplateResolver()));
        resolver.setContentType("text/plain");
        resolver.setCharacterEncoding("UTF-8");
        resolver.setViewNames(ArrayUtil.array("*.txt"));
        return resolver;
    }
}

Como podemos observar acima, criamos três resolvedores de vista diferentes - um para visualizações HTML, um para arquivos Javascript e outro para arquivos de texto sem formatação. O Thymeleaf irá diferenciá-los verificando extensões de nome de arquivo - .html, .js e .txt, respectivamente.

Também criamos a classe estática ArrayUtil, para usar o método _array () _ que cria a matriz _String [] _ ​​necessária com nomes de exibição.

Na próxima parte desta classe, precisamos configurar o mecanismo de modelo:

private ISpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
    SpringTemplateEngine engine = new SpringTemplateEngine();
    engine.setTemplateResolver(templateResolver);
    return engine;
}

Por fim, precisamos criar três resolvedores de modelos separados:

private ITemplateResolver htmlTemplateResolver() {
    SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
    resolver.setApplicationContext(applicationContext);
    resolver.setPrefix("/WEB-INF/views/");
    resolver.setCacheable(false);
    resolver.setTemplateMode(TemplateMode.HTML);
    return resolver;
}

private ITemplateResolver javascriptTemplateResolver() {
    SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
    resolver.setApplicationContext(applicationContext);
    resolver.setPrefix("/WEB-INF/js/");
    resolver.setCacheable(false);
    resolver.setTemplateMode(TemplateMode.JAVASCRIPT);
    return resolver;
}

private ITemplateResolver plainTemplateResolver() {
    SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
    resolver.setApplicationContext(applicationContext);
    resolver.setPrefix("/WEB-INF/txt/");
    resolver.setCacheable(false);
    resolver.setTemplateMode(TemplateMode.TEXT);
    return resolver;
}

Observe que, para testar, é melhor usar modelos não armazenados em cache, por isso é recomendável usar o método _setCacheable (false) _.

Os modelos Javascript serão armazenados na pasta /WEB-INF/js/, arquivos de texto sem formatação na pasta /WEB-INF/txt/ e, finalmente, o caminho para os arquivos HTML é /WEB-INF/html.

*4. Configuração do controlador de mola *

Para testar nossa nova configuração, criamos o seguinte controlador Spring:

@Controller
public class InliningController {

    @RequestMapping(value = "/html", method = RequestMethod.GET)
    public String getExampleHTML(Model model) {
        model.addAttribute("title", "Baeldung");
        model.addAttribute("description", "<strong>Thymeleaf</strong> tutorial");
        return "inliningExample.html";
    }

    @RequestMapping(value = "/js", method = RequestMethod.GET)
    public String getExampleJS(Model model) {
        model.addAttribute("students", StudentUtils.buildStudents());
        return "studentCheck.js";
    }

    @RequestMapping(value = "/plain", method = RequestMethod.GET)
    public String getExamplePlain(Model model) {
        model.addAttribute("username", SecurityContextHolder.getContext()
          .getAuthentication().getName());
        model.addAttribute("students", StudentUtils.buildStudents());
        return "studentsList.txt";
    }
}

No exemplo do arquivo HTML, mostraremos como usar o novo recurso embutido, com e sem escape de tags HTML.

Para o exemplo do JS, geraremos uma solicitação AJAX, que carregará o arquivo js com as informações dos alunos. Observe que estamos usando o método buildStudents () _ simples dentro da classe _StudentUtils, neste link:/thymeleaf-in-spring-mvc [article].

Finalmente, no exemplo de texto sem formatação, mostraremos as informações dos alunos como um arquivo de texto. Um exemplo típico de uso do modo de modelo de texto sem formatação pode ser usado para o envio de email em texto sem formatação.

Como um recurso adicional, usaremos SecurityContextHolder, para obter o nome de usuário registrado.

===* 5. Arquivos de exemplo de HTML/Js/Text *

A última parte deste tutorial é criar três tipos diferentes de arquivos e testar o uso dos novos recursos do Thymeleaf. Vamos começar com o arquivo HTML:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Inlining example</title>
</head>
<body>
    <p>Title of tutorial: [[title}]]</p>
    <p>Description: [(${description})]</p>
</body>
</html>

Neste arquivo, usamos duas abordagens diferentes. Para exibir o título, usamos a sintaxe de escape, que removerá todas as tags HTML, resultando na exibição apenas de texto. No caso da descrição, usamos sintaxe sem escape, para manter as tags HTML. O resultado final ficará assim:

<p>Title of tutorial: Baeldung</p>
<p>Description: <strong>Thymeleaf</strong> tutorial</p>

que obviamente serão analisados ​​pelo nosso navegador, exibindo a palavra Thymeleaf com um estilo arrojado.

Em seguida, passamos a testar os recursos do modelo js:

var count = [[students.size()}]];
alert("Number of students in group: " + count);

Os atributos no modo de modelo JAVASCRIPT não terão escape de JavaScript. Isso resultará na criação de um alerta js. Carregamos esse alerta, usando o jQuery AJAX, no arquivo listStudents.html:

<script>
    $(document).ready(function() {
        $.ajax({
            url : "/spring-thymeleaf/js",
            });
        });
</script>

A última, mas não a menor função, que queremos testar é a geração de arquivos de texto sem formatação. Criamos o arquivo studentsList.txt com o seguinte conteúdo:

Dear [(${username})],

This is the list of our students:
[# th:each="s : ${students}"]
   - [(${s.name})]. ID: [(${s.id})]
[/]
Thanks,
The Baeldung University

Observe que, como nos modos de modelo de marcação, os Dialetos padrão incluem apenas um elemento processável (_ [#…]) _ e um conjunto de atributos processáveis ​​(th: text, th: utext, th: if, th: a menos, th : each, etc.). O resultado será um arquivo de texto, que podemos usar, por exemplo, no e-mail, como mencionado no final da Seção 3.

*Como testar?* Nossa sugestão é jogar primeiro com o navegador e, em seguida, verificar o teste JUnit existente.

6. Conclusão

Neste artigo, discutimos novos recursos implementados na estrutura Thymeleaf com foco na versão 3.0.

A implementação completa deste tutorial pode ser encontrada em o projeto GitHub - este é um projeto baseado no Eclipse, fácil de testar em todos os ambientes modernos Navegador de internet.

Por fim, se você planeja migrar um projeto da versão 2 para esta versão mais recente, consulte aqui no guia de migração. E observe que seus modelos Thymeleaf existentes são quase 100% compatíveis com o Thymeleaf 3.0, portanto, você precisará fazer apenas algumas modificações na sua configuração.