springmvc使用JSR-303进行校验

来源:互联网 发布:进口商品数据 编辑:程序博客网 时间:2024/06/05 17:40

下面提供一种springmvc的校验方案,一般没有校验或者手动写validator的话都要写好多代码好多if判断,使用JSR-303规范校验只需要在Pojo字段上加上相应的注解就可以实现校验了

1.依赖的jar包,我直接贴pom了

[html] view plain copy
  1. <properties>  
  2.     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
  3.     <spring.version>4.1.1.RELEASE</spring.version>  
  4. </properties>  
  5.   
  6. <dependencies>  
  7.     <dependency>  
  8.         <groupId>com.fasterxml.jackson.core</groupId>  
  9.         <artifactId>jackson-core</artifactId>  
  10.         <version>2.4.0</version>  
  11.     </dependency>  
  12.     <dependency>  
  13.         <groupId>com.fasterxml.jackson.core</groupId>  
  14.         <artifactId>jackson-databind</artifactId>  
  15.         <version>2.4.0</version>  
  16.     </dependency>  
  17.     <dependency>  
  18.         <groupId>commons-fileupload</groupId>  
  19.         <artifactId>commons-fileupload</artifactId>  
  20.         <version>1.3.1</version>  
  21.     </dependency>  
  22.     <dependency>  
  23.         <groupId>javax.servlet</groupId>  
  24.         <artifactId>javax.servlet-api</artifactId>  
  25.         <version>3.1.0</version>  
  26.     </dependency>  
  27.     <dependency>  
  28.         <groupId>javax.validation</groupId>  
  29.         <artifactId>validation-api</artifactId>  
  30.         <version>1.1.0.Final</version>  
  31.     </dependency>  
  32.     <dependency>  
  33.         <groupId>org.hibernate</groupId>  
  34.         <artifactId>hibernate-validator</artifactId>  
  35.         <version>5.1.3.Final</version>  
  36.     </dependency>  
  37.     <dependency>  
  38.         <groupId>org.springframework</groupId>  
  39.         <artifactId>spring-orm</artifactId>  
  40.         <version>${spring.version}</version>  
  41.     </dependency>  
  42.     <dependency>  
  43.         <groupId>org.springframework</groupId>  
  44.         <artifactId>spring-context</artifactId>  
  45.         <version>${spring.version}</version>  
  46.     </dependency>  
  47.     <dependency>  
  48.         <groupId>org.springframework</groupId>  
  49.         <artifactId>spring-web</artifactId>  
  50.         <version>${spring.version}</version>  
  51.     </dependency>  
  52.     <dependency>  
  53.         <groupId>org.springframework</groupId>  
  54.         <artifactId>spring-webmvc</artifactId>  
  55.         <version>${spring.version}</version>  
  56.     </dependency>  
  57.     <dependency>  
  58.         <groupId>org.springframework</groupId>  
  59.         <artifactId>spring-test</artifactId>  
  60.         <version>${spring.version}</version>  
  61.     </dependency>  
  62.     <dependency>  
  63.         <groupId>org.slf4j</groupId>  
  64.         <artifactId>slf4j-log4j12</artifactId>  
  65.         <version>1.7.7</version>  
  66.     </dependency>  
  67.     <dependency>  
  68.         <groupId>junit</groupId>  
  69.         <artifactId>junit</artifactId>  
  70.         <version>4.11</version>  
  71.         <scope>test</scope>  
  72.     </dependency>  
  73.     <dependency>  
  74.         <groupId>org.aspectj</groupId>  
  75.         <artifactId>aspectjweaver</artifactId>  
  76.         <version>1.8.4</version>  
  77.     </dependency>  
  78.     <dependency>  
  79.         <groupId>javax.el</groupId>  
  80.         <artifactId>javax.el-api</artifactId>  
  81.         <version>3.0.0</version>  
  82.     </dependency>  
  83. </dependencies>  
