java校验bean_SpringMVC参数校验,包括JavaBean和基本类型的校验

该示例项目使用SpringBoot,添加web和aop依赖。

SpringMVC最常用的校验是对一个javaBean的校验,默认使用hibernate-validator校验框架。而网上对校验单个参数,譬如String,int之类的资料极少,这一篇就是讲这个的。

校验JavaBean

package com.example.bean;

import org.hibernate.validator.constraints.Length;

import org.hibernate.validator.constraints.NotEmpty;

/**

* Created by admin on 17/5/3.

*/

public classUser{

private Long id;

@NotEmpty(message = "姓名不能为空")

private String name;

@NotEmpty(message = "密码不能为空")

@Length(min = 6, message = "密码长度不能小于6位")

private String password;

publicLonggetId(){

return id;

}

publicvoidsetId(Long id){

this.id = id;

}

publicStringgetName(){

return name;

}

publicvoidsetName(String name){

this.name = name;

}

publicStringgetPassword(){

return password;

}

publicvoidsetPassword(String password){

this.password = password;

}

}

定义了@NotEmpty等标签后,结合在Controller里使用@Valid即可完成参数的校验。

package com.example.controller;

import com.example.bean.User;

import org.hibernate.validator.constraints.Length;

import org.hibernate.validator.constraints.Range;

import org.springframework.validation.BindingResult;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

/**

* Created by wuwf on 17/4/27.

*

*/

@RestController

public classFirstController{

@RequestMapping("/first")

publicObjectfirst(@Valid User user, BindingResult bindingResult){

return "first controller";

}

@RequestMapping("/second")

public @Length Objectsecond(@Length(min =6, message ="密码长度不能小于6位") String password){

return "second controller";

}

@RequestMapping("/third")

public @Length Objectthird(@Range(min =6, max =10, message ="数据需要大于6小于10")intnum,@Length(min =6, message ="密码长度不能小于6位") String password){

return "third controller";

}

@RequestMapping("/four")

public @Length Objectfour(intpage){

return "four controller";

}

}

譬如first方法里,只需要加上@Valid标签即可完成校验。如果校验不通过,那么错误信息就会封装到BindingResult对象了,可以通过bindingResult的相关方法获取详细的错误信息并返回给用户。

访问:http://localhost:8080/first?name=1&password=1 debug可看到

4c7ba9316dbfbe43901a1541bbb2c394.png

如果不加BindingResult则会抛出异常。

此时即可完成表单类,或者用户注册之类的类似请求的参数校验了,可以选择获取bindingResult信息后直接return给用户。如果这样的需要校验的地方比较多,每个都单独处理比较麻烦,可以通过aop统一处理返回,后面会讲到。

校验的标签可参考:http://blog.csdn.net/catoop/article/details/51278675

相关文章:http://412887952-qq-com.iteye.com/blog/2312356

校验基本类型

在很多场景下,我们不需要校验一个javaBean,更多的是校验单个的int,String等。也就是controller里的second和third方法。像方法中写的那样,但是直接写上去,是不起作用的,校验框架并没有去校验,我们需要做的就是让它生效。

参考如下:https://diamondfsd.com/article/78fa12cd-b530-4a90-b438-13d5a0c4e26c

http://blog.csdn.net/catoop/article/details/51284638

直接上代码吧

package com.example.aop;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.Around;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Pointcut;

import org.aspectj.lang.reflect.MethodSignature;

import org.hibernate.validator.internal.engine.path.PathImpl;

import org.springframework.core.LocalVariableTableParameterNameDiscoverer;

import org.springframework.core.ParameterNameDiscoverer;

import org.springframework.stereotype.Component;

import org.springframework.validation.BeanPropertyBindingResult;

import org.springframework.validation.ObjectError;

import javax.validation.ConstraintViolation;

import javax.validation.Validation;

import javax.validation.ValidatorFactory;

import javax.validation.executable.ExecutableValidator;

import java.lang.reflect.Method;

import java.util.List;

import java.util.Set;

/**

* Created by wuwf on 17/4/27.

* 参数校验切面

*/

@Aspect

@Component

public classValidAspect{

private ObjectError error;

@Pointcut("execution(public * com.example.controller.*.*(..))")

publicvoidvalid(){

}

//环绕通知,环绕增强,相当于MethodInterceptor

@Around("valid()")

publicObjectarround(ProceedingJoinPoint pjp){

System.out.println("方法环绕start.....");

try {

//取参数,如果没参数,那肯定不校验了

Object[] objects = pjp.getArgs();

if (objects.length == 0) {

return pjp.proceed();

}

/**************************校验封装好的javabean**********************/

//寻找带BindingResult参数的方法,然后判断是否有error,如果有则是校验不通过

for (Object object : objects) {

if (object instanceof BeanPropertyBindingResult) {

//有校验

BeanPropertyBindingResult result = (BeanPropertyBindingResult) object;

if (result.hasErrors()) {

List list = result.getAllErrors();

for (ObjectError error : list) {

System.out.println(error.getCode() + "---" + error.getArguments() + "--" + error.getDefaultMessage());

//返回第一条校验失败信息。也可以拼接起来返回所有的

return error.getDefaultMessage();

}

}

}

}

/**************************校验普通参数*************************/

// 获得切入目标对象

Object target = pjp.getThis();

// 获得切入的方法

Method method = ((MethodSignature) pjp.getSignature()).getMethod();

// 执行校验,获得校验结果

Set> validResult = validMethodParams(target, method, objects);

//如果有校验不通过的

if (!validResult.isEmpty()) {

String[] parameterNames = parameterNameDiscoverer.getParameterNames(method); // 获得方法的参数名称

for(ConstraintViolation constraintViolation : validResult) {

PathImpl pathImpl = (PathImpl) constraintViolation.getPropertyPath(); // 获得校验的参数路径信息

int paramIndex = pathImpl.getLeafNode().getParameterIndex(); // 获得校验的参数位置

String paramName = parameterNames[paramIndex]; // 获得校验的参数名称

System.out.println(paramName);

//校验信息

System.out.println(constraintViolation.getMessage());

}

//返回第一条

return validResult.iterator().next().getMessage();

}

return pjp.proceed();

} catch (Throwable e) {

e.printStackTrace();

return null;

}

}

private ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();

private final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();

private final ExecutableValidator validator = factory.getValidator().forExecutables();

private Set> validMethodParams(T obj, Method method, Object[] params) {

return validator.validateParameters(obj, method, params);

}

}

注释写的比较清楚了,这是一个aop切面类,拦截请求,并获取方法里的所有参数。第65行到85行是对普通参数进行校验的。

加上这几行代码后在controller里写的那些才会生效,并且把校验信息保存到了ConstraintViolation的Set集合里,判断Set是否有值,即可知道是否有校验不通过的信息,然后就可以取到校验信息并返回给用户,然后结束方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值