很痛苦遇到大量的参数进行校验,在业务中还要抛出异常或者

返回异常时的校验信息,在代码中相当冗长,今天我们就来学习spring注解式参数校验.

其实就是:hibernate的validator.

开始啦......

1.controller的bean加上@Validated就像这样

     @ApiOperation(value = "用户登录接口", notes = "用户登录")
@PostMapping("/userLogin")
public ResponseDTO<UserResponseDTO> userLogin(@RequestBody @Validated RequestDTO<UserLoginRequestDTO> requestDto) {
return userBizService.userLogin(requestDto);
}

2.下面是一些简单的例子:如在Bean中添加注解:

 @Data
public class UserDTO implements Serializable {
private static final long serialVersionUID = -7839165682411118398L; @NotBlank(message = "用户名不能为空")
@Length(min=5, max=20, message="用户名长度必须在5-20之间")
@Pattern(regexp = "^[a-zA-Z_]\\w{4,19}$", message = "用户名必须以字母下划线开头,可由字母数字下划线组成")
private String username; @NotBlank(message = "密码不能为空")
@Length(min = 24, max = 44, message = "密码长度范围为6-18位")
private String password; @NotBlank(message = "手机号不能为空")
@Pattern(regexp = "^[1][3,4,5,6,7,8,9][0-9]{9}$", message = "手机号不合法")
private String phone; @Email(message = "邮箱格式不正确")
private String email; @NotNull(message = "简介编号不能为空")
@NotEmpty(message = "简介编号不能为空")
private List<Integer> introList; @Range(min=0, max=4,message = "基础规格")
private int scale; @NotNull(message = "比例不能为空")
@DecimalMax(value = "100", message = "最大比率是100%啦~")
@DecimalMin(value = "0.01", message = "最小比率是0.01%啦~")
private Double cashbackRatio;
38 }

3.最后我们要进行切面配置,处理校验类的异常:

 import com.cn.GateWayException;
import com.cn.alasga.common.core.dto.ResponseDTO;
import com.cn.ResponseCode;
import com.cn.alasga.common.core.exception.BizException;
import com.cn.TokenException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice; import javax.validation.ValidationException;
import java.util.regex.Matcher;
import java.util.regex.Pattern; /**
* @author Lijing
* @ClassName: ExceptionHandlerController.class
* @Description: 统一异常处理类
* @date 2017年8月9日 下午4:44:25
*/
@RestControllerAdvice
public class ExceptionHandlerController { private Logger log = LoggerFactory.getLogger(ExceptionHandlerController.class); private final static Pattern PATTERN = Pattern.compile("(\\[[^]]*])"); @ExceptionHandler(Exception.class)
public ResponseDTO handleException(Exception exception) { if (exception instanceof GateWayException) {
GateWayException gateWayException = (GateWayException) exception;
return new ResponseDTO<>(gateWayException);
} if (exception instanceof BizException) {
BizException biz = (BizException) exception;
return new ResponseDTO<>(biz);
} if (exception instanceof MethodArgumentNotValidException) {
MethodArgumentNotValidException methodArgumentNotValidException = (MethodArgumentNotValidException) exception;
return new ResponseDTO<>(methodArgumentNotValidException.getBindingResult().getFieldError()
.getDefaultMessage(), ResponseCode.PARAM_FAIL, ResponseDTO.RESPONSE_ID_PARAM_EXCEPTION_CODE);
} if (exception instanceof ValidationException) {
if (exception.getCause() instanceof TokenException) {
TokenException tokenException = (TokenException) exception.getCause();
return new ResponseDTO<>(tokenException);
}
} if (exception instanceof org.springframework.web.HttpRequestMethodNotSupportedException) {
return new ResponseDTO<>(ResponseCode.HTTP_REQUEST_METHOD_NOT_SUPPORTED);
} if (exception instanceof HttpMessageNotReadableException) {
log.error(exception.getMessage());
return new ResponseDTO<>(ResponseCode.HTTP_REQUEST_PARAMETER_INVALID_FORMAT);
} if (!StringUtils.isEmpty(exception.getMessage())) {
Matcher m = PATTERN.matcher(exception.getMessage());
if (m.find()) {
String[] rpcException = m.group(0).substring(1, m.group().length() - 1).split("-");
Integer code;
try {
code = Integer.parseInt(rpcException[0]);
} catch (Exception e) {
log.error(exception.getMessage(), exception);
return new ResponseDTO<>(ResponseDTO.RESPONSE_ID_BIZ_EXCEPTION_CODE, ResponseCode.RESPONSE_TIME_OUT);
}
return new ResponseDTO<>(ResponseDTO.RESPONSE_ID_BIZ_EXCEPTION_CODE, code, rpcException[1]);
}
} //主要输出不确定的异常
log.error(exception.getMessage(), exception); return new ResponseDTO<>(exception);
} }
MethodArgumentNotValidException 就是我们的 猪脚了 ,他负责获取这些参数校验中的异常,
ValidationException 是javax.的校验,和今天的校验也是有关系的,很久了,我都忘记验证了.

