package org.springboot.sample.controller; import java.util.HashMap; import java.util.Map; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import javax.validation.Valid; import org.springboot.sample.entity.ValidatorTest; import org.springboot.sample.service.ValidatorTestService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; /** * Java验证框架测试 * * @author 单红宇(365384722) * @myblog http://blog.csdn.net/catoop/ * @create 2016年4月14日 */ @Controller @RequestMapping("/validator") public class ValidatorController { @Autowired private ValidatorTestService validatorTestService; @ModelAttribute("testModel") public ValidatorTest model(){ ValidatorTest vtest = new ValidatorTest(); vtest.setUsername("shanhy"); vtest.setPassword("123456"); return vtest; } /** * 使用required属性限定参数是否必须 * * @param name * @param age * @return * @author SHANHY * @create 2016年4月14日 */ @RequestMapping("/test1") @ResponseBody public Map<String, String> test1(@RequestParam(required = true) String name, @RequestParam(required = false) String age) { Map<String, String> map = new HashMap<>(); map.put("name", name); map.put("age", age); return map; } @RequestMapping("/test") public String test(){ return "validator1"; } /** * 响应到JSP页面 * * @param test * @param result 这里的BindResult result必须紧跟着前面的@ModelAttribute, 否则会出错 * @return * @author SHANHY * @create 2016年4月14日 */ @RequestMapping("/test2") public String test2(ValidatorTest test, BindingResult result, Model model){ model.addAttribute("test", test); return "validator2"; } /** * 响应到JSP页面 * * @param test * @param result * 这里的BindingResult必须紧挨着@Valid参数的,即必须紧挨着需要校验的参数, * 这就意味着我们有多少个@Valid参数就需要有多少个对应的Errors参数,它们是一一对应的。 * @return * @author SHANHY * @create 2016年4月14日 */ @RequestMapping("/test3") public String test3(@Valid @ModelAttribute("testModel") ValidatorTest test, BindingResult result, Model model){ model.addAttribute("test", test); if(result.hasErrors()) return "validator1"; return "validator2"; } @RequestMapping("/test6") @ResponseBody public Model test6(@Valid @ModelAttribute("testModel") ValidatorTest test, BindingResult result, Model model){ model.addAttribute("test", test); // 在实际开发中,我们需要判断是否存在错误,来决定是继续执行后续代码,还是跳转到别的页面 if(result.hasErrors()){ model.addAttribute("error", "验证不通过!"); } return model; } /** * 基础数据类型验证 * * @param name * @param model * @return * @author SHANHY * @create 2016年4月29日 */ @RequestMapping("/test4") @ResponseBody public Model test4(String name,Model model){ model.addAttribute("name", name); return model; } /** * 测试方法级别的验证(如果验证失败,则会抛出异常 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()); } } }