请您看下面的攻略。
SpringBoot中自定义注解实现参数非空校验的示例
1. 背景
在 SpringBoot 开发中,经常需要对方法的参数进行校验,确保参数的正确性。而参数非空校验是其中很重要的一项,避免了因为空指针等异常而导致程序崩溃。
无论你是使用 SpringMVC 的 @RequestParam、@PathVariable 注解获取请求参数,还是使用通用的 POJO 类封装参数,都需要进行参数校验。SpringBoot 提供了多种校验方式:使用 @NotNull、@NotEmpty、@NotBlank 注解等,在 Controller 方法上加上 @Validated 注解即可。但是,当需要大量重复输入校验注解时,会造成代码冗余。同时,不同开发者对于同一个参数可能会使用不同的校验规则,容易造成代码的混乱。
为此,本文会介绍使用自定义注解实现参数非空校验的示例,降低校验代码的冗余和混乱。
2. 实现步骤
2.1 创建注解类
首先,在我们的项目中创建一个注解类,用于标记需要进行非空校验的参数。我们可以通过 @Target 和 @Retention 注解,指定注解的作用对象和生命周期。
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotNullParam {
String value() default "";
String message() default "参数不能为空";
}
以上代码中,我们创建了一个名为 NotNullParam 的注解类。其中,@Target(ElementType.PARAMETER) 表示该注解只能作用于方法的参数上;@Retention(RetentionPolicy.RUNTIME) 表示注解的生命周期为运行时期。注解还提供了两个属性 value 和 message,value 属性可以用于指定注解名称;message 属性可以指定在参数为空时返回的提示信息,默认为 "参数不能为空"。
2.2 创建校验器
接下来,我们需要创建一个校验器类,用于对我们的注解进行校验。我们可以通过实现 Spring 的 Validator 接口实现该校验器,该接口提供了两个方法:supports 和 validate。
@Component
public class NotNullValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return Object[].class == clazz;
}
@Override
public void validate(Object target, Errors errors) {
Object[] params = (Object[]) target;
for (int i=0; i<params.length; i++) {
Object param = params[i];
if (param == null) {
NotNullParam annotation = getNotNullParamAnnotation(i, params);
String paramName = annotation.value();
if (StringUtils.isEmpty(paramName)) {
paramName = "参数" + i;
}
errors.reject(String.valueOf(i), paramName + "不能为空");
}
}
}
private NotNullParam getNotNullParamAnnotation(int index, Object[] params) {
MethodParameter parameter = new MethodParameter(getClass().getMethods()[0], index);
return parameter.getParameterAnnotation(NotNullParam.class);
}
}
以上代码中,我们创建了一个名为 NotNullValidator 的校验器类,其中,@Component 表示该类为 Spring 的一个组件,会自动扫描并注入到 Spring 容器中。该校验器实现了 Spring 的 Validator 接口,并实现了 supports 和 validate 两个方法。
在 supports 方法中,我们使用 Object[].class == clazz 来指定该校验器支持的校验对象类型,这里我们使用数组类型 Object[],因为我们希望对当前方法的参数列表进行校验。
在 validate 方法中,我们首先将校验对象转换为参数数组 params,并对 params 的每一个元素进行非空判断,如果该参数为空,则获取它的注解和位置信息,并使用 errors.reject 方法将错误信息加入校验结果中。
同时,我们还提供了一个 getNotNullParamAnnotation 方法,用于获取 NotNullParam 注解。其中,我们使用 MethodParameter 类获取 Method 对象和参数下标 index,并使用该参数下标获取对应的 NotNullParam 注解。
2.3 使用自定义注解
最后,我们使用自定义注解进行参数校验。我们只需要在需要进行校验的参数上,加上我们刚刚创建的注解即可。
@RequestMapping("/test")
@RestController
public class TestController {
@Autowired
private NotNullValidator notNullValidator;
@GetMapping("/hello")
public String hello(@NotNullParam("name") String name,
@NotNullParam("age") Integer age) {
notNullValidator.validate(new Object[]{name, age}, new BeanPropertyBindingResult(new Object[]{name, age}, "hello"));
return "hello, " + name + ", " + age;
}
}
以上代码中,我们在 Controller 的 hello 方法中,定义了两个接收参数的注解 @NotNullParam。这里我们还使用了 Autowired 注解,注入了我们刚刚创建的 NotNullValidator 校验器。
在方法参数中,我们通过使用 NotNullParam 注解,对当前参数进行非空校验。在方法体中,我们使用 notNullValidator.validate 方法进行校验,第一个参数传入需要校验的参数列表,第二个参数传入 errors,它是校验结果的封装类。
由于我们现在只提供了一个参数校验器,与目前的需求比较简单,所以当前校验器并没有模拟一个更完整的校验结果。如果我们有更复杂的校验需求,可以使用 Spring 提供的 Validated 注解和 BindingResult 类,它们提供了更详细和复杂的校验结果。
示例说明
- 在编写上述 @NotNullParam 注解时,我们添加了默认的 message 属性,以便在参数为空时提供一个默认的校验信息。如果需要自定义校验信息,可以使用 @NotNullParam(message="xxx") 的方式进行修改。
- 在校验器的 validate 方法中,我们只实现了简单的参数非空校验,实际开发中,我们可以根据不同的需求,添加各种校验规则,并将错误信息交给 errors 对象来封装。在直接调用校验器进行校验时,我们可以直接使用 Object[] 来进行校验,也可以使用对应的参数类型的包装类来进行校验,如 List、Map、DTO 对象等。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot中自定义注解实现参数非空校验的示例 - Python技术站