【问题标题】:Spring session based javax constraint validation基于 Spring 会话的 javax 约束验证
【发布时间】:2013-11-18 17:36:19
【问题描述】:

我想要完成的是在自定义约束中访问我的 Spring Session

示例场景:

自定义约束@UniqueEmail 验证电子邮件尚未在系统中使用。此验证在编辑端点上执行,如果用户没有更改电子邮件,则应忽略此验证,第一个:因为不需要它,第二个:因为查询该电子邮件的数据库实际上会返回一个结果,即用户本身,虽然没有访问会话就无法告诉它

这行得通:

如果我通过 @InitBinder 使用带有自定义编辑器的模型属性,我可以在验证发生之前在要验证的 bean 中设置一个属性,就像这样

@InitBinder(value="myModelObj")
protected void initBinder(WebDataBinder binder, HttpSession session) {
    User user = (User) session.getAttribute("user");
    binder.registerCustomEditor(User.class, "user", new UidPropertyEditor(user));
}

@RequestMapping(...)
public String updateUser(@Valid @ModelAttribute("myModelObj") MyModelObj form){
    ...
}

MyModelObj 有一个属性,它将被实际会话用户替换。问题:

  1. bean 中必须有一个属性来保存用户,即使它不能通过 Web 表单进行编辑
  2. Web 表单也必须提交此属性,在我的例子中使用 input[type="hidden"] 字段(用户可以随意更改它,我们从不相信用户发送的内容)

这不起作用

新端点必须使用@RequestBody 而不是@ModelAttribute,这意味着(afaik)@InitBinder 将不再工作,因此无法访问会话对象。

如何(如果可能)从自定义约束中访问会话?

public class EmailIsUniqueStringValidator implements ConstraintValidator<EmailIsUnique, String> {

@Autowired
private UserDAO userDAO;

HttpSession session; //Somehow initialized

@Override
public void boolean isValid(String email, ConstraintValidatorContext context) {
    User user = (User) session.getAttribute("user");
    if(user.getEmail().equals(email)){
        return true; // No need to validate
    }
    else if(userDAO.emailInUse(email)) {
        return false;
    }
}

非理想方法:

我现在正在做的是手动在控制器中执行与会话相关的验证,这意味着我有 2 个点可以执行验证。

this post 中还有一些其他有趣的选项,但如果有办法访问会话...

提前致谢

【问题讨论】:

    标签: spring validation spring-mvc bean-validation


    【解决方案1】:

    这可以使用RequestContextHolder 来实现,如下所示:

    public class EmailIsUniqueStringValidator implements ConstraintValidator<EmailIsUnique,         String> {
    
    @Autowired
    private UserDAO userDAO;
    
    HttpSession session;
    
    @Override
    public void boolean isValid(String email, ConstraintValidatorContext context) {
        ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        session = attr.getRequest().getSession();
    
        User user = (User) session.getAttribute("user");
        if(user.getEmail().equals(email)){
            return true; // No need to validate
        }
        else if(userDAO.emailInUse(email)) {
            return false;
        }
    }
    

    【讨论】:

    • 大+1 为您在找到解决方案后分享解决方案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-04
    相关资源
    最近更新 更多