Рубрики
Без рубрики

Введение в фреймворк Ниндзя

Узнайте о веб-фреймворке Ninja и основных функциях, которые он предоставляет с помощью простого веб-приложения

Автор оригинала: baeldung.

1. Обзор

В настоящее время существует множество фреймворков на основе JEE, таких как Spring , Play и Grails , доступных для разработки веб-приложений.

У нас могут быть свои причины предпочесть один из них другим. Однако наш выбор также зависит от варианта использования и проблемы, которую мы пытаемся решить.

В этом вводном уроке мы рассмотрим веб-фреймворк Ninja и создадим простое веб-приложение. В то же время мы рассмотрим несколько основных функций, которые он предоставляет.

2. Ниндзя

Ninja -это полнотекстовый, но легкий веб-фреймворк, который использует существующие библиотеки Java для выполнения работы.

Обладая функциями от рендеринга HTML до JSON, от персистентности до тестирования, это универсальное решение для создания масштабируемых веб-приложений.

Он следует парадигме convention-over-configuration и классифицирует код в пакетах, таких как модели , контроллеры, и сервисы .

Ninja использует популярные библиотеки Java для ключевых функций, таких как Jackson для рендеринга JSON/XML, Guice для управления зависимостями, Hibernate для сохранения и Flyway для миграции баз данных .

Для быстрой разработки он предлагает Режим Super Dev для горячей перезагрузки кода. Таким образом, это позволяет нам мгновенно видеть изменения в среде разработки.

3. Настройка

Для создания веб-приложения Ninja требуется стандартный набор инструментов:

  • Java 1.8 или более поздней версии
  • Maven 3 или более поздняя версия
  • IDE (Eclipse или IntelliJ)

Мы будем использовать архетип Maven, чтобы быстро настроить проект Ниндзя. Он предложит нам указать идентификатор группы, идентификатор артефакта и номер версии, а затем имя проекта:

mvn archetype:generate -DarchetypeGroupId=org.ninjaframework \
  -DarchetypeArtifactId=ninja-servlet-archetype-simple

Или, для существующего проекта Maven, мы можем добавить последнюю зависимость ninja-core в pom.xml :


    org.ninjaframework
    ninja-core
    6.5.0

Затем мы запустим команду Maven для компиляции файлов в первый раз:

mvn clean install

Наконец, давайте запустим приложение с помощью предоставленной ниндзя команды Maven:

mvn ninja:run

Вуаля! Наше приложение запущено и будет доступно по адресу localhost:8080 :

4. Структура проекта

Давайте взглянем на структуру проекта, похожую на Maven, созданную Ninja:

Фреймворк создает несколько пакетов, основанных на соглашениях.

Классы Java классифицируются по следующим категориям конф , контроллеры , модели , и услуги каталоги в src/main/java.

Аналогично, src/test/java содержит соответствующие классы модульных тестов.

Каталог views в каталоге src/main/java содержит HTML-файлы. Кроме того, каталог src/main/java/assets содержит такие ресурсы, как изображения, таблицы стилей и файлы JavaScript.

5. Контроллер

Мы все готовы обсудить несколько основных особенностей фреймворка. Контроллер-это класс, который получает запрос и возвращает ответ с конкретными результатами.

Во-первых, давайте обсудим несколько конвенций, которым следует следовать:

  • Создайте класс в пакете controllers и суффиксируйте имя с помощью Controller
  • Метод, обслуживающий запрос, должен возвращать объект класса Result

Давайте создадим класс ApplicationController с помощью простого метода для визуализации HTML:

@Singleton
public class ApplicationController {
    public Result index() {
        return Results.html();
    }
}

Здесь метод index отобразит HTML, вызвав метод html класса Results . Объект Result содержит все, что требуется для отображения содержимого, например код ответа, заголовки и файлы cookie.

Примечание: Аннотация Guice @Singleton позволяет использовать только один экземпляр контроллера во всем приложении .

6. Просмотр

Для метода index Ninja будет искать HTML – файл – index .ftl.html в каталоге views/ApplicationController .

Ninja использует движок шаблонов Freemarker для рендеринга HTML . Таким образом, все файлы в разделе views должны иметь .ftl.html расширение.

Давайте создадим i индекс .ftl.html файл для метода index :

  

    Ninja: Index


    

${i18n("helloMsg")}

User Json

