Spring MVC 中的验证

Posted

技术标签:

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

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

【问题讨论】:

【参考方案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.setValidator(setValidator 它是超类 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");
        
    

另见

Document

【讨论】:

【参考方案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)。

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

折衷方案如下:

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

    public class UserRegisterDto 
        private String correctCaptcha;
        //getter,setter
    
    

    在绑定表单 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 拦截器是一个很好的解决方案

以上是关于Spring MVC 中的验证的主要内容,如果未能解决你的问题,请参考以下文章

控制器或服务层中的 Spring MVC 验证?

Spring MVC 3.1 中的基本身份验证

来自 spring mvc 的 LDAP 身份验证

Spring 3 MVC:使用自定义验证器显示验证消息

Spring MVC REST + Spring Security + 基本身份验证

Spring MVC -- 验证器