【问题标题】:Validation in Spring MVCSpring MVC 中的验证
【发布时间】:2011-07-31 09:53:57
【问题描述】:

如何在验证器类中获取请求对象,因为我需要验证内容,即请求对象中存在的参数。

【问题讨论】:

    标签: java spring spring-mvc validation


    【解决方案1】:

    你有两个选择:

    • JSR 303(Bean 验证)验证器
    • Spring 验证器

    对于JSR 303,您需要Spring 3.0,并且必须使用JSR 303 Annotations 对您的Model 类进行注解,并在Web Controller Handler Method 中的参数前面写一个@Valid。 (如Willie Wheeler show in his answer)。另外,您必须在配置中启用此功能:

    <!-- JSR-303 support will be detected on classpath and enabled automatically -->
    <mvc:annotation-driven/>
    

    对于 Spring 验证器,您需要编写实现 org.springframework.validation.Validator 接口的验证器(参见 Jigar Joshi's answer)。您必须在控制器中注册您的验证器。在 Spring 3.0 中,您可以在 @InitBinder 带注释的方法中执行此操作,方法是使用 WebDataBinder.setValidatorsetValidator 它是超类 DataBinder 的方法)

    Example (from the spring docu)
    @Controller
    public class MyController {
    
        @InitBinder
        protected void initBinder(WebDataBinder binder) {
            binder.setValidator(new FooValidator());
        }
    
        @RequestMapping("/foo", method=RequestMethod.POST)
        public void processFoo(@Valid Foo foo) { ... }
    }
    

    有关详细信息,请查看 Spring 参考,章节 5.7.4 Spring MVC 3 Validation

    顺便说一句:在 Spring 2 中,SimpleFormController 中有类似 setValidator 的属性。

    【讨论】:

    • 设置 spring 验证器隐藏休眠验证功能 (JSR 303)。有什么方法可以保持休眠验证并额外使用自己的 spring 验证器?
    • @Saram:我强烈建议使用 JSR 303 而不是 spring 验证器。 -- 无论如何,如果您想问什么,请发布一个新问题。
    • 您可以使用binder.addValidator(new FooValidator()); 结合这两种验证方法。
    【解决方案2】:

    使用简单的验证器(您的自定义验证器) 您不需要请求对象即可在 Validator 中获取参数。你可以直接从那里得到它。

    例如:这将检查名称为 nameage 的请求中的字段

    public class PersonValidator implements Validator {
    
        /**
        * This Validator validates just Person instances
        */
        public boolean supports(Class clazz) {
            return Person.class.equals(clazz);
        }
    
        public void validate(Object obj, Errors e) {
            ValidationUtils.rejectIfEmpty(e, "name", "name.empty");
            Person p = (Person) obj;
            if (p.getAge() < 0) {
                e.rejectValue("age", "negativevalue");
            } else if (p.getAge() > 110) {
                e.rejectValue("age", "too.darn.old");
            }
        }
    }
    

    另见

    【讨论】:

      【解决方案3】:

      不是 100% 确定我正确地关注了您的问题,但是使用 Spring MVC,您将对象传递给方法并对其进行注释(至少使用 Spring 3),如下所示:

      @RequestMethod(value = "/accounts/new", method = RequestMethod.POST)
      public String postAccount(@ModelAttribute @Valid Account account, BindingResult result) {
          if (result.hasErrors()) {
              return "accounts/accountForm";
          }
      
          accountDao.save(account);
      }
      

      这里的相关注解是@Valid,它是JSR-303的一部分。还包括 BindingResult 参数,以便您可以检查错误,如上所示。

      【讨论】:

        【解决方案4】:

        您可以使用 HttpServletRequest 参数轻松添加另一个方法。

         public void validateReq(Object target, Errors errors,HttpServletRequest request) {
        
               // do your validation here
        }
        

        请注意,您没有在此处覆盖方法

        【讨论】:

          【解决方案5】:

          当我使用 spring 验证器验证验证码时,我也遇到了同样的问题。 在验证器实现中,我想从 HttpSession 中获取正确的验证码(从 HttpServletRequest 获取 HttpSession)。

          在验证器中没有找到任何好的代码,太糟糕了!!!

          折衷方案如下:

          1. 在绑定表单 DTO 中添加一个额外的字段(调用:correctCaptcha),在 Controller 方法中从 HttpSession 设置字段值,然后您可以在验证器中进行验证

            public class UserRegisterDto {
                private String correctCaptcha;
                //getter,setter
            }
            
          2. 在绑定表单 DTO 中添加 HttpServletRequest 引用,然后可以在验证器中使用。

            public class UserRegisterDto {
                private HttpServletRequest request;
                //getter ,setter
            }
            
            @RequestMapping(value = "register.hb", method = RequestMethod.POST)
            public String submitRegister(@ModelAttribute("formDto") @Valid UserRegisterDto formDto, HttpServletRequest request,BindingResult result) {
                formDto.setRequest(request);
                if (result.hasErrors()) {
                    return "user_register";
                }
            }
            

          【讨论】:

          • 对不起,它不起作用,也许使用 Spring MVC 拦截器是一个很好的解决方案
          猜你喜欢
          • 2013-03-05
          • 1970-01-01
          • 2011-06-07
          • 2012-10-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-08
          相关资源
          最近更新 更多