4.下面简单的解释一些常用的规则示意:

  1.@NotNull:不能为null,但可以为empty(""," ","   ")      
2.@NotEmpty:不能为null,而且长度必须大于0 (" "," ")
 3.@NotBlank:只能作用在String上,不能为null,而且调用trim()后,长度必须大于0("test") 即:必须有实际字符

5.是不是很简单: 学会了就去点个赞

验证注解

验证的数据类型

说明

@AssertFalse

Boolean,boolean

验证注解的元素值是false

@AssertTrue

Boolean,boolean

验证注解的元素值是true

@NotNull

任意类型

验证注解的元素值不是null

@Null

任意类型

验证注解的元素值是null

@Min(value=值)

BigDecimal,BigInteger, byte,

short, int, long,等任何Number或CharSequence(存储的是数字)子类型

验证注解的元素值大于等于@Min指定的value值

@Max(value=值)

和@Min要求一样

验证注解的元素值小于等于@Max指定的value值

@DecimalMin(value=值)

和@Min要求一样

验证注解的元素值大于等于@ DecimalMin指定的value值

@DecimalMax(value=值)

和@Min要求一样

验证注解的元素值小于等于@ DecimalMax指定的value值

@Digits(integer=整数位数, fraction=小数位数)

和@Min要求一样

验证注解的元素值的整数位数和小数位数上限

@Size(min=下限, max=上限)

字符串、Collection、Map、数组等

验证注解的元素值的在min和max(包含)指定区间之内,如字符长度、集合大小

@Past

java.util.Date,

java.util.Calendar;

Joda Time类库的日期类型

验证注解的元素值(日期类型)比当前时间早

@Future

与@Past要求一样

验证注解的元素值(日期类型)比当前时间晚

@NotBlank

CharSequence子类型

验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的首位空格

@Length(min=下限, max=上限)

CharSequence子类型

验证注解的元素值长度在min和max区间内

@NotEmpty

CharSequence子类型、Collection、Map、数组

验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)

@Range(min=最小值, max=最大值)

BigDecimal,BigInteger,CharSequence, byte, short, int, long等原子类型和包装类型

验证注解的元素值在最小值和最大值之间

@Email(regexp=正则表达式,

flag=标志的模式)

CharSequence子类型(如String)

验证注解的元素值是Email,也可以通过regexp和flag指定自定义的email格式

@Pattern(regexp=正则表达式,

flag=标志的模式)

String,任何CharSequence的子类型

验证注解的元素值与指定的正则表达式匹配

@Valid

任何非原子类型

指定递归验证关联的对象;

如用户对象中有个地址对象属性,如果想在验证用户对象时一起验证地址对象的话,在地址对象上加@Valid注解即可级联验证

此处只列出Hibernate Validator提供的大部分验证约束注解,请参考hibernate validator官方文档了解其他验证约束注解和进行自定义的验证约束注解定义。

6.是不是很简单: 我再教你看源码:

ValidationMessages.properties 就是校验的message,就可以顺着看下去了!!!

7.补充 自定义注解

很简单 找源码抄一份注解 比如我们来个 自定义身份证校验 注解

来 注解走起

@Documented
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = IdentityCardNumberValidator.class)
public @interface IdentityCardNumber { String message() default "身份证号码不合法"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {};
}

再实现校验接口

public class IdentityCardNumberValidator implements ConstraintValidator<IdentityCardNumber, Object> {

    @Override
public void initialize(IdentityCardNumber identityCardNumber) {
} @Override
public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
return IdCardValidatorUtils.isValidate18Idcard(o.toString());
}
}

最后 注解随便贴 IdCardValidatorUtils 是自己写的工具类 网上大把~  需要的可以加我vx: cherry_D1314

如此便是完成了自定义注解,将统一异常处理即可.

