SpringMVC参数校验,包括JavaBean和基本类型的校验(转载)
2017-12-12 11:30
621 查看
参考博客: SpringMVC参数校验,包括JavaBean和基本类型的校验
一、spingmvc引入Hibernate Validator校验框架,参考地址:http://blog.csdn.net/menghuanzhiming/article/details/78059876
二、校验JavaBean
1、javaben的实体类注解校验:
2、javaben定义了注解校验等标签后,结合在Controller里使用@Valid和BindingResult即可完成参数的校验。
譬如registerUser方法里,只需要加上@Valid标签即可完成校验。如果校验不通过,那么错误信息就会封装到BindingResult对象了,可以通过bindingResult的相关方法获取详细的错误信息并返回给用户。
如果不加BindingResult则会抛出异常。
此时即可完成表单类,或者用户注册之类的类似请求的参数校验了,可以选择获取bindingResult信息后直接return给用户。如果这样的需要校验的地方比较多,每个都单独处理比较麻烦,可以通过aop统一处理返回,后面会讲到。
校验的标签可参考:http://blog.csdn.net/catoop/article/details/51278675
相关文章:http://412887952-qq-com.iteye.com/blog/2312356
二、校验基本类型
在很多场景下,我们不需要校验一个javaBean,更多的是校验单个的int,String等。但是直接写上去,是不起作用的,校验框架并没有去校验,我们需要做的就是让它生效。
参考如下:https://diamondfsd.com/article/78fa12cd-b530-4a90-b438-13d5a0c4e26c
这里写链接内容
1、controller层添加注解校验:
controller层方法代码如下,既有javabean的校验也有简单参数的校验:
2、配置aop统一管理javabean的校验信息BindingResult以及使简单参数的注解校验生效:
(1)springmvc的controller配置aop注意事项:
参考连接:http://blog.csdn.net/menghuanzhiming/article/details/78780612
如果仍然无法使用aop请检查jar包是否冲突;
(2)配置文件:spring-aspect.xml
springmvc配置文件引入spring-aspect.xml文件:
切面类RequestParamValidAspect :
切面类中的环绕增强将校验错误汇总并返回;
参数异常处理类ParamValidException:
自定义校验错误实体类SimpleFiledError :
一、spingmvc引入Hibernate Validator校验框架,参考地址:http://blog.csdn.net/menghuanzhiming/article/details/78059876
二、校验JavaBean
1、javaben的实体类注解校验:
package edu.hrbeu.platform.modeling.pojo; import java.io.Serializable; import javax.validation.constraints.Pattern; import org.hibernate.validator.constraints.Email; import org.hibernate.validator.constraints.NotEmpty; public class User implements Serializable{ private Integer userId; @NotEmpty @Pattern(regexp="^[A-Za-z\u4e00-\u9fa5]{2,10}$", message="登录名:2-10位以内中文或英文或数字") private String username; @NotEmpty @Pattern(regexp="^[A-Za-z\u4e00-\u9fa5]{2,10}$", message="用户名:2-10位以内中文或英文或数字") private String alias; @NotEmpty @Pattern(regexp="^(?=.*[a-z])(?=.*[A-Z])[a-zA-Z\\d]{6,18}$", message="密码:6-18位以内数字和字母,至少各一个大小写字母") private String password; @NotEmpty @Email private String email; @NotEmpty @Pattern(regexp="^1[0-9]{10}$", message="手机号:11位以内中国大陆手机号") private String phone; }
2、javaben定义了注解校验等标签后,结合在Controller里使用@Valid和BindingResult即可完成参数的校验。
譬如registerUser方法里,只需要加上@Valid标签即可完成校验。如果校验不通过,那么错误信息就会封装到BindingResult对象了,可以通过bindingResult的相关方法获取详细的错误信息并返回给用户。
如果不加BindingResult则会抛出异常。
此时即可完成表单类,或者用户注册之类的类似请求的参数校验了,可以选择获取bindingResult信息后直接return给用户。如果这样的需要校验的地方比较多,每个都单独处理比较麻烦,可以通过aop统一处理返回,后面会讲到。
校验的标签可参考:http://blog.csdn.net/catoop/article/details/51278675
相关文章:http://412887952-qq-com.iteye.com/blog/2312356
/** * * @Title: RegisterUser * @Description: TODO(用户注册) * @return Map<String,Object> 返回类型 * @return */ @RequestMapping("registerUser") @ResponseBody @Operationlog(desc="用户注册") public Map<String, Object> registerUser( @Valid User user, BindingResult bindingResult ) { while(bindingResult.hasErrors()) { System.out.println("没有通过校验"); return null; } return null; }
二、校验基本类型
在很多场景下,我们不需要校验一个javaBean,更多的是校验单个的int,String等。但是直接写上去,是不起作用的,校验框架并没有去校验,我们需要做的就是让它生效。
参考如下:https://diamondfsd.com/article/78fa12cd-b530-4a90-b438-13d5a0c4e26c
这里写链接内容
1、controller层添加注解校验:
controller层方法代码如下,既有javabean的校验也有简单参数的校验:
/** * * @Title: RegisterUser * @Description: TODO(用户注册) * @return Map<String,Object> 返回类型 * @param user * @param confirmPassword * @param vercode * @param request * @return */ @RequestMapping("registerUser") @ResponseBody @Operationlog(desc="用户注册") public Map<String, Object> registerUser( @Valid User user, BindingResult bindingResult, @NotEmpty String confirmPassword, @NotEmpty String vercode) { return null; }
2、配置aop统一管理javabean的校验信息BindingResult以及使简单参数的注解校验生效:
(1)springmvc的controller配置aop注意事项:
参考连接:http://blog.csdn.net/menghuanzhiming/article/details/78780612
如果仍然无法使用aop请检查jar包是否冲突;
(2)配置文件:spring-aspect.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd"> <!-- 开启asepctj注解扫描 --> <aop:aspectj-autoproxy proxy-target-class="true"/> <!-- AOP的XML的aspectj配置 --> <bean id="requestParamValidAspect" class="edu.hrbeu.platform.modeling.common.aspect.RequestParamValidAspect"/> </beans>
springmvc配置文件引入spring-aspect.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> ... 省略 ... <import resource="spring-aspect.xml"/> </beans>
切面类RequestParamValidAspect :
package edu.hrbeu.platform.modeling.common.aspect; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.ElementKind; import javax.validation.Validation; import javax.validation.ValidatorFactory; import javax.validation.executable.ExecutableValidator; import org.aspectj.lang.JoinPoint; 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.NodeImpl; import org.hibernate.validator.internal.engine.path.PathImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.LocalVariableTableParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.FieldError; import org.springframework.validation.ObjectError; import edu.hrbeu.platform.modeling.exception.ParamValidException; import edu.hrbeu.platform.modeling.pojo.SimpleFiledError; /** * * @ClassName: RequestParamValidAspect * @Description: TODO(controller参数校验aspectj) * @author chenliming * @date 2017年12月12日 上午10:27:36 * */ @Aspect public class RequestParamValidAspect { private final ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); private final ExecutableValidator validator = factory.getValidator().forExecutables(); Logger log = LoggerFactory.getLogger(getClass()); @Pointcut("execution(public java.util.Map edu.hrbeu.platform.modeling.*.controller.*.*(..))") public void controllerAround() { } ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer(); /** * * @Title: around * @Description: TODO(环绕增强,校验controller参数) * @return Object 返回类型 * @param pjp * @return * @throws Throwable */ @Around("controllerAround()") public Object around(ProceedingJoinPoint pjp) throws Throwable { System.out.println("aspect参数校验start....."); try { // 取参数,如果没参数,那肯定不校验了 Object[] args = pjp.getArgs(); if (args.length == 0) { return pjp.proceed(); } List<SimpleFiledError> simpleFiledErrors = new ArrayList<>(); /************************** 校验封装好的javabean **********************/ // 寻找带BindingResult参数的方法,然后判断是否有error,如果有则是校验不通过 for (Object arg : args) { if (arg instanceof BeanPropertyBindingResult) { // 有校验 BeanPropertyBindingResult result = (BeanPropertyBindingResult) arg; if (result.hasErrors()) { List<ObjectError> list = result.getAllErrors(); for (ObjectError error : list) { // System.out.println( // error.getCode() + "---" + error.getArguments() + "--" + error.getDefaultMessage()); String name = null; if(error instanceof FieldError) { //字段名称 name = ((FieldError)error).getField(); } else { //对象名称 name = error.getObjectName(); } SimpleFiledError simpleFiledError = new SimpleFiledError(); simpleFiledError.setName(name); simpleFiledError.setMessage(error.getDefaultMessage()); simpleFiledErrors.add(simpleFiledError); } } } } /************************** 校验普通参数 *************************/ // 获得切入目标对象 Object target = pjp.getThis(); // 获得切入的方法 Method method = ((MethodSignature) pjp.getSignature()).getMethod(); // 执行校验,获得校验结果 Set<ConstraintViolation<Object>> validResult = validMethodParams(target, method, args); // 如果有校验不通过的 if (!validResult.isEmpty()) { String[] parameterNames = parameterNameDiscoverer.getParameterNames(method); // 获得方法的参数名称 for (ConstraintViolation<Object> constraintViolation : validResult) { PathImpl pathImpl = (PathImpl) constraintViolation.getPropertyPath(); // 获得校验的参数路径信息 NodeImpl leafNode = pathImpl.getLeafNode(); //判断是否是参数类型(如果是bean的属性无法获取index,抛出异常) if(leafNode.getKind() == ElementKind.PARAMETER) { int paramIndex = leafNode.getParameterIndex(); // 获得校验的参数位置 String paramName = parameterNames[paramIndex]; // 获得校验的参数名称 // //参数名称 // System.out.println(paramName); // // 校验信息 // System.out.println(constraintViolation.getMessage()); SimpleFiledError simpleFiledError = new SimpleFiledError(); simpleFiledError.setName(paramName); simpleFiledError.setMessage(constraintViolation.getMessage()); simpleFiledErrors.add(simpleFiledError); } } } if(!simpleFiledErrors.isEmpty()) { Map map = new HashMap(); map.put("success", false);//是否成功 map.put("message", "参数校验不成功");//文本消息 map.put("filedErrors", simpleFiledErrors); return map; } return pjp.proceed(); } catch (Throwable e) { e.printStackTrace(); throw e; } } public void before(JoinPoint point) throws ParamValidException { // 获得切入目标对象 Object target = point.getThis(); // 获得切入方法参数 Object[] args = point.getArgs(); // 获得切入的方法 Method method = ((MethodSignature) point.getSignature()).getMethod(); // 执行校验,获得校验结果 Set<ConstraintViolation<Object>> validResult = validMethodParams(target, method, args); if (!validResult.isEmpty()) { String[] parameterNames = parameterNameDiscoverer.getParameterNames(method); // 获得方法的参数名称 List<SimpleFiledError> errors = new ArrayList<>(); for (ConstraintViolation<Object> constraintViolation : validResult) { PathImpl pathImpl = (PathImpl) constraintViolation.getPropertyPath(); // 获得校验的参数路径信息 int paramIndex = pathImpl.getLeafNode().getParameterIndex(); // 获得校验的参数位置 String paramName = parameterNames[paramIndex]; // 获得校验的参数名称 SimpleFiledError error = new SimpleFiledError(); // 将需要的信息包装成简单的对象,方便后面处理 error.setName(paramName); // 参数名称(校验错误的参数名称) error.setMessage(constraintViolation.getMessage()); // 校验的错误信息 errors.add(error); System.out.println(paramName); // 校验信息 System.out.println(constraintViolation.getMessage()); } throw new ParamValidException(errors); // 我个人的处理方式,抛出异常,交给上层处理 } } private <T> Set<ConstraintViolation<T>> validMethodParams(T obj, Method method, Object[] params) { return validator.validateParameters(obj, method, params); } }
切面类中的环绕增强将校验错误汇总并返回;
参数异常处理类ParamValidException:
package edu.hrbeu.platform.modeling.exception; import java.util.List; import edu.hrbeu.platform.modeling.pojo.SimpleFiledError; public class ParamValidException extends Exception{ private static final long serialVersionUID = 1L; private List<SimpleFiledError> fieldErrors; public ParamValidException(List<SimpleFiledError> fieldErrors) { this.fieldErrors = fieldErrors; } }
自定义校验错误实体类SimpleFiledError :
package edu.hrbeu.platform.modeling.pojo; public class SimpleFiledError { private String name; private String message; public SimpleFiledError() { super(); // TODO Auto-generated constructor stub } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
相关文章推荐
- SpringMVC参数校验,包括JavaBean和基本类型的校验
- AOP日志,记录调用类、方法、方法参数名称、方法参数值(包括对象和基本类型)
- Springmvc学习笔记(4)之复杂参数类型绑定、校验、数据回显和异常处理
- SpringMVC使用@PathVariable ,参数接收使用基本类型
- AOP日志 记录方法参数名及对应值(包括对象和基本类型)
- SpringMVC绑定基本类型参数的问题
- SpringMvc 参数是对象,包含不提交基本类型的时候 400错误
- 基本数据类型和引用数据类型当做参数传递
- nginx配置:(一)基本配置与参数说明(转载)
- 彻底解决springMVC无法接受日期类型参数
- 基本、数组、引用类型的参数传递
- 学习SpringMVC(十)之确定目标方法POJO类型参数
- springmvc 接受 map类型的参数
- 基本数据类型参数的传值
- Springmvc注解开发:日期类型参数封装报错:The request sent by the client was syntactically incorrect.
- MATLAB图像处理(包括图像类型转换)----转载
- springMVC学习(6)-包装pojo类型、数组、list、Map类型参数绑定
- 基本数据类型的包装类型作为参数传递,以及其他引用类型作为参数传递,以及List中值的交换的一些问题
- 基本数据类型参数传递与引用型数据类型参数传递
- OC中Foundation集合的使用(其中包括基本数据类型与对象进行转换)