〰️
Programming with Java
  • Програмиране с JAVA
  • Обектно-ориентирано програмиране - 1 част
    • Лабораторно упражнение 1
      • Основи на програмирането с Java за начинаещи‎
        • Oбщи термини в Java
        • Основни характеристики на JAVA‎
        • Инсталиране на JDK
        • Инсталиране на Intellij
      • Първа програма в Java
      • Системен изход в JAVA
      • Дефиниране на променливи
      • Примитивни типове данни
      • Оператори
      • If-else
      • Switch-Case
      • For loop
      • While loop
      • Do-while loop
      • Continue
      • Break
      • Задачи
    • Лабораторно упражнение 2
      • Клас
      • Обект
      • Ключова дума new
      • Запазена дума static
      • Конвенции за именуване в Java
      • Wrapper Class
      • Сравняване на
      • Нуждата Wrapper Class
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 3
      • Наследяване
      • this и super
      • Модификатори за достъп
      • Капсулиране
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 4
      • Проследяване на грешки
      • Оценяване на изрази
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 5
      • Полиморфизъм
      • Абстрактен клас
      • Интерфейс
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 6
      • Разлика между Абстрактен клас и Интерфейс
        • Разлика 1
        • Разлика 2
        • Разлика 3
        • Разлика 4
        • Разлика 5
        • Разлика 6
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 7
      • String
      • Enum
      • Обработка на изключения
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 8
      • Генерични класове
      • Генеричен метод
      • Параметри на типа в Java Generics
      • Предимства на генериците
      • Генериците работят само с референтни типове
    • Лабораторно упражнение 9
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 10
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 11
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 12
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 13
      • Упражнения за извънаудиторна заетост
      • Упражнения за извънаудиторна заетост
  • Обектно-ориентирано програмиране - 2 част
    • Лабораторно упражнение 1
      • SRP - Single Responsibility Principle
        • Задачи
      • OCP - Open-Closed Principle
        • Задачи
    • Лабораторно упражнение 2
      • LSP - Liskov Substitution Principle
        • Задачи
      • ISP - Interface Segregation Principle
        • Задачи
      • DI - Dependency Inversion Principle
        • Задачи
    • Лабораторно упражнение 3
      • Singleton
        • Задачи
      • Builder
        • Задачи
    • Лабораторно упражнение 4
      • Factory Method
      • Abstract Factory
      • Задачи
    • Лабораторно упражнение 5
    • Лабораторно упражнение 6
      • Decorator
      • Bridge
        • Композиция
      • Задачи
    • Лабораторно упражнение 7
      • Adapter
      • Задачи
    • Лабораторно упражнение 8
      • Composite
      • Proxy
      • Задачи
    • Лабораторно упражнение 9
    • Лабораторно упражнение 10
      • Visitor
      • State
      • Задачи
    • Лабораторно упражнение 11
      • Observer
      • Задачи
    • Лабораторно упражнение 12
      • Chain of Responsibility
      • Command
      • Задачи
    • Лабораторно упражнение 13
  • Интернет технологии 2023
    • Лабораторно упражнение 1
      • HTTP протокол
        • Синтаксис на URL
        • HTTP съобщения
        • Методи за HTTP заявка
        • Кодове за състояние на HTTP отговор
      • Postman
        • Изпращане на заявка с Postman
        • Получаване на отговор
      • Задачи за работа с Postman
    • Лабораторно упражнение 2
      • Работа с Tomcat
      • Maven
      • Създаване на Maven проект в IntelliJ Ultimate Edition
      • Създаване на Maven проект в IntelliJ Community Edition
      • Създаване на Maven проект в Eclipse IDE
    • Лабораторно упражнение 3
      • Java Servlets
      • Жизнен цикъл на сървлета
      • Създаване на сървлети
      • Задачи за създаване на сървлети
    • Лабораторно упражнение 4
      • Extensible Markup Language
      • Java Architecture for XML Binding
      • JavaScript Object Notation
      • Задачи
    • Лабораторно упражнение 5
    • Лабораторно упражнение 6
      • Spring Boot
      • Създаване на Spring boot проект
      • Структура на Spring Boot проект
        • Файлът pom.xml
        • Main клас в Spring Boot
        • Управление на конфигурацията с application.properties
      • Задача
    • Лабораторно упражнение 7
      • Комуникационен поток и CRUD операции
      • ResponseEntity
      • Избрани анотации
      • Задача
    • Лабораторно упражнение 8
      • Lombok
      • Data transfer object (DTO)
      • Обработване на изключения в Spring Boot приложение
        • Клас Optional<T>
      • Валидиране на данните от заявката
      • Задачи
    • Лабораторно упражнение 9-10
      • Конфигуриране на PostgreSQL DB
      • Jakarta Persistence анотации
      • Repository слой
      • Задачи
    • Лабораторно упражнение 11
      • Проследяване на сесии
      • Филтри и FilterChain
      • Spring Security
        • Добавяне на Spring Security в Spring Boot приложение
        • Конфигуриране на филтри
        • Удостоверяване със Spring Security
        • Защита на метод със Spring Security
      • Задача
    • Лабораторно упражнение 12
      • JSON Web Token
      • Защита с помощта на JWT
      • Задача
    • Лабораторно упражнение 13
  • Програмиране за мобилни и Интернет устройства
    • Лабораторно упражнение 1
      • Задачи
    • Лабораторно упражнение 2
      • Среда за разработване
        • Създаване на проект
        • Структора на проект
        • Виртуално устройство с Android OS
      • Задача
    • Лабораторно упражнение 3
      • Activity
      • Layout
        • XML описание
      • Задача
    • Лабораторно упражнение 4
      • Activity Lifecycle
      • Intent
      • Слушатели на събитията и методи за обратно извикване
      • Задача
    • Лабораторно упражнение 5
      • Слушатели на събитията и методи за обратно извикване
      • Задача
    • Лабораторно упражнение 6
      • Фрагменти
      • DialogFragment
      • Задача
    • Лабораторно упражнение 7
      • Примери
        • BaseAdapter
        • ArrayAdapter
        • Custom ArrayAdapter
      • RecyclerView
        • Пример
      • CardView
      • Задача
    • Лабораторно упражнение 8
      • Runnable
      • HandlerThread
      • ThreadPoolExecutor
      • Задача
    • Лабораторно упражнение 9
      • Задача
      • Задача
      • Пример
  • Интернет Технологии
    • Лабораторно упражнение 1
      • Инсталиране и настройка на необходимата среда за работа в упражненията
      • Maven
      • Създаване на Maven проект в Eclipse IDE
      • Създаване на Maven проект в IntelliJ
      • Работа с Tomcat
      • Задача
    • Лабораторно упражнение 2
      • HTML форми
      • Cascading Style Sheets (CSS)
        • CSS селектори
        • Някои CSS свойства
      • Задача
    • Лабораторно упражнение 3
      • Java Servlets
      • Жизнен цикъл на сървлета
      • Създаване на сървлети
      • Задачи
    • Лабораторно упражнение 4
      • Java Server Pages технология. Същност и детайли
      • Пренасочване между Servlet и JSP
      • Задачи
    • Лабораторно упражение 5
      • Build pattern
      • JavaBean
      • Задачи
    • Лабораторно упражение 6
      • Проследяване на сесии
      • Управление на бисквитки (Cookies)
      • Задачи
    • Лабораторно упражнение 7
      • Проследяване на сесии
      • Управление на бисквитки (Cookies)
      • Servlet Filter
      • Задачи
    • Лабораторно упражнение 8
      • Servlet Filter
      • Прихващане на грешки
      • Задачи
    • Лабораторно упражнение 9
      • Extensible Markup Language
      • JavaScript Object Notation
        • Fetch
      • Задача
    • Лабораторно упражнение 10
      • Java Architecture for XML Binding
      • Задачи
