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.
Tabla de contenido
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.class
grupos (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
3.1 type=student, no pasar el campo de grupo de estudiantes
3.1 type=student, no pasar el campo de grupo de profesores
3.1 type=student, se pasan todos los campos del grupo
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.