Здесь мы использовали предоставленный ниндзя тег i18n , чтобы получить свойство helloMsg из файла message.properties . Мы обсудим это далее в разделе интернационализации позже.

7. Маршрут

Далее мы определим маршрут, по которому запрос достигнет метода index .

Ninja использует класс Routes в пакете conf для сопоставления URL-адреса с определенным методом контроллера.

Давайте добавим маршрут для доступа к индексу методу Контроллера приложения :

public class Routes implements ApplicationRoutes {
    @Override
    public void init(Router router) {          
        router.GET().route("/index").with(ApplicationController::index);
    }
}

Вот и все! Мы все настроены на доступ к странице index в localhost:8080/index :

8. Рендеринг JSON

Как уже обсуждалось, Ninja использует Джексона для рендеринга JSON. Для визуализации содержимого JSON мы можем использовать метод json класса Results .

Давайте добавим метод user Json в класс ApplicationController и отобразим содержимое простого HashMap в JSON:

public Result userJson() {
    HashMap userMap = new HashMap<>();
    userMap.put("name", "Norman Lewis");
    userMap.put("email", "[email protected]");    
    return Results.json().render(user);
}

Затем мы добавим необходимую маршрутизацию для доступа к user Json :

router.GET().route("/userJson").with(ApplicationController::userJson);

Теперь мы можем визуализировать JSON с помощью localhost:8080/user Json :

9. Обслуживание

Мы можем создать службу, чтобы отделить бизнес-логику от контроллера и внедрить нашу службу везде, где это необходимо.

Во-первых, давайте создадим простой Пользовательский сервис интерфейс для определения абстракции:

public interface UserService {
    HashMap getUserMap();
}

Затем мы реализуем интерфейс UserService в классе UserServiceImpl и переопределим метод getUserMap :

public class UserServiceImpl implements UserService {
    @Override
    public HashMap getUserMap() {
        HashMap userMap = new HashMap<>(); 
        userMap.put("name", "Norman Lewis"); 
        userMap.put("email", "[email protected]"); 
        return userMap;
    }
}

Затем мы свяжем интерфейс UserService с классом UserServiceImpl , используя функцию внедрения зависимостей Ninja, предоставленную Guice.

Давайте добавим привязку в класс Module , доступный в пакете conf :

@Singleton
public class Module extends AbstractModule {
    protected void configure() {        
        bind(UserService.class).to(UserServiceImpl.class);
    }
}

Наконец, мы введем зависимость UserService в класс Application Controller с помощью аннотации @Inject :

public class ApplicationController {
    @Inject
    UserService userService;
    
    // ...
}

Таким образом, мы все настроены на использование метода UserService ‘s getUserMap в ApplicationController :

public Result userJson() {
    HashMap userMap = userService.getUserMap();
    return Results.json().render(userMap);
}

10. Область применения вспышки

Ninja предоставляет простой, но эффективный способ обработки сообщений об успехах и ошибках от запросов с помощью своей функции, называемой Flash Scope.

Чтобы использовать его в контроллере, мы добавим в метод аргумент Flash Scope :

public Result showFlashMsg(FlashScope flashScope) {
    flashScope.success("Success message");
    flashScope.error("Error message");
    return Results.redirect("/home");
}

Примечание: Метод redirect класса Results перенаправляет цель на указанный URL-адрес.

Затем мы добавим маршрутизацию /flash в метод show Flash Msg и изменим представление, чтобы отображать сообщения flash:

<#if (flash.error)??>
    
${flash.error}
<#if (flash.success)??>
${flash.success}

Теперь мы можем видеть область действия Flash в действии на localhost:8080/flash :

11. Интернационализация

Ninja предоставляет встроенную функцию интернационализации, которую легко настроить.

Сначала мы определим список поддерживаемых языков в файле application.conf :

application.languages=fr,en

Затем мы создадим файл свойств по умолчанию – messages.properties для английского языка – с парами ключ-значение для сообщений:

header.home=Home!
helloMsg=Hello, welcome to Ninja Framework!

Аналогично, мы можем добавить код языка в имя файла для файла свойств конкретного языка-например, message_fr.properties файл для французского языка:

header.home=Accueil!
helloMsg=Bonjour, bienvenue dans Ninja Framework!

Как только конфигурации будут готовы, мы можем легко включить интернационализацию в классе ApplicationController .

У нас есть два способа: либо с помощью класса Lang , либо с помощью класса Messages :

@Singleton
public class ApplicationController {
    @Inject
    Lang lang;