Powered by GitBook
On this page

Was this helpful?

  1. Интернет технологии 2023
  2. Лабораторно упражнение 8

Валидиране на данните от заявката

PreviousКлас Optional<T>NextЗадачи

Last updated 2 years ago

Was this helpful?

Валидирането на данни в тялото на заявката трябва да се обработва от всеки REST API, за да се гарантира, че клиентите няма да изпращат дезинформация към сървъра, което може да наруши целостта на данните на приложението.

Jakarta Bean Validation е спецификация на Java, която ви позволява да задавате ограничения върху обектни модели чрез анотации като @NotNull, @Null, @Min, @Max и др. Предоставя API за валидиране на обекти и обектни графики, като можете да напишете и потребителски ограничения, ако вградените такива не отговарят на вашите нужди.

Hibernate Validator е референтна имплементация на спецификацията за валидиране на Java Bean, като предоставя допълнителни вградени ограничения, които ви дават повече опции за валидиране на обекти.

За да използвате Jakarta Bean validation с Hibernate Validator, трябва да добавите следната зависимост към вашия проект Maven. Това ще добави пакетите jakarta.validation-api-VERSION.jar и hibernate-validator-VERSION.jar към проекта.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

Основи на валидирането на Bean

Jakarta Bean Validation работи като дефинира ограничения за полетата на клас с помощта на определени.

Общи анотации за валидиране

