jersey-thymeleaf using ViewProcessor

結局つくったー。
https://github.com/bufferings/jersey-thymeleaf

使い方は、Viewableにテンプレート名とモデルを渡すだけです。
文字列だけのバージョンと、POJOを渡すバージョンを試してみました。

@Path("/hello")
public class HelloResource {

  @GET
  @Path("/{n}")
  @Produces(MediaType.TEXT_HTML)
  public Viewable sayHello(@PathParam("n") String name) {
    return new Viewable("sample", "Hello " + name + "!");
  }

  @GET
  @Produces(MediaType.TEXT_HTML)
  public Viewable sayHello2() {
    return new Viewable("sample2",
        new SampleModel("Good morning", "my friends"));
  }

  public static class SampleModel {
    public String greeting;
    public String name;

    public SampleModel(String greeting, String name) {
      this.greeting = greeting;
      this.name = name;
    }
  }
}

モデルは"it"として参照できます。ThymeleafだからHTMLとしても開ける感じが気持ちいいですね。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:th="http://www.thymeleaf.org">

<head>
<title>hello</title>
</head>

<body>
	<p th:text="${it.greeting} + ', ' + ${it.name} + '!'">message</p>
</body>
</html>

裏側はViewProcessorを使ってます。
Providerアノテーションをつけてるので自動で使用されます。

@Provider
public class ThymeleafViewProcessor implements ViewProcessor<String> {
  @Context
  ServletContext servletContext;

  @Context
  ThreadLocal<HttpServletRequest> requestInvoker;

  @Context
  ThreadLocal<HttpServletResponse> responseInvoker;

  TemplateEngine templateEngine;

  public ThymeleafViewProcessor() {
    TemplateResolver templateResolver = new ServletContextTemplateResolver();
    templateResolver.setPrefix("/WEB-INF/templates/");
    templateResolver.setSuffix(".html");
    templateResolver.setTemplateMode("HTML5");
    templateResolver.setCacheTTLMs(3600000L);

    templateEngine = new TemplateEngine();
    templateEngine.setTemplateResolver(templateResolver);
  }

  @Override
  public String resolve(final String path) {
    return path;
  }

  @Override
  public void writeTo(final String resolvedPath, final Viewable viewable,
      final OutputStream out) throws IOException {
    // Commit the status and headers to the HttpServletResponse
    out.flush();

    WebContext context = new WebContext(requestInvoker.get(),
        responseInvoker.get(), servletContext, requestInvoker.get().getLocale());
    Map<String, Object> variables = new HashMap<>();
    variables.put("it", viewable.getModel());
    context.setVariables(variables);
    templateEngine.process(viewable.getTemplateName(), context, responseInvoker
        .get().getWriter());
  }
}

スッキリしたー。