Статьи

Тимьян с JavaEE 8

Фон

В нашей организации (и, как я полагаю, как и для многих других) Apache Tiles был основой для рендеринга представлений на основе шаблонов. И он отлично работал с Spring. В последние годы тимелист превратился в зрелую и многофункциональную технологию просмотра.

Несколько недель назад я начал оценивать Thymeleaf как замену Apache Tiles и полюбил его с самого начала. Хотя для Thymeleaf + Spring есть несколько статей, для JavaEE их немного; Поэтому решил написать один для тех, кому это интересно.

Цель этой статьи — дать краткое введение в настройку Thymeleaf как технологии представления и шаблонов с использованием MVC 1.0, указанного в JavaEE 8.

Основы

web.xml

Вот простой web.xml. Поскольку мы будем использовать конфигурацию на основе аннотаций, здесь особо нечего включать.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

</web-app>

beans.xml

В этом файле также нет ничего особенного, за исключением того, что bean-discovery-mode имеет значение all. Это обеспечит настройку сервером приложений всех аннотированных bean-компонентов.

<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
                      http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
    bean-discovery-mode="all">

</beans>

Библиотеки







DZone: Programming & DevOps news, tutorials & tools

В первую очередь нам понадобятся библиотеки для спецификации MVC 1.0 и ее эталонной реализации наряду с основными ядрами Thymeleaf. Пожалуйста, найдите ссылки на эти библиотеки в справочном разделе в конце статьи.

Настройка все …

Настройка приложения

Первым шагом является настройка нашего приложения JAX-RS. Создайте класс Application (или любой другой, какой вам нравится) с аннотацией @ApplicationPath. Аргумент этой аннотации станет путем приложения после развертывания.

@ApplicationPath("api")
public class Application extends javax.ws.rs.core.Application
{
private static final Logger logger = LogManager.getLogger(Application.class);
}

Настройка контроллера

Если вы знакомы с JAX-RS, настройка контроллера MVC 1.0 не будет большой откровением. Есть несколько вещей, чтобы заметить —

  1. Контейнер может внедрять модели (аналогично другим ресурсам). Методы контроллера могут устанавливать атрибуты модели, аналогичные атрибутам HashMap.

  2. Аннотируйте свой класс с помощью @Controller. Эта аннотация предоставляется спецификацией MVC 1.0, которая указывает контейнеру обрабатывать этот класс как контроллер MVC.  

Ниже приведен код контроллера для обслуживания страницы входа в систему.

@Path("login")
@Controller
public class LoginController
{
@Inject
Models models;

private static final Logger logger = LogManager.getLogger(LoginController.class);

@GET
@Produces(MediaType.TEXT_HTML)
public String viewLogin()
{
models.put("company", "Acme Products");
models.put("product", "JavaEE 8 Bootstrap");
return "login";
}
}

Метод viewLogin возвращает строку «login», указывающую, что представление с именем «login» должно быть обслужено. 

Настройка Thymeleaf

Следующий код показывает, как настроить Thymeleaf для обслуживания контента на основе «представления», возвращаемого контроллером. 

@ApplicationScoped
public class ThymeleafViewEngine
extends ViewEngineBase
{

@Inject
private ServletContext servletContext;

private TemplateEngine engine;

@Override
public boolean supports(String view)
{
return !view.contains(".");
}

@PostConstruct
public void postConstruct()
{
TemplateResolver resolver = new ServletContextTemplateResolver();

resolver.setPrefix("/WEB-INF/layouts/");
resolver.setSuffix(".xhtml");
resolver.setTemplateMode(StandardTemplateModeHandlers.XHTML.getTemplateModeName());
resolver.setCacheable(false);

engine = new TemplateEngine();
engine.setTemplateResolver(resolver);
}

@Override
public void processView(ViewEngineContext context) throws ViewEngineException
{
try
{
HttpServletRequest request = context.getRequest();
HttpServletResponse response = context.getResponse();
WebContext ctx = new WebContext(request, response, servletContext, request.getLocale());

ctx.setVariables(context.getModels());
request.setAttribute("view", context.getView());

engine.process(context.getView().equals("login") ? "login-template":"default-template", ctx, response.getWriter());
}
catch (IOException e)
{
throw new ViewEngineException(e);
}
}
}