2.springmvc配置

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"  
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xmlns:mvc="http://www.springframework.org/schema/mvc"  
  6.     xmlns:aop="http://www.springframework.org/schema/aop"  
  7.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  8.         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
  9.         http://www.springframework.org/schema/tx   
  10.         http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
  11.         http://www.springframework.org/schema/context  
  12.         http://www.springframework.org/schema/context/spring-context-3.0.xsd  
  13.         http://www.springframework.org/schema/mvc  
  14.         http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd  
  15.         http://www.springframework.org/schema/aop   
  16.         http://www.springframework.org/schema/aop/spring-aop.xsd">  
  17.   
  18.     <!-- 默认的注解映射的支持 -->  
  19.     <mvc:annotation-driven/>  
  20.     <context:annotation-config/>  
  21.     <aop:aspectj-autoproxy/>  
  22.   
  23.     <!-- 自动扫描的包名 -->  
  24.     <context:component-scan base-package="spring.test.web.controller"/>  
  25.       
  26.     <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />  
  27.       
  28. </beans>  

3.写java代码了

先建一个User类

[java] view plain copy
  1. public class User {  
  2.     @NotNull  
  3.     private String username;  
  4.       
  5.     @NotNull(message = "密码不能为空")  
  6.     private String password;  
  7.       
  8.     public String getUsername() {  
  9.         return username;  
  10.     }  
  11.       
  12.     public void setUsername(String username) {  
  13.         this.username = username;  
  14.     }  
  15.       
  16.     public String getPassword() {  
  17.         return password;  
  18.     }  
  19.       
  20.     public void setPassword(String password) {  
  21.         this.password = password;  
  22.     }  
  23.       
  24. }  
然后建一个controller试试
[java] view plain copy
  1. @ResponseBody  
  2. @RequestMapping("/test1")  
  3. public AjaxResponse validateTest1(@Valid User user, BindingResult result){  
  4.     AjaxResponse ajaxResponse = new AjaxResponse();  
  5.     Map<String, Object> map = new HashMap<>();  
  6.     if(result.hasErrors()){  
  7.         ajaxResponse.setSuccess(false);  
  8.         ajaxResponse.setHasErrors(true);  
  9.         map.put("errors", result.getAllErrors());  
  10.     }  
  11.     else {  
  12.         map.put("now"new Date());  
  13.         map.put("user", user);  
  14.     }  
  15.     ajaxResponse.setData(map);  
  16.     return ajaxResponse;  
  17. }  

这个方法第一个参数上加了@Valid标注,第二个参数是必须的而且必须紧跟着@Valid参数之后,校验结果都在这个result里面

方法逻辑比较简单,调用result.hasErrors()看校验有没有错误,有错误的话就把所有的错误放进结果返回给客户端,如果没有错误就返回当前时间跟user对象

然后写个测试方法试试

[java] view plain copy
  1. @Test  
  2. public void test1() throws Exception{  
  3.     this.mockMvc.perform(post("/validator/test1")).andDo(print());  
  4.     this.mockMvc.perform(post("/validator/test1").param("username""testusername").param("password""testpassword")).andDo(print());  
  5. }  

第一个请求的结果是

[javascript] view plain copy
  1. {"success":false,"message":null,"hasErrors":true,"data":[{"name":"user","message":"may not be null"},{"name":"user","message":"密码不能为空"}]}  

第二个请求结果是

[javascript] view plain copy
  1. {"success":true,"message":null,"hasErrors":false,"data":{"now":1420788232169,"user":{"username":"testusername","password":"testpassword"}}}  

很明显第一次请求没有用户名和密码两个字段校验都没有通过,第二次是成功的

用起来还是很简单的,但是如果我不想每次都在controller方法里写if(result.hasErrors())怎么办呢,写个切面,把if写在切面里,如果有errors直接就返回了,不用再执行controller方法了

