SpringMVC 使用验证框架 Bean Validation(下)
来源:互联网 发布:移民文案知乎 编辑:程序博客网 时间:2024/06/06 19:10
本文接上一篇《SpringMVC 使用验证框架 Bean Validation(上)》:
四、Controller 普通参数验证与视图错误信息的展示
对于 form 表单提交绑定到对象的验证方式,上面已经介绍了。但是在很多时候,我们是通过普通传参来调用接口的。
比如:http://localhost:8080/myproject/hello?name=Shanhy&age=27&password=pwd
那么对于这种情况,我们该如何校验 name、age、password 的值呢?
看下面的 Controller 代码:
五、JSON 请求响应错误信息
package org.springboot.sample.interceptor;import java.util.HashMap;import java.util.Map;import java.util.Map.Entry;import java.util.Set;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.validation.ConstraintViolation;import javax.validation.ConstraintViolationException;import org.springframework.validation.BindingResult;import org.springframework.validation.FieldError;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;/** * JSON请求响应错误消息处理 * * @author 单红宇(365384722) * @myblog http://blog.csdn.net/catoop/ * @create 2016年4月17日 */public class JsonErrorMsgInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { if(modelAndView == null) return; // 因为MappingJackson2JsonView默认会把BindingResult全部过滤掉。 // 所以我们要想将错误消息输出,要在这里自己处理好。 // 判断请求是否是.json、方法上是否有@ResponseBody注解,或者类上面是否有@RestController注解 // 表示为json请求 if (!request.getRequestURI().endsWith(".json")) { HandlerMethod handlerMethod = (HandlerMethod)handler; if(handlerMethod.getMethodAnnotation(ResponseBody.class) == null){ if(handlerMethod.getBeanType().getAnnotation(RestController.class) == null){ return; } } } Map<String, Object> modelMap = modelAndView.getModel(); if (modelMap != null) { Map<String, String> errorMsg = null; if(modelMap.containsKey("errorMsg")){ errorMsg = (Map<String, String>)modelMap.get("errorMsg"); } if(errorMsg == null){ errorMsg = new HashMap<>(); modelMap.put("errorMsg", errorMsg); } for (Entry<String, Object> entry : modelMap.entrySet()) { if (entry.getValue() instanceof BindingResult) { BindingResult bindingResult = (BindingResult) entry.getValue(); if (bindingResult.hasErrors()) { for (FieldError fieldError : bindingResult.getFieldErrors()) { errorMsg.put(fieldError.getObjectName() + "." + fieldError.getField(), fieldError.getDefaultMessage()); } } } } } } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { }}
注意配置该拦截器配置,使其生效。
效果:
六、错误信息的配置文件
默认在 ValidationMessages.properties 配置文件中(参考 《SpringMVC 使用验证框架 Bean Validation(上)》中的第二点有样例)。
如果想统一使用 messaeg.properties 配置文件中的配置,下面的配置提供参考:
<!-- 指定自己定义的validator --> <mvc:annotation-driven validator="validator"/> <!-- 以下 validator ConversionService 在使用 mvc:annotation-driven 会 自动注册--> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/> <!-- 如果不加默认到 使用classpath下的 ValidationMessages.properties --> <property name="validationMessageSource" ref="messageSource"/> </bean> <!-- 国际化的消息资源文件(本系统中主要用于显示/错误消息定制) --> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basenames"> <list> <!-- 在web环境中一定要定位到classpath 否则默认到当前web应用下找 --> <value>classpath:messages</value> <value>classpath:org/hibernate/validator/ValidationMessages</value> </list> </property> <property name="useCodeAsDefaultMessage" value="false"/> <property name="defaultEncoding" value="UTF-8"/> <property name="cacheSeconds" value="60"/> </bean>
七、错误信息中使用EL表达式
请参考 《SpringMVC 使用验证框架 Bean Validation(上)》中的第二点。
八、方法级别的验证
首先注册 MethodValidationPostProcessor
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"> <!-- 可以引用自己的 validator 配置,在本文中(下面)可以找到 validator 的参考配置,如果不指定则系统使用默认的 --> <property name="validator" ref="validator"/> </bean>
某个 Service 的方法:
@Validated // 告诉MethodValidationPostProcessor此Bean需要开启方法级别验证支持 @Servicepublic class ValidatorTestService { public @Length(min = 12, max = 16, message = "返回值长度应该为12-16") String getContent( @NotBlank(message = "name不能为空") String name, @Size(min = 5, max = 10, message="{password.length.illegal}") String password) { return name + ":" + password; }}
在 Controller 调用该方法测试:
/** * 测试方法级别的验证(如果验证失败,则会抛出异常 ConstraintViolationException) * * @param name * @param model * @return * @author SHANHY * @create 2016年4月17日 */ @RequestMapping("/test5") @ResponseBody public Model test5(String name, String password, Model model){ try { String content = validatorTestService.getContent(name, password); model.addAttribute("name", content); } catch (ConstraintViolationException e) { addErrorMessage(model, e); } return model; } /** * 添加错误消息,建议将该方法提取为一个公共的方法使用。 * * @param model * @param e * @author SHANHY * @create 2016年5月4日 */ protected void addErrorMessage(Model model, ConstraintViolationException e){ Map<String, String> errorMsg = new HashMap<>(); model.addAttribute("errorMsg", errorMsg); for (ConstraintViolation<?> constraintViolation : e.getConstraintViolations()) { // 获得验证失败的类 constraintViolation.getLeafBean() // 获得验证失败的值 constraintViolation.getInvalidValue() // 获取参数值 constraintViolation.getExecutableParameters() // 获得返回值 constraintViolation.getExecutableReturnValue() errorMsg.put(constraintViolation.getLeafBean().getClass().getName() + "-" + constraintViolation.getPropertyPath().toString(), constraintViolation.getMessage()); } }
工具类
最后提供一个校验工具类,注意看第一个方法就行了:
/** * Copyright (c) 2005-2012 springside.org.cn */package org.springboot.sample.util;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.ConstraintViolationException;import javax.validation.Validator;/** * JSR303 Validator(Hibernate Validator)工具类. * * ConstraintViolation中包含propertyPath, message 和invalidValue等信息. * 提供了各种convert方法,适合不同的i18n需求: * 1. List<String>, String内容为message * 2. List<String>, String内容为propertyPath + separator + message * 3. Map<propertyPath, message> * * 详情见wiki: https://github.com/springside/springside4/wiki/HibernateValidator */public class BeanValidatorUtils { /** * 调用JSR303的validate方法, 验证失败时抛出ConstraintViolationException. * * 参数 Validator 可以直接注入,如: * * @Autowired * protected Validator validator; * */ public static void validateWithException(Validator validator, Object object, Class<?>... groups) throws ConstraintViolationException { Set<? extends ConstraintViolation<?>> constraintViolations = validator.validate(object, groups); if (!constraintViolations.isEmpty()) { throw new ConstraintViolationException(constraintViolations); // 调用处捕获异常后,获取错误信息的方法 // List<String> list = BeanValidatorUtils.extractPropertyAndMessageAsList(ex, ": "); } } /** * 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>中为List<message>. */ public static List<String> extractMessage(ConstraintViolationException e) { return extractMessage(e.getConstraintViolations()); } /** * 辅助方法, 转换Set<ConstraintViolation>为List<message> */ @SuppressWarnings("rawtypes") public static List<String> extractMessage(Set<? extends ConstraintViolation> constraintViolations) { List<String> errorMessages = new ArrayList<String>(); for (ConstraintViolation violation : constraintViolations) { errorMessages.add(violation.getMessage()); } return errorMessages; } /** * 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>为Map<property, message>. */ public static Map<String, String> extractPropertyAndMessage(ConstraintViolationException e) { return extractPropertyAndMessage(e.getConstraintViolations()); } /** * 辅助方法, 转换Set<ConstraintViolation>为Map<property, message>. */ @SuppressWarnings("rawtypes") public static Map<String, String> extractPropertyAndMessage(Set<? extends ConstraintViolation> constraintViolations) { Map<String, String> errorMessages = new HashMap<String, String>(); for (ConstraintViolation violation : constraintViolations) { errorMessages.put(violation.getPropertyPath().toString(), violation.getMessage()); } return errorMessages; } /** * 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>为List<propertyPath message>. */ public static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e) { return extractPropertyAndMessageAsList(e.getConstraintViolations(), " "); } /** * 辅助方法, 转换Set<ConstraintViolations>为List<propertyPath message>. */ @SuppressWarnings("rawtypes") public static List<String> extractPropertyAndMessageAsList(Set<? extends ConstraintViolation> constraintViolations) { return extractPropertyAndMessageAsList(constraintViolations, " "); } /** * 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>为List<propertyPath +separator+ message>. */ public static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e, String separator) { return extractPropertyAndMessageAsList(e.getConstraintViolations(), separator); } /** * 辅助方法, 转换Set<ConstraintViolation>为List<propertyPath +separator+ message>. */ @SuppressWarnings("rawtypes") public static List<String> extractPropertyAndMessageAsList(Set<? extends ConstraintViolation> constraintViolations, String separator) { List<String> errorMessages = new ArrayList<String>(); for (ConstraintViolation violation : constraintViolations) { errorMessages.add(violation.getPropertyPath() + separator + violation.getMessage()); } return errorMessages; }}
1 0
- SpringMVC 使用验证框架 Bean Validation(下)
- SpringMVC 使用验证框架 Bean Validation(上)
- springmvc 使用validation验证!
- 使用SpringMVC数据验证框架validation做数据校验
- SpringMVC验证框架Validation分组验证
- java后端验证 bean validation 框架
- SpringMVC验证框架Validation特殊用法
- SpringMVC验证框架Validation特殊用法
- SpringMVC验证框架Validation特殊用法
- SpringMVC验证框架Validation特殊用法
- SpringMVC验证框架Validation特殊用法
- SpringMVC验证框架Validation特殊用法
- SpringMVC BindingResult验证框架Validation特殊用法
- SpringMVC 集成 Bean Validation
- @Valid springMvc bean Validation
- SpringMVC使用hibrenate validation进行验证
- Bean Validation 注解-约束验证(一)
- springmvc使用校验框架validation校验
- BP神经网络介绍
- java中常用的字符串的截取方法1
- Mina的IoBuffer类getSlice方法略坑
- 命名空间+闭包+全局变量实例
- usaco布局(差分约束系统的应用)
- SpringMVC 使用验证框架 Bean Validation(下)
- MyEclipse注册码生成器
- maven多模块工程打包部署
- treap模板
- jxl怎样使用自定义颜色设置单元格颜色
- javascript笔记
- SDCC 的源码安装
- CocoaPods集成到Xcode项目中的步骤
- 理解一般指针和指向指针的指针