Вот что делает приведенный выше код:

  1. Класс расширяет ViewEngineBase и аннотируется как @ApplicationScoped. Это позволяет рассматривать этот класс как MVC ViewEngine и использовать, когда контроллер возвращает представление.

  2.  Метод postConstruct () инициализирует механизм шаблонов Thymeleaf с каталогом шаблонов, а режим шаблона устанавливается как HTML5 
  3. Для производственной среды рекомендуется resolver.setCacheable (true).
  4. Метод processView () вызывается, когда контроллер возвращает представление, в данном случае представление «login».
  5. Шаблоны Thymeleaf не могут напрямую обращаться к модели MVC, поэтому модель копируется в контекст Thymeleaf с помощью  ctx.setVariables (context.getModels ());
  6. В случае Apache Tiles единое представление представляет шаблон и его подкомпоненты с использованием конфигурации XML. Чтобы достичь этого с Thymeleaf, представление, возвращаемое контроллером, используется для установки шаблона, который будет использоваться. Таким образом, с  context.getView (). Equals («вход в систему»)? «login-template»: «default-template»,  мы настраиваем login-шаблон для представления «login» и default-template для остальных представлений.
  7. Затем мы устанавливаем имя представления в качестве атрибута запроса, чтобы мы могли указать шаблону, где искать его компоненты содержимого, относящиеся к его представлению. 

Настройка шаблона просмотра

Следующий код является типичным шаблоном для визуализации представления. Шаблон использовал переменную области видимости $ {view} для замены значения «view» в шаблоне.

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

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />

<!-- Favicon -->

<link rel="icon" type="image/x-icon" th:href="@{/images/favicon.ico}" />

<!-- Common styles -->

<link rel="stylesheet" type="text/css" th:href="@{/styles/common.css}" />
<link rel="stylesheet" type="text/css" th:href="@{/styles/form.css}" />

<!-- View specific styles -->

<link rel="stylesheet" type="text/css" th:href="@{/styles/login-layout.css}" />

<th:block th:include="${view} :: styles" />

<!-- Common scripts -->

<script type="text/javascript" th:src="@{/scripts/jquery-2.1.3.min.js}"></script>
<script type="text/javascript" th:src="@{/scripts/velocity.min.js}"></script>
<script type="text/javascript" th:src="@{/scripts/commonts.js}"></script>
<script type="text/javascript" th:src="@{/scripts/form.js}"></script>

<!-- View specific scripts -->

<script type="text/javascript" th:src="@{/scripts/login.js}"></script>

<th:block th:include="${view} :: scripts" />

</head>
<body>

<div class="body">
<div class="page">

<div class="branding">

<div class="company-branding" th:text="${company}">Some Default Company</div>
<div class="product-branding" th:text="${product}">Bootstrap</div>

</div>

<div th:replace="${view} :: page">
</div>
</div>
</div>
</body>
</html>

Структура каталогов для веб-контента, как показано ниже —

Настройка «просмотра»

Представление входа в систему (login.xhtml) определяет различные компоненты содержимого, которые будут включены в шаблон при отображении полной страницы.

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

<head th:fragment="styles">
</head>

<head th:fragment="scripts">
</head>

<body th:fragment="page">

<form class="login-form" name="login-form" method="post" th:action="@{/login.json}">

<h2 class="form-header">Customer Login</h2>

<div class="form-body">
<div class="field-wrapper">
<label><input type="text" name="user-name" value="" placeholder="User Name" autocomplete="off" /></label>
</div>
<div class="field-wrapper">
<label><span /> <input type="password" name="password" value="" placeholder="Password" autocomplete="off" /></label>
</div>
</div>

<div class="form-options">
<a th:href="@{/forgot-password}">Forgot Password</a>
<a th:href="@{/sign-up}">Sign Up</a>
</div>

<div class="form-footer">
<input type="submit" value="Login" />
<input type="reset" value="Cancel" />
</div>
</form>

</body>
</html>

развертывание

Мы развернем наше приложение на glassfish, поскольку это единственный сервер приложений, который поддерживает черновую спецификацию MVC 1.0 и поставляется в комплекте с его эталонной реализацией. После развертывания приложения перейдите по  адресу http: // localhost: 8080 / JavaEE / api / login  для просмотра страницы входа (при условии, что ваше приложение использует JavaEE в качестве пути к контексту).

Предложения?

Пожалуйста, оставьте комментарий для любого предложения.

Исходный код

Пожалуйста, посетите https://github.com/kedar-joshi/Thymeleaf-JavaEE-MVC  для источников

Ссылки

  1. Основная структура проекта  https://dzone.com/articles/java-ee-8-mvc-getting-started-with-ozark

  2. Для JavaEE 8 ссылка  https://javaee8.zeef.com/arjan.tijms

  3. Для основ MVC 1.0  http://www.bennet-schulz.com/2015/10/javaee-mvc-controllers.html  и  http://www.mscharhag.com/java-ee-mvc/a-detailed-look- на MVC-контроллеров

  4. Ссылка на домашнюю страницу MVC 1.0  https://ozark.java.net/

  5. Для загрузки Thymeleaf и документации  http://www.thymeleaf.org/download.html  и  http://www.thymeleaf.org/doc/articles/layouts.html

  6. Для пользовательских макетов Thyemleaf  http://blog.codeleak.pl/2013/11/thymeleaf-template-layouts-in-spring.html