Verificación de grupo @valid, activar manualmente la verificación válida

Escenario de negocios: 同一个接口,不同的操作cuando el tiempo, verifique que el campo sea diferente. Por ejemplo, cuando se cambia el estado, cuando los campos a verificar son diferentes para la aprobación y cancelación de la solicitud de licencia.
Sin embargo, la anotación @valid convencional no es satisfactoria (interceptación de parámetros al solicitar, activación de reglas de validación). Y mi escenario empresarial debe activar manualmente la verificación @valid

No hay muchas tonterías, lo siguiente muestra directamente las ideas y los códigos relacionados principales.

1. Ideas de diseño

En esencia, la razón por la cual @Valid convencional no cumple con los requisitos es:
1. La misma interfaz activa una verificación de campo de grupo diferente según el tipo de campo
2. Activa manualmente la verificación de grupo válido.
Suplemento: lo que quiero decir con @valid normal es @Validated(value = {People.Student.class}), el código es el siguiente:

    /**
     * <p>@Description: 请求拦截-根据分组进行参数校验 </p >
     * <p>@param [people]</p >
     * <p>@return com.lzq.learn.domain.CommonResult</p >
     * <p>@throws </p >
     * <p>@date 14:37 14:37</p >
     */
    @PostMapping("validByGroup")
    public CommonResult validByGroup(@RequestBody @Validated(value = {
    
    People.Student.class}) People people) {
    
    
        System.out.println("People 参数:" + people);
        CommonResult commonResult = CommonResult.success(people);
        return commonResult;
    }

2. Pantalla de código completo

2.1 código del controlador

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.lzq.learn.domain.CommonResult;
import com.lzq.learn.domain.People;
import com.lzq.learn.domain.User;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.*;
import javax.validation.groups.Default;
import java.util.List;
import java.util.Set;

@RestController
@RequestMapping("valid")
public class TestValidController {
    
    


    @Autowired
    private Validator validator;

    /**
     * <p>@Description: 测试手动触发valid分组校验</p >
     * <p>@param [userList]</p >
     * <p>@return com.lzq.learn.domain.CommonResult</p >
     * <p>@throws </p >
     * <p>@date 15:21 15:21</p >
     */
    @PostMapping("validByHand")
    public CommonResult validByHand(@RequestBody People people) {
    
    
        System.out.println("people  参数:" + people);
        String validResult = "";
        List<Class> groupList = CollUtil.newArrayList(Default.class);
        if (StrUtil.equals("student", people.getType())) {
    
    
            groupList.add(People.Student.class);
        }
        if (StrUtil.equals("teacher", people.getType())) {
    
    
            groupList.add(People.Teacher.class);
        }
        Class[] groupArray = groupList.toArray(new Class[groupList.size()]);
        // 写法1:使用ValidatorFactory 获取Validator对象
        Set<ConstraintViolation<People>> violations = Validation.buildDefaultValidatorFactory().getValidator().validate(people, groupArray);
        // 写法2:从springboot上下文 获取Validator对象
        // Set<ConstraintViolation<People>> violations = validator.validate(people, groupArray);
        validResult = getResultFromValidate(violations);
        CommonResult commonResult = CommonResult.success(validResult);
        return commonResult;
    }


    /**
     * <p>@Description: 对于valid校验结果进行转换结果</p >
     * <p>@param </p >
     * <p>@return </p >
     * <p>@throws </p >
     * <p>@date 13:43 13:43</p >
     */
    public static <T> String getResultFromValidate(Set<ConstraintViolation<T>> violations) {
    
    
        if (CollUtil.isEmpty(violations)) {
    
    
            return "pass";
        }
        StringBuilder sb = new StringBuilder();
        for (ConstraintViolation<T> violation : violations) {
    
    
            sb.append(violation.getPropertyPath()).append(": ").append(violation.getMessage()).append("\n");
        }
        return sb.toString();
    }
    
}

注意:Necesitamos activarlo manualmente, por lo que no podemos agregar anotaciones @valid (o @validated) a la interfaz del controlador, de lo contrario, la solicitud será interceptada y no podremos ingresar nuestro código de controlador.

2.2 Clase de entidad Código de personas


import lombok.*;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;

/**
 * @author x
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class People implements Serializable {
    
    

    /**     自定义校验分组        **/
    public interface Student{
    
    }
    public interface Teacher{
    
    }

    private Long id;

    @NotNull(message = "年龄不能为空")
    private Integer age;

    @NotBlank(message = "个人名称不能为空")
    private String myName;

    @NotBlank(message = "学生名称不能为空", groups = Student.class)
    private String studentName;

    @NotBlank(message = "教师名称不能为空", groups = Teacher.class)
    private String teacherName;

    // dto 字段
    private String type;
}

Nota: Para esta clase de entidad, los campos edad y miNombre no especifican grupos, pero en realidad están asignados a Default.classgrupos (javax.validation.groups.Default)

3. prueba de interfaz postMan

Para una breve descripción general, este artículo solo realiza un análisis de prueba para el caso de type=student. De acuerdo con el código anterior, cuando type=student, se realizará la verificación grupal de Default y Student, como se muestra en la prueba de la interfaz del cartero como se muestra abajo

3.1 tipo = estudiante, no pase el campo de grupo predeterminado

inserte la descripción de la imagen aquí

3.1 type=student, no pasar el campo de grupo de estudiantes

inserte la descripción de la imagen aquí

3.1 type=student, no pasar el campo de grupo de profesores

inserte la descripción de la imagen aquí

3.1 type=student, se pasan todos los campos del grupo

inserte la descripción de la imagen aquí

Como se muestra en la figura, encontramos que el código que escribimos es correcto y ha realizado 任意代码执行顺序la verificación de grupo autodefinida según el tipo. Pero la interfaz del controlador no debe anotarse con @valid o @validated, 不然请求会被拦截y no llegará a nuestro método personalizado en absoluto.

Este blog también acaba de cambiar el tiempo de ejecución de la verificación de parámetros válidos. De hecho, el código anterior solo proporciona la solución más básica, que se puede optimizar para agregar anotaciones personalizadas al método para realizar la intercepción de verificación de parámetros aop. Abstraiga este comportamiento para evitar la redundancia repetitiva del código.

Supongo que te gusta

Origin blog.csdn.net/lzq2357639195/article/details/131259458
Recomendado
Clasificación