    @Inject
    Messages msg;
    
    // ...
}

Затем, используя класс Lang , мы можем задать язык результата:

Result result = Results.html();
lang.setLanguage("fr", result);

Аналогично, используя класс Messages , мы можем получить сообщение, зависящее от языка:

Optional language = Optional.of("fr");        
String helloMsg = msg.get("helloMsg", language).get();

12. Настойчивость

Ninja поддерживает JPA 2.0 и использует режим гибернации для обеспечения сохраняемости в веб-приложении. Кроме того, он предлагает встроенную поддержку базы данных H2 для быстрой разработки.

12.1. Модель

Нам требуется класс Entity для подключения к таблице в базе данных. Для этого Ninja следует соглашению о поиске классов сущностей в пакете models . Итак, мы создадим там класс User entity:

@Entity
public class User {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    Long id;
    public String firstName;
    public String email;  
}

Затем мы настроим режим гибернации и установим сведения о подключении к базе данных.

12.2. Конфигурация

Для конфигурации гибернации Ninja ожидает persistence.xml файл должен находиться в каталоге src/main/java/META-INF :



   
    
    
        org.hibernate.jpa.HibernatePersistenceProvider
        
            
            
            
            
            
            
        
    

Затем мы добавим сведения о подключении к базе данных в application.conf :

ninja.jpa.persistence_unit_name=dev_unit
db.connection.url=jdbc:h2:./devDb
db.connection.username=sa
db.connection.password=

12.3. EntityManager

Наконец, мы введем экземпляр EntityManager в ApplicationController с помощью класса Provider Guice:

public class ApplicationController {
    @Inject 
    Provider entityManagerProvider;

    // ...
}

Итак, мы готовы использовать EntityManager для сохранения объекта User :

@Transactional
public Result insertUser(User user) {
    EntityManager entityManager = entityManagerProvider.get();
    entityManager.persist(user);
    entityManager.flush();
    return Results.redirect("/home");
}

Аналогично, мы можем использовать EntityManager для чтения объекта User из БД:

@UnitOfWork
public Result fetchUsers() {
    EntityManager entityManager = entityManagerProvider.get();
    Query q = entityManager.createQuery("SELECT x FROM User x");
    List users = (List) q.getResultList();
    return Results.json().render(users);
}

Здесь аннотация Ninja @UnitOfWork будет обрабатывать все, что связано с подключениями к базе данных, без обработки транзакций. Следовательно, он может оказаться удобным для запросов только для чтения, где мы обычно не требуем транзакций.

13. Валидация

Ninja обеспечивает встроенную поддержку валидаций bean, следуя спецификациям JSR 303 .

Давайте рассмотрим функцию, аннотируя свойство в сущности User с помощью аннотации @NotNull :

public class User {
    // ...
    
    @NotNull
    public String firstName;
}

Затем мы изменим уже обсужденный метод insertUser в ApplicationController , чтобы включить проверку:

@Transactional
public Result insertUser(FlashScope flashScope, @JSR303Validation User user, Validation validation) {
    if (validation.getViolations().size() > 0) {
        flashScope.error("Validation Error: User can't be created");
    } else {
        EntityManager entityManager = entitiyManagerProvider.get();
        entityManager.persist(user);
        entityManager.flush();
        flashScope.success("User '" + user + "' is created successfully");
    }
    return Results.redirect("/home");
}

Мы использовали аннотацию Ninja @JSR303Validation , чтобы включить проверку объекта User . Затем мы добавили аргумент Validation для работы с проверками с помощью таких методов, как hasViolations , get Violations и addViolation.

Наконец, объект Flash Scope используется для отображения ошибки проверки на экране.

Примечание: Ninja следует спецификациям JSR 303 для проверки бобов. Однако спецификация JSR380 ( Bean Validation 2.0 ) является новым стандартом.

14. Заключение

В этой статье мы рассмотрели веб — фреймворк Ninja-фреймворк с полным стеком, который предоставляет удобные функции с использованием популярных библиотек Java.

Для начала мы создали простое веб-приложение с использованием контроллеров , моделей и сервисов . Затем мы включили поддержку JPA в приложении для сохранения.

В то же время мы увидели несколько основных функций, таких как маршруты, рендеринг JSON, интернационализация и области Flash.

Наконец, мы изучили поддержку валидации, предоставляемую фреймворком.

Как обычно, все реализации кода доступны на GitHub .