spring注解式参数校验的更多相关文章

  1. spring注解式参数校验列表

    校验注释列表: @AssertFalse Boolean,boolean 验证注解的元素值是false @AssertTrue Boolean,boolean 验证注解的元素值是true @NotNu ...

  2. 转 spring注解式参数校验

    转自: https://blog.csdn.net/jinzhencs/article/details/51682830 转自: https://blog.csdn.net/zalan01408980 ...

  3. Spring基础系列-参数校验

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9953744.html Spring中使用参数校验 概述 ​ JSR 303中提出了Bea ...

  4. Spring注解式事务解析

    #Spring注解式事务解析 增加一个Advisor 首先往Spring容器新增一个Advisor,BeanFactoryTransactionAttributeSourceAdvisor,它包含了T ...

  5. 【spring】-- jsr303参数校验器

    一.为什么要进行参数校验? 当我们在服务端控制器接受前台数据时,肯定首先要对数据进行参数验证,判断参数是否为空?是否为电话号码?是否为邮箱格式?等等. 这里有个问题要注意: 前端代码一般上会对这些数据 ...

  6. Spring注解式与配置文件式

    http://tom-seed.iteye.com/blog/1584632 Spring注解方式bean容器管理 1.通过在配置文件中配置spring组件注入 <context:compone ...

  7. SpringMVC学习笔记六:使用 hibernate-validator注解式数据校验

    对客户端传过来的参数,在使用前一般需要进行校验. SpringMVC框架内置了Validator验证接口,但是实现起来太麻烦.我们一般使用 hibernate-validator进行数据校验. 1:j ...

  8. springmvc JSR303 Validate 注解式,校验数据

    参考:http://www.cnblogs.com/liukemng/category/578644.html 先进行配置: <!-- 默认的注解映射的支持 --> <mvc:ann ...

  9. Spring注解式AOP面向切面编程.

    1.AOP指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式.aop底层是动态代理. package com.bie.config; import org.aspectj.lan ...

随机推荐

  1. 【原创】Mac book pro入手后,需要做哪些才能开始开展自动化测试工作

    2018国庆节,脑袋一热,入手了一台Mac book pro,从此掉坑到了这个异构的操作系统中,因为之前工作中接触了Windows.Linux.Unix等操作系统的诸多版本,基本的操作倒是不成问题,但 ...

  2. Hashtable与ConcurrentHashMap区别(转)

    转载地址: https://blog.csdn.net/wisgood/article/details/19338693

  3. mvcmovie sample 在window10 下的部署问题(HTTP Error 500.19 - Internal Server Error)

    mvcmovie sample 在window10 下的部署问题 使用VS2018配置好了mvcmovie sample,发布到IIS后,打开报错: HTTP Error 500.19 - Inter ...

  4. 三、CSS样式——字体

    概念: CSS字体属性定义文本的字体系列.大小.加粗.风格和变形. 属性 描述 font-family 设置字体系列 font-size 设置字体的大小 font-style 设置字体的风格 font ...

  5. Spring事务@Transactional标签深入学习

    事务管理是应用系统开发中必不可少的一部分.Spring为事务管理提供了丰富的功能支持.Spring事务管理分为编码式和声明式 两种方式.编码式事务指的是通过编码方式实现事务;声明式事务基于AOP,将具 ...

  6. 类名:IExternalCommandAvailability+IExternalCommand实现对某些控件的自定义使用

    起初对于这些名词不懂,后经查阅了解如下,希望对学习者能有所帮助.在Revil里大部分命令在没有打开文档的时候是禁用的,有的在没有打开文档也是可以使用的.而又一些在平面视图是禁用的如标高,有的在3D视图 ...

  7. Btrace官方教程-中文版

    教程英文版来源:https://github.com/btraceio/btrace/blob/master/docs/usersguide.html BTrace用户指南 BTrace是一种安全,动 ...

  8. 关于std::thread

    std::thread基本用法 1.普通函数: std::thread thread(func, param, ...) 2.类成员函数: std::thread thread(&class_ ...

  9. [Tools] Wireshark Primer Tutorials

    介绍就不说了,安装也没必要讲,关于如何使用,网上的辣鸡文过多,视频又太冗余. 我推荐看下面有条理的入门教程. 界面说明:http://openmaniak.com/cn/wireshark_use.p ...

  10. Java中获取系统时间的四种方式

    第一种: Date day=new Date(); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss" ...