【问题标题】:How to avoid duplicate validation in web tier and service tier?如何避免 Web 层和服务层的重复验证?
【发布时间】:2011-06-16 01:01:25
【问题描述】:

如果我有一个 Web 应用程序,假设我正在使用 Spring MVC,并在我的表单和控制器中添加验证。如果客户端以其他方式(通过 REST 服务等)访问我的应用程序,我可能还会在我的服务层中进行验证。在这种情况下,我可能在多个地方都有验证逻辑/代码。

是否有建议的方法来保持验证部分干燥?

【问题讨论】:

    标签: java validation spring-mvc


    【解决方案1】:

    我建议这些是不同类型的验证。

    客户端/控制器验证检查以确保存在所需的值、遵守格式等。

    将 HTTP 请求参数绑定到要传递给服务层的对象中是控制器的专属职责。

    服务层将执行与客户端相同的验证,但也会加入与用例相关的“业务验证”。控制器无法知道这些。

    避免重复的一种方法是在客户端和服务器端执行相同的 JavaScript 函数。服务器端使用 JavaScript 引擎执行客户端验证以及与业务验证相关的其他验证。

    【讨论】:

      【解决方案2】:

      首先,业务/功能级别验证应始终在服务层中进行。如果您说您正在重复在 MVC 层上完成的验证,那么在服务层上会重复,这听起来令人震惊。例如,在视图中,您可以验证电话号码格式、信用卡格式等内容。您不得在您的服务层中重复这些内容。

      同时,您可能必须重复验证,例如“空”检查,从设计的角度来看,这些都是可以的。

      【讨论】:

        【解决方案3】:

        很多人会告诉你如何做到这一点。我将回答为什么你可能不想。

        在 N 层系统中,所有层都是半自治的。但这并不意味着他们可以——或者应该——依赖另一层来保证数据的一致性和有效性。

        有两个主要原因。首先,N 层系统是可扩展的。例如,在一个 web 系统中,一个新的前端可能会利用现有的 web 层来做一些在原始设计中从未想过的事情。因此,您通过允许在层的某个中间点出现新的东西来对您的系统进行设计校对。

        其次,验证通常越靠近用户越有效。如果我在基于浏览器的解决方案中,并且在双输入验证字段中输入了错误的密码,我希望浏览器立即指出这一点。等待往返需要时间并且让用户感到沮丧。

        现在举同样的例子,把它移到逻辑层。逻辑层不完全确定是谁在向它发送数据,希望确定它正在接收两个匹配的密码。所以它也会检查,如果它们不匹配则返回错误。这可以保护数据免受不良更改。

        这只是一种哲学,但过去对我来说效果很好。

        【讨论】:

        • 您说得对,验证更接近用户更有效,但通常可以在服务层中使用的域模型中描述您的验证约束。例如。服务层返回一个错误对象,Web 层负责翻译它,另一个服务层用户将按照他们需要的方式处理它。
        • 这似乎是最有意义的。我在问问题 b/c 我正在参加“使用 Spring 开发丰富的 Web 应用程序”培训,在 Spring MVC 讨论期间,他们展示了如何进行验证。有人问了一个关于验证逻辑的潜在重复的问题,因为它在控制器/表单区域和服务区域中存在一些。
        • 尽管理想情况下代码应该在两个层中运行,但这对于实际复制代码(比如使用两种不同的语言)并不是一个好案例,尤其是在理论上存在问题时(“设计校对”) ,因为当验证逻辑发生变化时(并且在有用的系统中总是如此),它必须在两个(或更多!)不同的地方正确修复。有时你别无选择,但肯定不是“面向未来”的练习。
        • @Daff 通过允许域模型或值对象执行验证,您如何将验证错误映射回通过控制器传入的特定错误字段?
        • 我同意,可以在多个位置进行验证。然而,我试图提出的观点是,在直接接触点之外进行的验证本质上是可疑的。任何中间层都有可能伪造/存储/伪造验证信息。因此,唯一的 TRUE 验证是从每一层到下一个直接连接的层。
        【解决方案4】:

        Spring 使用validator 接口这是一种方式。我不知道为什么您也不能在服务层中使用它。或者,您可以使用 AOP 并根据需要在任何层中定义切入点。

        【讨论】:

          【解决方案5】:

          可能值得一看 JSR-303 bean 验证。如果您对不同的接口使用相同的 JavaBean,则可以避免重复的验证逻辑。

          Hibernate 实现提供了最好的参考文档:

          http://hibernate.org/subprojects/validator

          Spring 参考文档告诉您如何集成它。

          http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/validation.html#validation-beanvalidation-overview

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-03-09
            • 2014-02-13
            • 2012-01-19
            • 2020-11-17
            • 1970-01-01
            • 2018-08-20
            • 1970-01-01
            相关资源
            最近更新 更多