我应该在MVC层和服务层中复制验证吗?

JMM*_*JMM 7 java validation spring stripes

我现在感觉有些矛盾.我有一个使用Stripes用于MVC框架的Web应用程序和用于后端的Spring/Hibernate.我的MVC层中有一个帐户注册方法,需要以下验证:

  • 用户名尚未使用
  • 提供的电子邮件地址尚未与其他帐户相关联

我在Stripes(MVC层)中有一个验证方法来检查这两个案例,但是想知道我的服务层是否应该复制这些检查?如果服务层接口作为Web服务公开,那么我认为验证是个好主意,但如果它只在Web应用程序的上下文中使用它是否需要?

编辑:我不打算复制验证代码 - 我的意思是在两个地方复制验证方法调用.

我认为我的选择是:

  1. 在MVC和服务层中复制验证调用
  2. 仅在MVC层中执行此验证
  3. 仅在服务层中执行此验证.

这里最好的做法是什么?我正在寻找关于我应该选择哪个选项以及原因的建议/意见.

请注意,对注册表单的输入字段进行简单的验证检查(如检查空白),我认为这些应仅由MVC验证处理; 我只关心更复杂的验证.

mat*_*t b 5

不要重复代码.使用JSR303 Bean验证,以便您可以在应用程序的所有层中使用相同的验证逻辑.

Hibernate Validator(来自Hibernate ORM的独立项目)提供了此接口的参考实现.使用起来很简单,你可以很快开始使用它.


Pau*_*Pau 5

在我看来,你应该区分两种验证:

  • 格式数据验证:应在表示层(在您的情况下为 MVC)中进行验证。通常在客户端和服务器端
  • 业务数据验证:应在服务层进行验证

在您的情况下,您的验证与业务规则相关,因此我将仅将它们放在服务层中。此外,如果您在两个层中重复验证,您将进行两次相同的查询,从而降低应用程序的性能。


Han*_*eek 3

安妮,

好问题,我曾多次问过自己同样的问题。这就是我最终得到的结果(到目前为止)。

最纯粹(但乏味)的方法是调用两层中的验证逻辑。务实的方法可能是仅在网络领域(例如您的控制器)中调用它。

我认为没有一个答案可以结束所有的讨论。我认为这取决于您的项目的背景。如果项目规模不大(就人员和代码库大小而言),并且您确信其他人不会开发大量调用您的服务 API 的代码(在某种程度上您将无法监督),那么仅在 Web 层进行验证就足够了。

但是,如果您预计有很多客户,您可能需要更高级别的安全性。当我在这里说安全性时,我将其称为您需要的一致性保证级别。如果该级别很高,则没有办法解决它:您将必须在服务(出于安全性)和 Web 层(主要是为了能够为最终用户提供可接受的体验)中执行此操作。

因此,这里的关键驱动因素是安全性以及您真正需要多少安全性。如果您需要很多,您就会选择“纯粹”方法。如果您的应用程序并未做出涉及生死问题的决策,那么您将采用务实的方法。