我应该在哪里放置需要访问数据库的验证码?

时间:2013-09-12 14:47:41

标签: java validation spring-mvc controller

我有一个Spring MVC网页,用于密码重置。这要求我们执行以下验证工作流程:

  1. 提供用户名或电子邮件
  2. 如果提供电子邮件,请确保其格式有效(例如:@Email)
  3. 通过以下方式检查用户是否存在:

    3a)尝试通过用户名
    从数据库加载用户 3b)如果按用户名加载返回null,请尝试通过电子邮件从数据库加载用户

  4. 加载后,检查用户是否未被锁定:user.isLocked()

  5. 目前,我在org.springframework.validation.Validator

    中拥有所有这些验证

    但是,这要求我的Validator可以访问UserService对象,以便加载用户。这会导致用户被我的验证器加载2次,第二次加载Controller,因此可以调用.resetPassword(User)


    问题:我应该在哪里查看第3项?

    这些验证更适合Controller吗?如果我按原样保留验证,我可以从Validator返回用户(由于Validator接口,它有void方法吗?)

3 个答案:

答案 0 :(得分:3)

在我看来,步骤3和4根本不属于视图层(特别是控制器执行的验证)。

这些步骤是此方案的业务逻辑的基本部分,因此它们应该在服务层中实现。

您的服务层应提供诸如

之类的方法
public void resetPasswordByUsernameOrEmail(String usernameOrEmail) { ... }

这些步骤应该在此方法中与resetPassword(User)一起发生。

如果需要,可以通过抛出异常使控制器知道此方法的结果,返回booleanenum(如果您想区分不同的错误条件)。

答案 1 :(得分:2)

按顺序回答您的问题:

  1. 您应该在 UserDao 中检查用户是否存在。
  2. ,这些验证不应在Controller中。控制器不应该对验证有任何了解,否则它会尝试太多,我们会犯低内聚
  3. 由于您使用的接口定义了具有void返回的方法,因此如果您想要返回User,则必须执行以下操作之一:
    • 在验证器实现中创建自己的方法。这样做的缺点是您不能有效地使用多态,因为您将依赖于未在接口中定义的方法。
    • 制作自己的Validator (可能会创建自己的接口,扩展Spring的Validator接口并定义您想要的方法)。这可能是我选择的。

答案 2 :(得分:1)

也许这是重复:Spring MVC Bean Validation

另一种解决方案是:

在我工作的一个项目中,我们曾经有一个SpringBeanUtil类。它将获得WebApplicationContext,并通过静态方法获取所需的bean。 这有点难看,但在这些问题上有所帮助。

自担风险。

public class SpringBeanUtil implements ApplicationContextAware{

private static ApplicationContext APPLICATION_CONTEXT;

@Override
public void setApplicationContext(ApplicationContext applicationContext)
        throws BeansException {
    APPLICATION_CONTEXT=applicationContext;
}

public static Object getBean(String name){
    return APPLICATION_CONTEXT.getBean(name);
}
public static <T> T getBean(Class<T> type){
    return APPLICATION_CONTEXT.getBean(type);
}
}