Rest API i walidacja beana


Rest API i walidacja beana

W tym artykule zaprezentuję w jaki sposób wykonać walidację beana zwracając w Response Body wynik poszczególnych walidacji. Napiszemy również własną walidację w postaci wygodnej do użycia adnotacji. Do dzieła! Zacznijmy od dodania niezbędnych zależności – plik pom.xml:

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter</artifactId>
	</dependency>
 
	<dependency>
		<groupId>com.h2database</groupId>
		<artifactId>h2</artifactId>
		<version>1.4.197</version>
		<scope>runtime</scope>
	</dependency>
 
	<!--Starting with Boot 2.3, we also need to explicitly add the spring-boot-starter-validation dependency:-->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-validation</artifactId>
	</dependency>
 
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-data-jpa</artifactId>
	</dependency>
 
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
 
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
</dependencies>

Przykładowy model – dla uproszczenia pominięto metody dostępowe:

@Entity
public class Employee {
 
    @Id
    private int id;
 
    @NotBlank
    private String name;
 
    @NotBlank
    private String surname;
 
    @NotBlank
    private String salary;
 
    @EmployeeRoleValid
    private String role;
 
}

Adnotacja @EmployeeRoleValid – dokonamy walidacji roli pracownika. Tylko wartość „DEV” jest prawidłowa:

@Documented
@Constraint(validatedBy = RoleEmployeeValidator.class)
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface EmployeeRoleValid {
    String message() default "Invalid employee role";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

Klasa gdzie definiujemy właściwą walidację:

public class RoleEmployeeValidator implements ConstraintValidator<EmployeeRoleValid, String> {
 
    @Override
    public void initialize(EmployeeRoleValid employeeRole) {
    }
 
    @Override
    public boolean isValid(String employeeRole, ConstraintValidatorContext cxt) {
        return (employeeRole.contains("DEV")) ? true: false;
    }
}

Klasa kontrolera:

@RestController
public class EmployeeController {
 
    @PostMapping("/emp")
    public ResponseEntity<String> addEmployee(@Valid @RequestBody Employee employee) {
        return ResponseEntity.ok("employee is valid");
    }
}

Po wysłaniu przykładowego zapytania POST:

{"name":"","surname":"Leader","salary":1000,"role":"Lead"}

otrzymamy:

{
"timestamp": "2021-10-13T16:36:29.307+00:00",
"status": 400,
"error": "Bad Request",
"path": "/emp"
}

co nie jest zadowalającym wynikiem – poprawny to dodając @ExceptionHandler:

@ControllerAdvice
public class GlobalExceptionHandler {
 
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity handleValidationExceptions(
            MethodArgumentNotValidException ex) {
 
        List<String> errors = new ArrayList<>();
        ex.getBindingResult().getFieldErrors().forEach(err -> errors.add(err.getDefaultMessage()));
 
        Map<String, Object> errorResponse = new HashMap<>();
        errorResponse.put("errors", errors);
        errorResponse.put("status", HttpStatus.BAD_REQUEST.toString());
 
        return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
 
    }
}

wynik:

{
"errors": [
  "Invalid employee role",
  "nie może być odstępem"
],
"status": "400 BAD_REQUEST"
}

Zobacz kod na GitHubie i zapisz się na bezpłatny newsletter!

.


Leave a comment

Your email address will not be published.


*


Ta strona wykorzystuje pliki cookie. Używamy informacji zapisanych za pomocą plików cookies w celu zapewnienia maksymalnej wygody w korzystaniu z naszego serwisu. Mogą też korzystać z nich współpracujące z nami firmy badawcze oraz reklamowe. Jeżeli wyrażasz zgodę na zapisywanie informacji zawartej w cookies kliknij na „akceptuję". Jeśli nie wyrażasz zgody, ustawienia dotyczące plików cookies możesz zmienić w swojej przeglądarce. kliknij po więcej informacji

Ta strona wykorzystuje pliki cookie. Używamy informacji zapisanych za pomocą plików cookies w celu zapewnienia maksymalnej wygody w korzystaniu z naszego serwisu. Mogą też korzystać z nich współpracujące z nami firmy badawcze oraz reklamowe. Jeżeli wyrażasz zgodę na zapisywanie informacji zawartej w cookies kliknij na „akceptuję". Jeśli nie wyrażasz zgody, ustawienia dotyczące plików cookies możesz zmienić w swojej przeglądarce.

zamknij