Spring Boot se da cuenta del uso básico de la verificación de parámetros

El uso simple de
la especificación API de Java (JSR303) define la API de validación estándar para la validación de Bean, pero no proporciona una implementación. La validación de hibernación es la implementación de esta especificación y agrega anotaciones de validación como @Email, @Length, etc. Spring Validation es una encapsulación secundaria de la validación de hibernación, que se utiliza para admitir la validación automática de los parámetros de spring mvc. A continuación, tomamos el proyecto spring-boot como ejemplo para presentar el uso de Spring Validation.

Introducción de dependencias
Si la versión de spring-boot es inferior a 2.3.x, spring-boot-starter-web importará automáticamente las dependencias de hibernate-validator. Si la versión Spring-Boot es superior a 2.3.x, debe introducir manualmente las dependencias:

<!--Validación de datos JSR303-->
<dependencia>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-validation</artifactId>
   <version>2.6.4</version>
< /dependencia>
Para los servicios web, para evitar que los parámetros ilegales afecten el negocio, ¡la verificación de parámetros debe realizarse en la capa del Controlador! En la mayoría de los casos, los parámetros de solicitud se dividen en las dos formas siguientes:

Para solicitudes POST y PUT, use requestBody para pasar parámetros;

Solicitud GET, use requestParam/PathVariable para pasar parámetros.

¡Presentemos brevemente la verificación de parámetros real de requestBody y requestParam/PathVariable!

Las solicitudes POST y PUT de verificación de parámetros de requestBody
generalmente usan requestBody para pasar parámetros. En este caso, el backend usa objetos DTO para recibir. Simplemente agregue la anotación @Validated al objeto DTO para lograr la validación automática de parámetros. Por ejemplo, hay una interfaz para guardar Usuario, que requiere que la longitud del nombre de usuario sea 2-10 y la longitud del campo de contraseña sea 6-20. Si la verificación falla, se lanzará una MethodArgumentNotValidException y Spring la convertirá en una solicitud 400 (Solicitud incorrecta) de forma predeterminada.

Declarar anotaciones de restricciones en campos DTO

@Data  
public class UserDTO {  
  
    private Long userId;  
  
    @NotNull  
    @Length(min = 2, max = 10)  
    private String userName;  
  
    @NotNull  
    @Length(min = 6, max = 20)  
    private String contraseña;  
}  
declarar en el parámetro del método Validación notas

@PostMapping("/save")  
public Result saveUser(@RequestBody @Validated UserDTO userDTO) {  
  
    return Result.ok();  
}  
En este caso, se pueden usar tanto @Valid como @Validated.

requestParam/PathVariable Verificación de parámetros
Las solicitudes GET generalmente usan requestParam/PathVariable para pasar parámetros. En este caso, debe marcar la anotación @Validated en la clase Controller y declarar anotaciones de restricción (como @Min, etc.) en los parámetros de entrada. Si la verificación falla, se lanzará una ConstraintViolationException. El ejemplo de código es el siguiente:

@RequestMapping("/api/user")  
@RestController  
@Validated  
public class UserController {  
  
    @GetMapping("{userId}")  
    public Result detail(@PathVariable("userId") @Min(10000000000000000L) Long userId) {  
  
        UserDTO userDTO = nuevo usuarioDTO();  
        usuarioDTO.setUserId(usuarioId);   
        usuarioDTO.setUserName("xiaoxiao");   
        devolver Result.ok (usuarioDTO);  
    }  
  
    @GetMapping("getByAccount")  
    public Result getByAccount(@Length(min = 2, max = 10) @NotNull String nombre de usuario) {  
  
        UserDTO userDTO = new UserDTO();  
        usuarioDTO.setUserId(10000000000000003L);  
        usuarioDTO.   
        return Result.ok(userDTO);  
    }  
}  
Manejo unificado de excepciones
Si falla la verificación, se generará una excepción MethodArgumentNotValidException o ConstraintViolationException. En el desarrollo de proyectos reales, el manejo de excepciones unificado se usa generalmente para devolver un indicador más amigable. Por ejemplo, nuestro sistema requiere que, sin importar qué excepción se envíe, el código de estado http debe devolver 200 y el código comercial se usa para distinguir la situación anormal del sistema.

@RestControllerAdvice  
public class CommonExceptionHandler {  
  