Някои от най-често срещаните анотации за валидиране са:

  • @NotNull: указва, че полето не трябва да бъде null.

  • @NotEmpty: указва, че полето на списък не трябва да бъде празно.

  • @NotBlank: указва, че полето на низ не трябва да е празен низ (т.е. трябва да има поне един знак).

  • @Min и @Max: указва, че едно числово поле е валидно, само когато стойността му е над или под определена стойност.

  • @Size: указва, че размерът на елемента (CharSequence, Collection, Map или Array) трябва да бъде в зададени граници

  • @Pattern: указва, че полето на низ е валидно, само когато съответства на определен регулярен израз.

  • @Email: указва, че полето на низ трябва да е валиден имейл адрес.

Пример:

class Customer {

  @Email(message = "Email must be valid")
  private String email;

  @NotBlank(message = "Name cannot be blank")
  private String name;
  
  // ...
}

Валидиране на тялото на заявката

В POST и PUT заявките е обичайно да се предава JSON в тялото на заявката. Spring автоматично картографира входящия JSON към Java обект. Сега искаме да проверим дали входящият Java обект отговаря на нашите изисквания.

class Input {

  @Min(1)
  @Max(10)
  private int numberBetweenOneAndTen;

  @Pattern(regexp = "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$")
  private String ipAddress;
  
  // ...
}

Имаме int поле, което трябва да има стойност между 1 и 10 включително, както е дефинирано от анотациите @Min и @Max. Имаме и String поле, което трябва да съдържа IP адрес, както е дефинирано от регулярния израз в анотацията @Pattern.

За да потвърдим тялото на входяща HTTP заявка, ние анотираме тялото на заявката с анотацията @Valid в REST контролера:

@RestController
class ValidateRequestBodyController {

  @PostMapping("/validateBody")
  ResponseEntity<String> validateBody(@Valid @RequestBody Input input) {
    return ResponseEntity.ok("valid");
  }
}

Ние просто добавихме @Valid анотацията към параметъра Input input , който е анотиран r с @RequestBody, за да отбележи, че трябва да бъде прочетен от тялото на заявката. Правейки това, ние казваме на Spring да предаде обекта на валидатор, преди да направи нещо друго.

Ако проверката е неуспешна, тя ще задейства MethodArgumentNotValidException. По подразбиране Spring ще преведе това изключение в HTTP статус 400 (Bad request).

Използвайте @Valid и при сложни типове

Ако Input класът съдържа поле с друг сложен тип, което трябва да бъде валидирано, това поле също трябва да бъде анотирано с @Valid.

Валидиране на path variable и query parameter

Валидирането на темплейтните променливи и query параметрите на заявката работи малко по-различно.

В този случай не валидираме сложни обекти на Java, тъй като променливите на пътя и параметрите на заявката обикновено са примитивни типове като int; техните wrapper обекти като Integer или пъкString.

Вместо да анотираме поле на клас като по-горе, ние добавяме анотация на ограничение (в този случай @Min) директно към параметъра на метода в контролера:

@RestController
@Validated
class ValidateParametersController {

  @GetMapping("/validatePathVariable/{id}")
  ResponseEntity<String> validatePathVariable(
      @PathVariable("id") @Min(5) int id) {
    return ResponseEntity.ok("valid");
  }
  
  @GetMapping("/validateRequestParameter")
  ResponseEntity<String> validateRequestParameter(
      @RequestParam("param") @Min(5) int param) { 
    return ResponseEntity.ok("valid");
  }
}

Имайте предвид, че трябва да добавим анотация @Validated към контролера на ниво клас, за да кажем на Spring да оцени анотациите на ограниченията върху параметрите на метода.

За разлика от валидирането на тялото на заявката, неуспешното валидиране ще задейства ConstraintViolationException вместо MethodArgumentNotValidException. Spring не регистрира манипулатор на изключения по подразбиране за това изключение, така че по подразбиране ще предизвика отговор с HTTP статус 500 (вътрешна сървърна грешка).

Ако вместо това искаме да върнем HTTP статус 400 (което има смисъл, тъй като клиентът предоставя невалиден параметър, което го прави bad request), можем да добавим персонализиран манипулатор на изключения.

Добавяне на метод за обработване на изключения

@ControllerAdvice
public class ControllerAdvisor extends ResponseEntityExceptionHandler {
 
***
    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
              HttpHeaders headers, HttpStatusCode status,WebRequest request) {
        Map<String, Object> body = new LinkedHashMap<>();
        body.put("timestamp", LocalDate.now());
        body.put("status", status.value());

        List<String> errors = ex.getBindingResult()
                .getFieldErrors()
                .stream()
                .map(x -> x.getDefaultMessage())
                .collect(Collectors.toList());

        body.put("errors", errors);

        return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
    }
}
анотации