Вступление
В этом уроке мы создадим асинхронный сервлет, который добавляет контакты в список, анализирует запросы и обрабатывает проверку формы с помощью ActiveJ framework. Вы можете найти исходный код этого руководства на GitHub .
Настройка проекта
Нам понадобятся следующие зависимости:
io.activej activej-launchers-http 3.0 com.github.spullara.mustache.java compiler 0.9.4 ch.qos.logback logback-classic 1.2.3
Мы будем использовать следующие активные технологии:
- Active Inject – легкая и мощная библиотека внедрения зависимостей с высокой производительностью и отсутствием сторонних зависимостей.
- Active J HTTP – высокопроизводительные асинхронные HTTP-клиенты и серверы.
- Active Launcher – заботится о полном жизненном цикле приложения, управлении службами и ведении журнала. Идеально совместим с активной инъекцией.
Время кодировать!
В этом учебном пособии представлен шаблон MVC:
- Кому модель для представления
контакта
мы создадим простой класс Java с полями (имя
,возраст
,адрес
), конструктором и средствами доступа к полям:
class Contact { private final String name; private final Integer age; private final Address address; public Contact(String name, Integer age, Address address) { this.name = name; this.age = age; this.address = address; } public String getName() { return name; } public int getAge() { return age; } public Address getAddress() { return address; } @Override public String toString() { return "Contact{name='" + name + '\'' + ", age=" + age + ", address=" + address + '}'; } }
Класс Адрес
довольно прост:
class Address { private final String title; public Address(String title) { this.title = title; } public String getTitle() { return title; } @Override public String toString() { return "Address{title='" + title + '\'' + '}'; } }
Чтобы упростить учебник, мы будем использовать список массивов для хранения объектов Contact
. ContactDAO
для этой цели используется интерфейс и его реализация:
interface ContactDAO { Listlist(); void add(Contact user); }
class ContactDAOImpl implements ContactDAO { private final ListuserList = new ArrayList<>(); @Override public List list() { return userList; } @Override public void add(Contact user) { userList.add(user); } }
- Для создания представления мы будем использовать один HTML-файл, скомпилированный с помощью движка шаблонов Mustache:
Decoder example
Name | Age | Address |
---|---|---|
{{name}} | {{age}} | {{address.title}} |
- Ан
Асинхронный сервлет
будет использоваться в качестве контроллера . Мы также добавимRoutingServlet
для маршрутизации запросов к необходимым конечным точкам. Мы вернемся к этому через минуту.
Давайте создадим Пример Http-декодера
класс, который расширяет Пусковую установку Http-сервера
. Путем расширения Пусковая установка Http-сервера
мы позаботимся о жизненном цикле сервера и управлении услугами. Далее мы предоставляем два пользовательских анализатора, основанных на Декодер
– АДРЕС_ДЕКОДЕРА
и CONTACT_DECODER
– который будет использоваться для проверки. Класс Decoder
предоставляет вам инструменты для анализа запросов.
public final class HttpDecoderExample extends HttpServerLauncher { private static final String SEPARATOR = "-"; private static final Decoder ADDRESS_DECODER = Decoder.of(Address::new, ofPost("title", "") .validate(param -> !param.isEmpty(), "Title cannot be empty") ); private static final DecoderCONTACT_DECODER = Decoder.of(Contact::new, ofPost("name") .validate(name -> !name.isEmpty(), "Name cannot be empty"), ofPost("age") .map(Integer::valueOf, "Cannot parse age") .validate(age -> age >= 18, "Age must not be less than 18"), ADDRESS_DECODER.withId("contact-address") );
Кроме того, нам нужно создать применить шаблон (Усы усы, Карта<Строка, Объект> области видимости)
способ заполнения предоставленного шаблона усов заданными данными:
private static ByteBuf applyTemplate(Mustache mustache, Mapscopes) { ByteBufWriter writer = new ByteBufWriter(); mustache.execute(writer, scopes); return writer.getBuf(); }
Далее давайте предоставим ContactDAOImpl
заводской метод:
@Provides ContactDAO dao() { return new ContactDAOImpl(); }
Теперь у нас есть все необходимое для создания контроллера Асинхронный сервлет
для обработки запросов:
@Provides AsyncServlet mainServlet(ContactDAO contactDAO) { Mustache contactListView = new DefaultMustacheFactory().compile("static/contactList.html"); return RoutingServlet.create() .map("/", request -> HttpResponse.ok200() .withBody(applyTemplate(contactListView, map("contacts", contactDAO.list())))) .map(POST, "/add", AsyncServletDecorator.loadBody() .serve(request -> { EitherdecodedUser = CONTACT_DECODER.decode(request); if (decodedUser.isLeft()) { contactDAO.add(decodedUser.getLeft()); } Map scopes = map("contacts", contactDAO.list()); if (decodedUser.isRight()) { scopes.put("errors", decodedUser.getRight().toMap(SEPARATOR)); } return HttpResponse.ok200() .withBody(applyTemplate(contactListView, scopes)); })); }
Здесь мы предоставляем Асинхронный сервлет
, который получает Http-запросы
от клиентов, создает HttpResponse HttpResponse Ответ
s в зависимости от маршрута и отправляет его.
Внутри RoutingServlet
определены два пути маршрута. Первый сопоставляет запросы с корневым маршрутом /
– он просто отображает список контактов. Второй, /добавить
– это метод HTTP POST, который добавляет или отклоняет добавление новых пользователей. Мы обработаем синтаксический анализ этого запроса с помощью вышеупомянутого Декодер
с помощью метода декодирования
:
EitherdecodedUser = CONTACT_DECODER.decode(request);
Либо
представляет значение двух возможных типов данных, которые являются либо Слева
( Связаться
) или Правильно
( (
Ошибки декодирования ). Чтобы определить, был ли синтаксический анализ успешным или нет, мы проверяем его значение с помощью
is Left() и
является правильным() методы. Наконец, запишите метод
main
public static void main(String[] args) throws Exception { Launcher launcher = new HttpDecoderExample(); launcher.launch(args); }
Время проверить!
Вы только что создали и запустили веб-приложение MVC с асинхронным и высокопроизводительным сервером! Теперь вы можете протестировать приложение, посетив localhost:8080 .
Оригинал: “https://dev.to/activej/mvc-web-application-with-activej-1kmp”