    @ExceptionHandler({MethodArgumentNotValidException.class})  
    @ResponseStatus(HttpStatus.OK)  
    @ResponseBody  
    public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {  
        BindingResult bindingResult = ex.getBindingResult();  
        StringBuilder sb = new StringBuilder("校验失败:");  
        for (FieldError fieldError : bindingResult.getFieldErrors()) {  
            sb.append(fieldError.getField()).append(":").append(fieldError.getDefaultMessage()).append(", ");  
        }  
        String mensaje = sb.toString();  
       devuelve Result.fail(mensaje);  

  
    @ExceptionHandler({ConstraintViolationException.class})   @ResponseStatus     ;           (ex.getMessage())  Result.fail return       public Result handleConstraintViolationException(ConstraintViolationException ex) {       @ResponseBody  
    (HttpStatus.OK)  En este momento, simplemente agregar anotaciones de restricciones a los campos de la clase DTO no puede resolver este problema. Por lo tanto, la validación de primavera admite la función de verificación de grupo, que se utiliza especialmente para resolver este tipo de problemas. Sigue siendo el ejemplo anterior, por ejemplo, al guardar el usuario, el ID de usuario puede estar vacío, pero al actualizar el usuario, el valor del ID de usuario debe ser >=10000000000000000L; las reglas de verificación para otros campos son las mismas en ambos casos. El ejemplo de código del uso de la verificación de grupo en este momento es el siguiente:






Los grupos de información de agrupación aplicables se declaran en la anotación de restricción

@Data  
public class UserDTO {  
 
    // solo límite de actualización (Update.class)  
    @Min(value = 100000000000000000L, groups = Update.class)  
    private Long userId  
  
    // no es nulo, el límite de longitud es válido tanto para guardar como para actualizar
    @NotNull ( grupos = {Guardar.clase, Actualizar.clase})  
    @Length(mín. = 2, máx. = 10, grupos = {Guardar.clase, Actualizar.clase})  
    private String nombre de usuario  
  
    @NotNull(grupos = {Guardar.clase, Update .class})  
    @Length(min = 6, max = 20, groups = {Save.class, Update.class})  
    contraseña de cadena privada;  
  
}  
Especifique el grupo de verificación en la anotación @Validated

@PostMapping("/guardar")  
public Result saveUser(@RequestBody @Validated(UserDTO.Save.class) UserDTO userDTO) {  
  
    return Result.ok();  
}  
  
@PostMapping("/update")  
public Result updateUser(@RequestBody @ Validated(UserDTO.Update.class) UserDTO userDTO) {  
  
    return Result.ok();  
}  
Validación anidada 
En el ejemplo anterior, los campos en la clase DTO son todos tipos de datos básicos y tipos de cadena. Pero en escenarios reales, es posible que cierto campo también sea un objeto.En este caso, se puede usar la validación anidada.

Por ejemplo, cuando la información del usuario se guarda arriba, también se incluye la información de la dirección. Cabe señalar que en este momento, el campo correspondiente de la clase DTO debe marcarse con la anotación @Valid.

@Data  
public class UserDTO {  
  
    @Min(value = 100000000000000000L, groups = Update.class)  
    private Long userId;  
  
    @NotNull(grupos = {Guardar.clase, Actualizar.clase})  
    @Length(mín. = 2, máx. = 10, grupos = {Guardar.clase, Actualizar.clase})  
    private String nombre de usuario;  
  
    @NotNull(groups = {Save.class, Update.class})  
    @Length(min = 6, max = 20, groups = {Save.class, Update.class})  
    contraseña de cadena privada;  
  
    @NotNull(grupos = {Guardar.clase, Actualizar.clase})  
    @  
    Dirección privada válida addr;  
  
    @Data  
    dirección de clase estática pública{  
  
        @Min(valor = 1, grupos = Actualizar.clase)  
        private Long addrId;  
  
        @NotNull(groups = {Save.class, Update.class})  
        @Length(min = 2, max = 10, groups = {Save.class, Update.class})  
        private String addrName;  
  
        @NotNull(groups = {Guardar.clase, Actualizar.clase})  
        @Length(mín. = 2, máx. = 10, grupos = {Guardar.clase, Actualizar.clase})  
        Ubicación de la cadena privada;  
    }  
}  
Validación de la colección 
si el cuerpo de la solicitud pasa directamente una colección Al fondo, y esperamos realizar la verificación de parámetros en cada elemento de la colección. En este punto, si usamos directamente la lista o configuramos en java.util.Collection para recibir datos, ¡la verificación de parámetros no tendrá efecto! Podemos usar una colección de lista personalizada para recibir parámetros:

La verificación de la colección verificará cada elemento de la colección, por ejemplo, el campo List<Address> verificará cada objeto de dirección en la lista.

Colección de listas personalizadas
clase pública ValidationList<E> implementa List<E> {  
  
    @Delegate  
    @Valid  
    public List<E> list = new ArrayList<>();  
  
    @Override  
    public String toString() {  
        return list.toString();  
    }  
}  
La anotación @Delegate está limitada por la versión de lombok y es compatible con versiones anteriores a la 1.18.6. Si la verificación falla, se lanzará una NotReadablePropertyException, que también se puede manejar con una excepción unificada.

Guarde varios objetos de usuario en una solicitud

@PostMapping("/saveList")  
public Result saveList(@RequestBody @Validated(UserDTO.Save.class) ValidationList<UserDTO> userList) {  
  
    return Result.ok();  
}  
@Valid和@Validated区别

Supongo que te gusta

Origin blog.csdn.net/qq_36647209/article/details/130184397
Recomendado
Clasificación