Перейти к основному содержимому

Весенняя проверка на сервисном уровне

· 6 мин. чтения

1. Обзор

В этом руководстве мы обсудим проверку Spring на сервисном уровне приложения Java. Хотя Spring Boot поддерживает бесшовную интеграцию с пользовательскими валидаторами, стандартом де-факто для выполнения валидации является Hibernate Validator .

Здесь мы узнаем, как перенести нашу логику проверки из наших контроллеров в отдельный сервисный уровень. Кроме того, мы реализуем проверку на уровне службы в приложении Spring.

2. Слои приложений

В зависимости от требований бизнес-приложения Java могут принимать различные формы и типы. Например, мы должны определить, какие слои требуются нашему приложению на основе этих критериев. Если нет особой необходимости, многие приложения не выиграют от дополнительной сложности и затрат на обслуживание уровней обслуживания или репозитория.

Мы можем решить все эти проблемы, используя несколько слоев. Эти слои:

./6006e07a1273d2634863a1d8616b3408.png

Уровень потребителя или веб-уровень — это самый верхний уровень веб-приложения. Он отвечает за интерпретацию вводимых пользователем данных и предоставление соответствующего ответа . Исключения, создаваемые другими уровнями, также должны обрабатываться веб-уровнем. Поскольку веб-уровень является точкой входа нашего приложения, он отвечает за аутентификацию и служит первой линией защиты от неавторизованных пользователей.

Под веб-слоем находится сервисный уровень. Он служит транзакционным барьером и содержит как приложения, так и службы инфраструктуры. Кроме того, общедоступный API сервисного уровня предоставляется прикладными сервисами. Они часто служат границей транзакций и отвечают за авторизацию транзакций . Инфраструктурные службы предоставляют «программный код», который подключается к внешним инструментам, включая файловые системы, базы данных и серверы электронной почты. Эти подходы часто используются несколькими службами приложений.

Нижний уровень веб-приложения — это уровень сохраняемости. Другими словами, он отвечает за взаимодействие с хранилищем данных пользователя.

3. Проверка на сервисном уровне

Сервисный уровень — это уровень в приложении, который облегчает связь между контроллером и уровнем постоянства. Кроме того, бизнес-логика хранится на сервисном уровне. В частности, он включает логику проверки. Состояние модели используется для связи между уровнями контроллера и сервиса.

У обращения с валидацией как с бизнес-логикой есть свои преимущества и недостатки, и архитектура проверки (и привязки данных) Spring не препятствует этому. Проверка, в частности, не должна быть привязана к веб-уровню, должна быть простой для локализации и должна позволять использовать любой доступный валидатор.

Кроме того, входные данные клиента не всегда проходят через процесс контроллера REST, и если мы не проверим их также на уровне службы, могут пройти неприемлемые данные, что вызовет несколько проблем . В этом случае мы будем использовать стандартную схему проверки Java JSR-303 .

4. Пример

Давайте рассмотрим простую форму регистрации учетной записи пользователя, разработанную с использованием Spring Boot.

4.1. Простой доменный класс

Для начала у нас будут только атрибуты имени, возраста, телефона и пароля:

public class UserAccount {

@NotNull(message = "Password must be between 4 to 15 characters")
@Size(min = 4, max = 15)
private String password;

@NotBlank(message = "Name must not be blank")
private String name;

@Min(value = 18, message = "Age should not be less than 18")
private int age;

@NotBlank(message = "Phone must not be blank")
private String phone;

// standard constructors / setters / getters / toString
}

Здесь, в приведенном выше классе, мы использовали четыре аннотации — @NotNull , @Size , @NotBlank и @Min — чтобы убедиться, что входные атрибуты не являются ни нулевыми, ни пустыми и соответствуют требованиям к размеру.

4.2. Внедрение проверки на сервисном уровне

Существует множество доступных решений для проверки, при этом Spring или Hibernate обрабатывают фактическую проверку. С другой стороны, ручная проверка является жизнеспособной альтернативой . Когда дело доходит до интеграции проверки в правильную часть нашего приложения, это дает нам большую гибкость.

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

@Service
public class UserAccountService {

@Autowired
private Validator validator;

@Autowired
private UserAccountDao dao;

public String addUserAccount(UserAccount useraccount) {

Set<ConstraintViolation<UserAccount>> violations = validator.validate(useraccount);

if (!violations.isEmpty()) {
StringBuilder sb = new StringBuilder();
for (ConstraintViolation<UserAccount> constraintViolation : violations) {
sb.append(constraintViolation.getMessage());
}
throw new ConstraintViolationException("Error occurred: " + sb.toString(), violations);
}

dao.addUserAccount(useraccount);
return "Account for " + useraccount.getName() + " Added!";
}
}

Валидатор является частью Bean Validation API и отвечает за проверку объектов Java . Кроме того, Spring автоматически предоставляет экземпляр Validator , который мы можем внедрить в нашу службу UserAccountService . Validator используется для проверки переданного объекта в функции validate (..) . Результатом является набор ConstraintViolation .

Если никакие ограничения проверки не нарушены (объект действителен), набор пуст. В противном случае мы выбрасываем ConstraintViolationException .

4.3. Реализация REST-контроллера

После этого давайте создадим класс Spring REST Controller для отображения службы клиенту или конечному пользователю и оценки проверки ввода для приложения:

@RestController
public class UserAccountController {

@Autowired
private UserAccountService service;

@PostMapping("/addUserAccount")
public Object addUserAccount(@RequestBody UserAccount userAccount) {
return service.addUserAccount(userAccount);
}
}

Мы не использовали аннотацию @Valid в приведенной выше форме контроллера REST, чтобы предотвратить любую проверку.

4.4. Тестирование REST-контроллера

Теперь давайте проверим этот метод, запустив приложение Spring Boot. После этого, используя Postman или любой другой инструмент тестирования API, мы опубликуем ввод JSON по URL-адресу localhost:8080/addUserAccount :

{
"name":"ForEach",
"age":25,
"phone":"1234567890",
"password":"test",
"useraddress":{
"countryCode":"UK"
}
}

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

{
"name":"",
"age":25,
"phone":"1234567890",
"password":"",
"useraddress":{
"countryCode":"UK"
}
}

Консоль теперь показывает сообщение об ошибке. Следовательно, мы можем видеть, насколько важно использование Validator для проверки :

Error occurred: Password must be between 4 to 15 characters, Name must not be blank

5. Плюсы и минусы

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

Мы также можем использовать этот метод для модульных тестов, чтобы мы могли фактически смоделировать класс Service. Чтобы облегчить реальную проверку в модульных тестах, мы можем вручную сгенерировать необходимый экземпляр Validator .

Ни в том, ни в другом случае в наших тестах не требуется загрузка контекста приложения Spring.

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

В этом кратком руководстве мы рассмотрели различные уровни бизнес-приложений Java. Мы узнали, как перенести нашу логику проверки из наших контроллеров в отдельный сервисный уровень. Кроме того, мы реализовали один подход к выполнению проверки на сервисном уровне приложения Spring.

Код в примерах доступен на GitHub .