Фон
В нашей организации (и, как я полагаю, как и для многих других) 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>
Библиотеки
В первую очередь нам понадобятся библиотеки для спецификации 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 не будет большой откровением. Есть несколько вещей, чтобы заметить —
-
Контейнер может внедрять модели (аналогично другим ресурсам). Методы контроллера могут устанавливать атрибуты модели, аналогичные атрибутам HashMap.
-
Аннотируйте свой класс с помощью @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);
}
}
}
Вот что делает приведенный выше код:
-
Класс расширяет ViewEngineBase и аннотируется как @ApplicationScoped. Это позволяет рассматривать этот класс как MVC ViewEngine и использовать, когда контроллер возвращает представление.
- Метод postConstruct () инициализирует механизм шаблонов Thymeleaf с каталогом шаблонов, а режим шаблона устанавливается как HTML5
- Для производственной среды рекомендуется resolver.setCacheable (true).
- Метод processView () вызывается, когда контроллер возвращает представление, в данном случае представление «login».
- Шаблоны Thymeleaf не могут напрямую обращаться к модели MVC, поэтому модель копируется в контекст Thymeleaf с помощью ctx.setVariables (context.getModels ());
- В случае Apache Tiles единое представление представляет шаблон и его подкомпоненты с использованием конфигурации XML. Чтобы достичь этого с Thymeleaf, представление, возвращаемое контроллером, используется для установки шаблона, который будет использоваться. Таким образом, с context.getView (). Equals («вход в систему»)? «login-template»: «default-template», мы настраиваем login-шаблон для представления «login» и default-template для остальных представлений.
- Затем мы устанавливаем имя представления в качестве атрибута запроса, чтобы мы могли указать шаблону, где искать его компоненты содержимого, относящиеся к его представлению.
Настройка шаблона просмотра
Следующий код является типичным шаблоном для визуализации представления. Шаблон использовал переменную области видимости $ {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 для источников
Ссылки
-
Основная структура проекта https://dzone.com/articles/java-ee-8-mvc-getting-started-with-ozark
-
Для JavaEE 8 ссылка https://javaee8.zeef.com/arjan.tijms
-
Для основ 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-контроллеров
-
Ссылка на домашнюю страницу MVC 1.0 https://ozark.java.net/
-
Для загрузки Thymeleaf и документации http://www.thymeleaf.org/download.html и http://www.thymeleaf.org/doc/articles/layouts.html
-
Для пользовательских макетов Thyemleaf http://blog.codeleak.pl/2013/11/thymeleaf-template-layouts-in-spring.html