/java/

JEE + JAX-RS + Thymeleaf + Layout-dialect (way4)

2016-05-09 23:29:16

https://github.com/szalek/JEE-Thymeleaf-Layout

pom.xml

<?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?>

<project http:="" maven-4.0.0.xsd&quot;="" maven.apache.org="" xmlns='"http://maven.apache.org/POM/4.0.0"' xmlns:xsi='"http://www.w3.org/2001/XMLSchema-instance"' xsd="" xsi:schemalocation='"http://maven.apache.org/POM/4.0.0'>
<modelversion>4.0.0</modelversion>
<groupid>pl.btbw</groupid>
<artifactid>jeeThymeleaf2</artifactid>
<version>1.0</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupid>javax</groupid>
<artifactid>javaee-api</artifactid>
<version>7.0</version>
</dependency>
<dependency>
<groupid>org.thymeleaf</groupid>
<artifactid>thymeleaf</artifactid>
<version>2.1.4.RELEASE</version>
</dependency>
<dependency>
<groupid>nz.net.ultraq.thymeleaf</groupid>
<artifactid>thymeleaf-layout-dialect</artifactid>
<version>1.3.3</version>
</dependency>
</dependencies>
<build>
<finalname>jeet2</finalname>
<plugins>
<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-compiler-plugin</artifactid>
<configuration>
<source/>1.8
                    <target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactid>maven-war-plugin</artifactid>
<configuration>
<failonmissingwebxml>false</failonmissingwebxml>
</configuration>
</plugin>
</plugins>
</build>
</project>

./src/main/resources/templates/layout/default.html

<!DOCTYPE html>

<html lang='"en"' xmlns:layout='"http://www.ultraq.net.nz/thymeleaf/layout"' xmlns:th='"http://www.thymeleaf.org"'>
<head>
<meta charset="utf-8"/>
<title>jee Thymeleaf</title>
</head>
<body>
<div class='"container"'>
<hr/>
<h1>main</h1>
<img 35px;&quot;="" style='"padding:' th:src='"@{/static/img/opimoto.jpg}"'/>
<hr/>
<h1>fragment</h1>
<div ::="" test&quot;="" th:replace='"fragments.html'></div>
<hr/>
<h1>layout</h1>
<section layout:fragment='"content"'>Page content</section>
</div>
</body>
</html>

./src/main/resources/templates/fragments.html

<!DOCTYPE html>

<html xmlns:th='"http://www.thymeleaf.org"'>
<body>
<div th:fragment='"test"'>
<ul>
<li>1 ...</li>
<li>2 ...</li>
<li>3 ...</li>
</ul>
</div>
</body>
</html>

./src/main/resources/templates/home.html

<!DOCTYPE html>

<html lang='"en"' layout:decorator='"layout/default.html"' xmlns:layout='"http://www.ultraq.net.nz/thymeleaf/layout"' xmlns:th='"http://www.thymeleaf.org"'>
<body>
<div layout:fragment='"content"'>
<p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
        In euismod neque ut quam placerat tristique.
        Duis sodales, lorem eu dignissim venenatis, leo ligula cursus augue, ac gravida est nisl ut massa.
        Cras quis euismod tellus.
        Aliquam eros mauris, aliquam facilisis velit sit amet, cursus rutrum libero.
        Integer lacinia sed magna at vehicula. Etiam pellentesque, urna ut malesuada malesuada, lacus justo pretium ante,
        at pharetra orci sapien in tortor. Nulla facilisi. Duis egestas condimentum risus in varius.
        Vestibulum sodales dolor ipsum, non pretium eros commodo quis. Interdum et malesuada fames ac
        ante ipsum primis in faucibus. Morbi vestibulum luctus feugiat. Pellentesque ultrices dictum nulla,
        sed ullamcorper ipsum. Cras sed ultricies est, sit amet blandit diam. Duis sodales ligula ac sodales vestibulum.
        Morbi mattis ultricies mauris, auctor varius mauris vehicula nec.
    </p>
</div>
</body>
</html>

HtmlResponse

package pl.btbw.core.thymeleaf;

import java.util.HashMap;
import java.util.Map;

public class HtmlResponse {

    public String templateName;
    public Map

<string, object=""> model = new HashMap&lt;&gt;();

    public HtmlResponse(String templateName) {
        this.templateName = templateName;
    }

    public HtmlResponse add(String modelName, Object model) {
        this.model.put(modelName, model);
        return this;
    }
}

HtmlResponseMessageBodyWriter

package pl.btbw.core.thymeleaf;

import nz.net.ultraq.thymeleaf.LayoutDialect;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

@Provider
@Produces(MediaType.TEXT_HTML)
public class HtmlResponseMessageBodyWriter implements MessageBodyWriter<htmlresponse> {

    @Context
    private HttpServletRequest httpRequest;

    @Context
    private HttpServletResponse httpResponse;

    @Context
    private ServletContext servletContext;

    private static TemplateEngine templateEngine;

    static {
        templateEngine = new TemplateEngine();
        ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
        resolver.setPrefix("templates/");
//        resolver.setSuffix(".html");
        templateEngine.setTemplateResolver(resolver);
        templateEngine.addDialect(new LayoutDialect());
    }

    @Override
    public void writeTo(
            HtmlResponse response,
            Class<? > type,
            Type genericType,
            Annotation[] annotations,
            MediaType mediaType,
            MultivaluedMap<string, object=""> httpHeaders,
            OutputStream entityStream) throws IOException, WebApplicationException {

        WebContext context = new WebContext(httpRequest, httpResponse, servletContext);
        response.model.forEach((k, v) -&gt; context.setVariable(k, v));
        Writer writer = new OutputStreamWriter(entityStream);
        templateEngine.process(response.templateName, context, writer);
        writer.flush();
    }

    @Override
    public long getSize(HtmlResponse arg0, Class<? > arg1, Type arg2, Annotation[] arg3, MediaType arg4) {
        return -1;
    }

    @Override
    public boolean isWriteable(Class<? > type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return HtmlResponse.class.isAssignableFrom(type);
    }

}

HomeController

package pl.btbw.module.home;

import pl.btbw.core.thymeleaf.HtmlResponse;

import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("/")
public class HomeController {

    @Path("/")
    @GET
    public HtmlResponse home() {
        return new HtmlResponse("home.html");
    }
}

MyApplication

package pl.btbw.core;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/app")
public class MyApplication extends Application {
}