博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring MVC 数据校验 -实现方式validate自定义注解
阅读量:3925 次
发布时间:2019-05-23

本文共 3670 字,大约阅读时间需要 12 分钟。

前言

自从我接触了spring-boot框架,对于基于注解的开发方式越来越中意,无疑这是一种提升开发效率和简化配置的开发方式。开发中对于方法入参数据校验是必须的也是严谨的,一方面是为了提升性能(对于不合法数据,或格式不正确的数据,不做处理,直接返回错误信息)。另一方面也是业务需求,对某些字段有着check。当我们使用spring框架来开发项目,其实spring-validation这个模块也已经提供了一些常用校验注解。例如@Size、@NotNull、@Email之类的格式或者非空校验。

分析

既然spring-validation这个模块已经提供一部分常用注解,但是在实际开发中的需求,并不能完全解决。

所以我们可以参照既有的注解的实现方式,照葫芦画瓢,也用注解来完成数据字段的校验。

源码分析

@Target({
ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})@Retention(RetentionPolicy.RUNTIME)@Repeatable(NotNull.List.class)@Documented@Constraint( validatedBy = {
}//1.注入校验类)public @interface NotNull {
//2.定义message String message() default "{javax.validation.constraints.NotNull.message}"; Class
[] groups() default {
};//支持分组校验 Class
[] payload() default {
}; @Target({
ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface List {
NotNull[] value(); }}

这个是validation包定义的@NotNull的注解接口的定义

此处需要注意我标注的两处
1.Constraint中注入校验类
2.校验用的message

@Documented@Target({
ElementType.ANNOTATION_TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface Constraint {
Class
>[] validatedBy();//校验类注入}

此处是@Constraint注解接口的定义

validatedBy 方法中可以传入ConstraintValidator的校验类

public interface ConstraintValidator {
default void initialize(A constraintAnnotation) {
} boolean isValid(T var1, ConstraintValidatorContext var2);//校验实现方法}

ConstraintValidator校验类接口,具体实现的校验类需要实现这个ConstraintValidator接口,实现isValid这个抽象方法。

分析总结:实装自定义注解校验,需要定义一个注解接口用于标识字段,需要一个ConstraintValidator的实现类,用于判断字段是否满足校验规则

实现

具体实现

@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documented@Constraint(validatedBy = IpCheckValidator.class)//校验实现类绑定public @interface IpCheck {
String message() default "{} ip address is not legal"; Class
[] groups() default {
}; Class
[] payload() default {
}; @Target({
ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface List {
IpCheck[] value(); }}

我这里是自定实现的ip地址check的注解

public class IpCheckValidator implements ConstraintValidator
{
//实现方法 @Override public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
String ipArry[] = value.split("\\."); if(ipArry.length==4){
int ipArryInt[] = new int[4]; for (int i=0;i<4;i++){
try {
ipArryInt[i]=Integer.parseInt(ipArry[i]); } catch (Exception e){
return false; } } if(ipArryInt[0]>=1&&ipArryInt[0]<=255) for (int j=1;j<4;j++){
if(ipArryInt[j]<0||ipArryInt[j]>255){
return false; } } return true; } return false; }}

使用方式

@IpCheck    private String ipAddress;

最后的校验信息存在BindingResult,通过hasErrors方法就可以判断校验是否通过

@RequestMapping(value = "/logon",method =RequestMethod.POST)    public BaseResponse userRegister(@RequestBody  @Valid RegisterUserInfo userInfo,                                     BindingResult result){
//判断校验是否有误 if(!result.hasErrors()){
//执行注册 service.register(userInfo); }else{
//抛出异常-提交参数格式不对 throw new APIException(HttpServletResponse.SC_BAD_REQUEST, "request parameters formatter is wrong "); } return NORMAL_RESPONSE; }

转载地址:http://rqugn.baihongyu.com/

你可能感兴趣的文章
C# 9 新特性 —— 补充篇
查看>>
Asp.Net Core使用Skywalking实现分布式链路追踪
查看>>
浅谈CLR基础知识
查看>>
Xamarin使XRPC实现接口/委托远程调用
查看>>
如何成功搞垮一个团队?
查看>>
.NET开源5年了,这些宝藏你还没get?
查看>>
【日常排雷】 .Net core 生产环境appsetting读取失败
查看>>
从内存中释放Selenium chromedriver.exe
查看>>
如何在 C# 中使用 MSMQ
查看>>
小试elsa
查看>>
巧用 Lazy 解决.NET Core中的循环依赖关系
查看>>
微前端架构在容器平台的应用
查看>>
C# 中的 null 包容运算符 “!” —— 概念、由来、用法和注意事项
查看>>
仓储模式到底是不是反模式?
查看>>
【One by One系列】IdentityServer4(一)OAuth2.0与OpenID Connect 1.0
查看>>
为什么人和人的差距这么大?
查看>>
ML.NET 推荐引擎中一类矩阵因子分解的缺陷
查看>>
微软2020开源回顾:止不住的挨骂,停不下的贡献
查看>>
说说 RabbiMQ 的应答模式
查看>>
OpenTelemetry - 云原生下可观测性的新标准
查看>>