1. Обзор
Jooby
— это масштабируемая и быстрая микро-веб-инфраструктура, построенная на основе наиболее часто используемых веб-серверов NIO
. Он очень простой и модульный, явно разработанный для современной веб-архитектуры. Он также поддерживает Javascript
и Kotlin
.
По умолчанию Jooby
поставляется с отличной поддержкой Netty, Jetty и Undertow
.
В этой статье мы узнаем об общей структуре проекта Jooby
и о том, как создать простое веб-приложение с помощью Jooby
.
2. Архитектура приложения
Простая структура приложения Jooby выглядит
следующим образом :
├── public
| └── welcome.html
├── conf
| ├── application.conf
| └── logback.xml
└── src
| ├── main
| | └── java
| | └── com
| | └── foreach
| | └── jooby
| | └── App.java
| └── test
| └── java
| └── com
| └── foreach
| └── jooby
| └── AppTest.java
├── pom.xml
Здесь следует отметить, что в общий
каталог мы можем поместить статические файлы, такие как css/js/html и т. д. В каталог conf
мы можем поместить любой файл конфигурации, который нужен приложению, например logback.xml
или application.conf
и т. д.
3. Зависимость от Maven
Мы можем создать простое приложение Jooby
, добавив следующую зависимость в наш pom.xml:
<dependency>
<groupId>org.jooby</groupId>
<artifactId>jooby-netty</artifactId>
<version>1.1.3</version>
</dependency>
Если мы хотим выбрать Jetty
или Undertow
, мы можем использовать следующую зависимость:
<dependency>
<groupId>org.jooby</groupId>
<artifactId>jooby-jetty</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>org.jooby</groupId>
<artifactId>jooby-undertow</artifactId>
<version>1.1.3</version>
</dependency>
Вы можете проверить последнюю версию проекта Jooby
в Центральном репозитории Maven .
У Jooby
также есть специальный архетип Maven. Мы можем использовать его для создания примера проекта со всеми предварительно построенными необходимыми зависимостями.
Мы можем использовать следующий скрипт для создания примера проекта:
mvn archetype:generate -B -DgroupId=com.foreach.jooby -DartifactId=jooby
-Dversion=1.0 -DarchetypeArtifactId=jooby-archetype
-DarchetypeGroupId=org.jooby -DarchetypeVersion=1.1.3
4. Создание приложения
4.1. Запуск сервера
Чтобы запустить встроенный сервер, нам нужно использовать следующий фрагмент кода:
public class App extends Jooby {
public static void main(String[] args) {
run(App::new, args);
}
}
После запуска сервер будет работать на порту
8080
по умолчанию .
Мы также можем настроить внутренний сервер с настраиваемым портом и настраиваемым портом HTTPS
:
{
port( 8081 );
securePort( 8443 );
}
4.2. Реализация маршрутизатора
В Jooby
очень легко создать маршрутизатор на основе пути . Например, мы можем создать маршрутизатор для пути « /login
» следующим образом:
{
get( "/login", () -> "Hello from ForEach");
}
Аналогичным образом, если мы хотим обрабатывать другие методы HTTP
, такие как POST, PUT и т. д., мы можем использовать приведенный ниже фрагмент кода:
{
post( "/save", req -> {
Mutant token = req.param( "token" );
return token.intValue();
});
}
Здесь мы извлекаем токен имени параметра запроса из запроса. По умолчанию все параметры запроса приводятся к типу данных Jooby
Mutant
. Основываясь на ожиданиях, мы можем преобразовать его в любой поддерживаемый примитивный тип данных.
Мы можем проверить любой параметр URL следующим образом:
{
get( "/user/{id}", req -> "Hello user : " + req.param("id").value() );
get( "/user/:id", req -> "Hello user: " + req.param("id").value() );
}
Мы можем использовать любой из вышеперечисленных. Также можно найти параметры, начинающиеся с фиксированного содержимого. Например, мы можем найти параметр URL, начинающийся с « uid: »,
следующим образом:
{
get( "/uid:{id}", req -> "Hello User with id : uid" +
req.param("id").value());
}
4.3. Реализация контроллера паттернов MVC
Для корпоративного приложения Jooby
поставляется с MVC API, как и любые другие среды MVC, такие как Spring MVC.
Например, мы можем обработать путь с именем ' /hello
':
@Path("/hello")
public class GetController {
@GET
public String hello() {
return "Hello ForEach";
}
}
Точно так же мы можем создать обработчик для обработки других HTTP-методов с аннотациями @POST , @PUT, @DELETE
и т. д.
4.4. Обработка статического контента
Чтобы обслуживать любой статический контент, такой как HTML, Javascript, CSS, изображения и т. д., нам нужно поместить этот файл в общедоступный
каталог.
После размещения с маршрутизатора мы можем сопоставить любой URL-адрес с этими ресурсами:
{
assets( "/employee" , "form.html" );
}
4.5. Форма обработки
` [
Интерфейс запроса](https://javadoc.io/static/org.jooby/jooby/1.2.3/org/jooby/Request.html)
Jooby` по умолчанию обрабатывает любой объект формы без использования какого-либо ручного приведения типов.
Предположим, нам нужно отправить данные о сотруднике через форму. На первом этапе нам нужно создать объект bean-компонента Employee
, который мы будем использовать для хранения данных:
public class Employee {
String id;
String name;
String email;
// standard constructors, getters and setters
}
Теперь нам нужно создать страницу для создания формы:
<form enctype="application/x-www-form-urlencoded" action="/submitForm"
method="post">
<input name="id" />
<input name="name" />
<input name="email" />
<input type="submit" value="Submit"/>
</form>
Далее мы создадим обработчик сообщений для обращения к этой форме и извлечения отправленных данных:
post( "/submitForm", req -> {
Employee employee = req.params(Employee.class);
// ...
return "empoyee data saved successfullly";
});
Здесь следует отметить, что нам необходимо объявить enctype
формы как application/x-www-form-urlencoded
для поддержки динамической привязки формы.
По Request.file(String имя файла)
мы можем получить загруженный файл:
post( "/upload", req -> {
Upload upload = req.file("file");
// ...
upload.close();
});
4.6. Реализация фильтра
По умолчанию Jooby
обеспечивает гибкость определения глобальных фильтров, а также фильтров на основе путей.
Реализация фильтра в Jooby
немного сложна, так как нам нужно настроить URL-путь дважды, один раз для фильтра и еще раз для обработчика.
Например, если нам нужно реализовать фильтр для URL-пути с именем « /filter»,
нам нужно реализовать фильтр в этом пути явно:
get( "/filter", ( req, resp, chain ) -> {
// ...
chain.next( req, resp );
});
Синтаксис очень похож на фильтр сервлетов .
Можно ограничить запрос и отправить ответ в самом фильтре, вызвав метод Response.send(результат результата) .
После того, как фильтр реализован, нам нужно реализовать обработчик запроса:
get("/filter", (req, resp) -> {
resp.send("filter response");
});
4.7. Сессия
Jooby
поставляется с двумя типами реализации сеанса; в памяти и на основе файлов cookie.
Реализовать управление сеансами в памяти довольно просто. У нас есть возможность выбрать любое из высокопроизводительных хранилищ сеансов, доступных с Jooby
, таких как EhCache, Guava, HazleCast, Cassandra, Couchbase, Redis, MongoDB
и Memcached.
Например, чтобы реализовать хранилище сеансов на основе Redis, нам нужно добавить следующую зависимость Maven:
<dependency>
<groupId>org.jooby</groupId>
<artifactId>jooby-jedis</artifactId>
<version>1.1.3</version>
</dependency>
Теперь мы можем использовать приведенный ниже фрагмент кода, чтобы включить управление сеансом:
{
use(new Redis());
session(RedisSessionStore.class);
get( "/session" , req -> {
Session session = req.session();
session.set("token", "value");
return session.get("token").value();
});
}
Здесь следует отметить, что мы можем настроить URL-адрес Redis
как свойство «db» в
application.conf
.
Чтобы включить управление сеансом на основе файлов cookie, нам нужно объявить cookieSession()
. Если выбран подход на основе файлов cookie, нам необходимо объявить свойство application.secret в файле
application.conf .
Поскольку каждый файл cookie будет подписан этим секретным ключом, всегда рекомендуется использовать в качестве секретного ключа длинный фрагмент случайной строки. **
**
Как в подходе, основанном на памяти, так и на основе файлов cookie, мы должны объявить необходимый параметр конфигурации в файле application.conf
, иначе приложение выдаст исключение IllegalStateException
при запуске.
5. Тестирование
Тестировать маршрут MVC действительно легко, поскольку маршрут привязан к стратегии для некоторого класса. Это упрощает запуск модульных тестов для всех маршрутов.
Например, мы можем быстро создать тестовый пример для URL по умолчанию:
public class AppTest {
@ClassRule
public static JoobyRule app = new JoobyRule(new App());
@Test
public void given_defaultUrl_expect_fixedString() {
get("/").then().assertThat().body(equalTo("Hello World!"))
.statusCode(200).contentType("text/html;charset=UTF-8");
}
}
Здесь следует отметить, что использование аннотации @ClassRule
создаст только один экземпляр сервера для всех тестовых случаев. Если нам нужно построить отдельные экземпляры серверов для каждого теста, мы должны использовать аннотацию @Rule
без модификатора static.
Мы также можем использовать MockRouter от Jooby
для проверки пути таким же образом:
@Test
public void given_defaultUrl_with_mockrouter_expect_fixedString()
throws Throwable {
String result = new MockRouter(new App()).get("/");
assertEquals("Hello World!", result);
}
6. Заключение
В этом руководстве мы рассмотрели проект Jooby
и его основные функции.
Как всегда, полный исходный код доступен на GitHub .