[java] view plain copy
  1. @Aspect  
  2. public class ValidAspect {  
  3.       
  4.     @Autowired private Validator validator;  
  5.       
  6.     @Around("@annotation(org.springframework.web.bind.annotation.ResponseBody)")  
  7.     public Object doTest(ProceedingJoinPoint pjp) throws Throwable{  
  8.         MethodSignature signature = (MethodSignature) pjp.getSignature();  
  9.         Method method = signature.getMethod();  
  10.         if(!AjaxResponse.class.equals(method.getReturnType())){  
  11.             pjp.proceed();  
  12.         }  
  13.         Object[] args = pjp.getArgs();  
  14.         Annotation[][] annotations = method.getParameterAnnotations();  
  15.         for(int i = 0; i < annotations.length; i++){  
  16.             if(!hasValidAnnotation(annotations[i])){  
  17.                 continue;  
  18.             }  
  19.             if(!(i < annotations.length-1 && args[i+1instanceof BindingResult)){  
  20.                 //验证对象后面没有跟bindingResult,事实上如果没有应该到不了这一步  
  21.                 continue;  
  22.             }  
  23.             BindingResult result = (BindingResult) args[i+1];  
  24.             if(result.hasErrors()){  
  25.                 AjaxResponse ajaxResponse = new AjaxResponse();  
  26.                 ajaxResponse.setSuccess(false);  
  27.                 ajaxResponse.setHasErrors(true);  
  28.                 ajaxResponse.setData(processErrors(result));  
  29.                 return ajaxResponse;  
  30.             }  
  31.         }  
  32.         return pjp.proceed();  
  33.     }  
  34.   
  35.     private boolean hasValidAnnotation(Annotation[] annotations){  
  36.         if(annotations == null){  
  37.             return false;  
  38.         }  
  39.         for(Annotation annotation : annotations){  
  40.             if(annotation instanceof Valid){  
  41.                 return true;  
  42.             }  
  43.         }  
  44.         return false;  
  45.     }  
  46.       
  47.     private List<BindingError> processErrors(BindingResult result){  
  48.         if(result != null && result.hasErrors()){  
  49.             List<BindingError> list = new ArrayList<BindingError>();  
  50.             for(ObjectError error : result.getAllErrors()){  
  51.                 BindingError be = new BindingError();  
  52.                 be.setMessage(error.getDefaultMessage());  
  53.                 be.setName(error.getObjectName());  
  54.                 list.add(be);  
  55.             }  
  56.             return list;  
  57.         }  
  58.         return null;  
  59.     }  
  60. }  

注意要在springmvc配置文件加一行<bean class="spring.test.web.aop.ValidAspect"/>

然后再写个方法逻辑跟上面的类似

[java] view plain copy
  1. @ResponseBody  
  2. @RequestMapping("/test2")  
  3. public AjaxResponse validateTest2(@Valid User user, BindingResult result){  
  4.     AjaxResponse ajaxResponse = new AjaxResponse();  
  5.     Map<String, Object> map = new HashMap<>();  
  6.     map.put("now"new Date());  
  7.     map.put("user", user);  
  8.     ajaxResponse.setData(map);  
  9.     return ajaxResponse;  
  10. }  

这里没有再去判断hasErrors()了,然后测试一下

写测试方式试一下

[java] view plain copy
  1. @Test  
  2. public void test2() throws Exception{  
  3.     this.mockMvc.perform(post("/validator/test2")).andDo(print());  
  4.     this.mockMvc.perform(post("/validator/test2").param("username""testusername").param("password""testpassword")).andDo(print());  
  5. }  

第一个请求结果是

[javascript] view plain copy
  1. {"success":false,"message":null,"hasErrors":true,"data":[{"name":"user","message":"密码不能为空"},{"name":"user","message":"may not be null"}]}  
第二个请求结果是

[java] view plain copy
  1. {"success":true,"message":null,"hasErrors":false,"data":{"now":1420788479105,"user":{"username":"testusername","password":"testpassword"}}}  
效果跟上面是一样的

当然我这个切面仅仅是个示范,我拦截的是带有ResponseBody注解的方法,我这些方法会返回一个统一的格式,如果是要返回别的视图就要自己定义注解加其他参数了

JSR-303原生支持的校验注解也是有限的,如果要实现其他的验证,可以自己拓展,拓展方法就下次再说了,我也才刚接触。



阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 风月无边林家成 林家成新书 林家成经典作品 林家成作品集 南朝春色 林家成 美绝兽寰 林家成 一夜难求 林家成 绝色天医 林家成 凤月无边 林家成 误长生 林家成 情狐 林家成 类似林家成作品 骄骄无双林家成 林家成作品哪个好看 林家成作品魏晋三部曲 林家 娇娇无双 恃运而娇txt下载 林家栋图片 林家栋东莞仔 林家栋老婆 东莞仔林家栋 林家栋沙发后式入陈法拉 氟班色林 氟班色林喝下多久有效果 林老师的特殊班by 林家耀 第一豪婿林阳全文阅读 都世神豪林云 超级神豪林云免费阅读版 第一豪婿林阳许苏晴在线阅读 第一豪婿林阳目录 林恒林枫神豪 都是神豪林云免费阅读全文 都市神豪林云免费阅读结局 第一豪婿林阳免费 第一豪胥林阳 都市神豪林云无弹窗 都市神豪林云txt 都市神豪林云完整版 绝顶神豪林云