1. Обзор
В этой статье мы рассмотрим VRaptor , простую и понятную веб-инфраструктуру Java MVC, которая использует технологии Java Contexts и Dependency Injection и проста для понимания.
Как и Spring — он сильно зависит от аннотаций и отлично работает с Hibernate .
Он также поставляется с некоторыми полезными плагинами, например, для интернализации и модульного тестирования.
Итак, давайте изучим различные компоненты VRaptor и создадим пример проекта.
2. Зависимости и настройка Maven
Один из быстрых способов приступить к работе — скачать vraptor-blank-project-distribution
из официального репозитория .
Пустой проект — это всего лишь скелет, который можно превратить в полноценное веб-приложение.
Скачав и разархивировав проект, давайте переименуем директорию в vraptor
(или любое другое имя).
Каталог должен содержать:
источник/
пом.xml
- и
README.md
Проект основан на Maven и поставляется с плагином tomcat7
Maven, который предоставляет контейнер сервлетов для запуска приложения.
Он также поставляется с IndexController
по умолчанию , который имеет только один метод — index()
.
По умолчанию представление, отображаемое этим методом, находится в файле webapp/WEB-INF/jsp/index/index.jsp
— это соответствует соглашению WEB-INF/jsp/
имя_контроллера/имя_метода.
Чтобы запустить сервер, мы выполним команду mvn tomcat7
: run
из корня проекта.
В случае успеха, если мы посетим http://localhost:8080,
браузер отобразит « Это работает!! ВРаптор!
“.
Если мы сталкиваемся с « java.lang.LinkageError: нарушение ограничения загрузчика»
, нам нужно изменить следующие зависимости в pom.xml
:
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet-core</artifactId>
<version>2.1.2.Final</version>
<exclusions>
<exclusion>
<groupId>org.jboss.spec.javax.el</groupId>
<artifactId>jboss-el-api_3.0_spec</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-core-impl</artifactId>
<version>2.1.2.Final</version>
<exclusions>
<exclusion>
<groupId>org.jboss.spec.javax.el</groupId>
<artifactId>jboss-el-api_3.0_spec</artifactId>
</exclusion>
</exclusions>
</dependency>
Виновником является el-api
, включенный в weld-servlet-core
и weld-core-impl
с областью компиляции
; это приводит к конфликту зависимостей.
Следующие зависимости потребуются по ходу, поэтому давайте включим их в pom.xml
:
<dependency>
<groupId>br.com.caelum.vraptor</groupId>
<artifactId>vraptor-freemarker</artifactId>
<version>4.1.0-RC3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.8-dmr</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.27-incubating</version>
</dependency>
Последнюю версию артефактов vraptor-freemarker
, mysql-connector-java
и freemarker
можно найти в Maven Central.
Теперь, когда все готово, давайте создадим простой блог-сайт.
3. Поддержка гибернации
VRaptor предоставляет различные плагины для взаимодействия с базами данных, один из них vraptor-hibernate
, который `` работает с Hibernate 4.
Плагин делает bean- компонент SessionFactory
Hibernate доступным во время выполнения через CDI.
После установки плагина нам понадобится стандартный файл конфигурации Hibernate — пример можно найти в репозитории.
VRaptor использует технику под названием Producers, чтобы сделать объекты доступными для управления DI. Подробнее об этом здесь .
4. Определение веб-маршрутов в VRaptor
В VRaptor
определения маршрутов находятся в контроллерах, которые представляют собой просто @Controller- аннотированные Java-объекты — точно так же, как в Spring.
Аннотации @Path
используются для сопоставления пути запроса с конкретным контроллером, а аннотации @Get, @Post, @Put, @Delete
и @Patch
используются для указания типов HTTP-запросов.
Конфигурация сопоставления маршрутов похожа на JAX-RS, но официально не реализует стандарт.
Кроме того, при определении пути можно указать переменную пути в фигурных скобках:
@Get("/posts/{id}")
Затем значение id
можно получить внутри метода контроллера:
@Get("/posts/{id}")
public void view(int id) {
// ...
}
Когда форма отправляется по определенному маршруту, VRaptor может автоматически заполнять объект отправленными данными формы.
Давайте посмотрим на это в действии в следующем разделе статьи.
5. Представления и механизм шаблонов
По умолчанию представления могут быть реализованы с помощью JSP. Однако можно использовать и другие шаблонизаторы — в этой статье мы будем работать с Freemarker.
Начнем с создания index.ftl и сохранения
его в каталоге просмотра по умолчанию (src/main/resources/templates):
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>VRaptor Blank Project</title>
</head>
<body>
It works!! ${variable}
</body>
</html>
Теперь мы можем использовать определенное представление с классом FreemarkerView
для рендеринга вида:
@Path("/")
public void index() {
result.include("variable", "VRaptor!");
result.use(FreemarkerView.class).withTemplate("index");
}
Объект Result
содержит состояние модели — у него есть методы для перенаправления на другую страницу, URL-адрес или метод контроллера; его можно ввести в контроллер с помощью CDI.
В нашем примере переменная
разрешается Freemarker. Таким образом , заполнитель ${variable}
в index.ftl
заменяется на «VRaptor!».
Здесь задокументировано более продвинутое использование .
6. Пример обработки отправки формы
Давайте посмотрим, как мы можем обрабатывать отправку форм с проверкой:
@Post("/post/add")
public void add(Post post) {
post.setAuthor(userInfo.getUser());
validator.validate(post);
if(validator.hasErrors()) {
result.include("errors", validator.getErrors());
}
validator.onErrorRedirectTo(this).addForm();
Object id = postDao.add(post);
if(Objects.nonNull(id)) {
result.include("status", "Post Added Successfully");
result.redirectTo(IndexController.class).index();
} else {
result.include(
"error", "There was an error creating the post. Try Again");
result.redirectTo(this).addForm();
}
}
Объект Post
сначала проверяется с помощью проверки Java-бина , а затем сохраняется в базе данных с помощью postDao.add()
.
Поля объекта Post
заполняются автоматически из значений отправленных данных формы, которые соответствуют полям ввода формы в файле представления.
Обратите внимание, что имя поля ввода должно начинаться с имени объекта в нижнем регистре.
Например, представление, отвечающее за добавление нового поста, имеет поля ввода: post.title
и post.post
, которые соответствуют полям title
и post
в Post
. java
соответственно:
<input type="text" class="form-control" placeholder="Title"
id="title" name="post.title" required />
<textarea rows="10" class="form-control" placeholder="Post"
id="post" name="post.post" required></textarea>
Полный файл add.ftl
можно найти в исходном коде.
Если при отправке формы возникает ошибка, включается сообщение об ошибке, и пользователь перенаправляется к тому же методу add() :
if(validator.hasErrors()) {
result.include("errors", validator.getErrors());
}
validator.onErrorRedirectTo(this).addForm();
7. Заключение
В заключение мы кратко рассмотрели VRaptor и увидели, как можно реализовать базовую функциональность MVC.
Документация содержит более подробную информацию о фреймворке, а также о доступных плагинах.
Полный исходный код, включая образец database.sql
, доступен на Github .