2009-06-25 59 views
6

我不确定是否根据数据库的状态使验证程序验证命令是一个很好的设计决策。例如,如果我需要验证一个用户bean,除了检查电子邮件和用户名是否为空等我还需要拒绝值,如果他们已经被使用。这种逻辑是否应该进入验证者或服务对象?Spring中的验证器应该访问数据库吗?

回答

10

那么你的验证器只是spring bean,所以它们可以注入处理数据访问的服务对象。您可以让验证器从数据库中获取数据,而不会影响设计。

2

不,恕我直言验证器应该很小,side-effect free为了让他们很容易组合。明确地说,验证者应该与持久层分开

+0

当你想检查一个引用是指一个真实的实体时,你会怎么做?他们不应该更改数据,但有时您至少需要进行身份验证。 – 2009-06-25 20:07:15

1

我检查了我的一个,我从验证调用服务层:

@Service 
public final class StartFormValidator { 
private FacilityService facilityService; 
private AdminService adminService; 

/** 
* Verify that they've selected a facility. Verify that they've selected a 
* valid facility. Verify that they've selected a view and that it's a valid 
* view. 
* 
* @param startForm 
* @param errors 
* @return true if no errors were set 
*/ 
public boolean isValid(final StartForm startForm, final Errors errors) { 
    if (startForm.getFacilityId() == 0) { 
     errors.rejectValue("facilityId", "facilityIdEmpty", 
       "Select a facility."); 
    } 

    if (!this.facilityService.isFacilWaitlistEnabled(startForm 
      .getFacilityId())) { 
     errors.rejectValue("facilityId", "facilityInvalid", 
       "Invalid facility"); 
    } 

    if (StringUtils.isBlank(startForm.getPassword())) { 
     errors.rejectValue("password", "passwordEmpty", 
       "Enter the password."); 

     return (false); 
    } 

    if (!this.adminService.validateAdmin(startForm.getPassword())) 
     errors.rejectValue("password", "passwordInvalid", 
       "Incorrect password"); 

    return (!errors.hasErrors()); 
} 

/** 
* @param _facilityService 
*/ 
@Autowired 
public void setFacilityService(final FacilityService _facilityService) { 
    this.facilityService = _facilityService; 
} 

/** 
* @param _adminService 
*/ 
@Autowired 
public void setAdminService(final AdminService _adminService) { 
    this.adminService = _adminService; 
} 

}

6

这将在很大程度上取决于你如何定义验证。考虑一下:你在买东西,然后你输入你的信用卡号码。如果校验位不匹配,则验证失败。没有尝试过任何交易。但是,如果它是一个有效的信用卡号码,但它与您的邮政编码不相符(需要DB /第三方交互),那么这是一个付款错误。

现在考虑一下:你输入你的地址,然后你输入Mastiffica作为你的国家。为什么系统甚至允许你输入 - 它们应该只将接口限制为有效输入(不需要输入数据库)。

或者您在银行付款屏幕的金额字段中输入“五十”。为什么它允许那里的字母 - 验证失败(不需要DB)。但是,您在金额字段中输入50,结果表明您的帐户中没有50英镑。这是一个验证错误?或者它是一个失败的交易?

现在,考虑到您已通过所有基本入境验证(信用卡校验码,国家,数字,邮政编码),并且交易失败,因为您的信用卡已过期。是验证错误还是失败的事务?

您可以将验证视为用户不会输入完全自然数据的基本保证,也可以将验证视为“我可以使用所提供的数据完成此交易”。我个人会喜欢前者,但同样,这是定义的问题。

再就是作为一种安全措施,第一线的验证的方面 - 已接受了过去的顶部UI层可以是安全风险(SQL注入,例如)

1

如果你真的相信“MVC野外数据“那么我不这么认为,你会希望你的验证器去数据库。验证是一个从业务逻辑的角度来验证数据的阶段。

数据库不需要知道验证器将如何使用它,验证器也不应该知道数据库是什么样的。这只是不适合MVC模型。明天,如果您有来自多个来源的数据,您是否仍会继续并告诉验证者,哪些来源具体应该在哪些条件下访问。这本身将构成甚至不需要的逻辑。在应用中。

您正在寻找的验证类型将被视为业务对象的一部分,这将确保在调用服务对象之前;这种组合并不存在。

服务对象也不应包含业务验证,因此它既不属于验证者也不属于服务对象。但是,是的,如果应用程序足够小以至于不用担心太多的图层,倾斜的方法就没有问题,但只要“贯穿始终遵循标准”即可。

总之,我觉得spring验证器是用于基本验证而不是真正的业务验证。

0

我赞成使用数据库的验证,因为最终用户的可用性。

在提交注册表单时,您要检查用户名是否在语法上正确,并且该用户名尚未提供(需要数据库访问权限)。

表单可以一次返回所有错误。它可以向用户显示所有问题。用户可以修复它并再次发送表单。

我知道你可以用ajax等做得更聪明,这不是重点。

我总是检查一切。我检查这个表单是否将由即将到来的交易处理。如果没有,我会因为一些可以轻松处理的并发访问而发生异常。