在我们的应用程序中,我们有各种层。服务层,DAO层和操作(struts应用程序)。
数据从一层传递到另一层。
理想情况下我们应该在哪里进行输入验证?
说,用户ID,电话号码来自UI,它们是强制性的。所以我们已经在客户端进行验证。
现在,根据我的观点,这就是你所需要的。没有别的地方应该验证。
但我的一位同事认为,如果客户直接提出请求会怎样。所以我们还需要添加Actions。
现在,在Dao,同样的方法也被用于其他一些动作,而且没有验证,
或者,说服务层,它可能会被曝光,比如说作为Web服务,所以你也可以进行验证。
基本上,他建议......我们到处都有验证。这对我来说没有意义。它跨层重复。
这是什么理想的方法?假设验证可能是简单的空检查或一些复杂的验证。
答案 0 :(得分:12)
同意Pangea,您肯定应该在客户端和服务端点进行验证。
我想补充一点,验证的概念是“快速失败”。您可以向每个层添加验证,以便用户或调用者可以立即获得有关调用失败的原因的反馈,而不是可能启动事务,进行复杂查询并执行写操作以查找字段太短。
在客户端,您需要尽可能多的验证,这样您就不会浪费用户的时间,带宽和服务器端资源(在许多情况下会产生争用)。但是,您通常无法在客户端进行所有验证(例如,检查是否已经在注册时使用了这样的用户名),因此您希望选中此选项并在发布时立即返回正确的错误消息点击服务层。
在服务器层,您要假设所有输入都有潜在危险和不正确(并且通常会是这样)。我认为最好是更全面和积极地验证服务层上的输入,因为这是你的最后一道防线。如果你在客户端省略一两个验证,你只需要一个好的故障处理机制让用户知道什么是错的。如果您错过了服务端的某些内容并发生灾难,则可能意味着需要数小时或数天的调试并尝试恢复数据库备份。
还有一些检查在数据库级别完成,这些检查强制执行参照完整性等操作。我通常会在尝试写入之前尝试尽可能多地检查它们,因为解释各种RDBMS的错误消息并尝试将它们转换回用户可理解的术语通常很难,如果不是不可能的话。
答案 1 :(得分:5)
如果您的应用程序提供了多个入口点(UI或系统到系统接口或批处理系统),那么您应该清理(空检查,格式检查,必需等)所有这些数据边缘和到达服务层之前。 但这并不意味着您需要复制验证逻辑。您可以使用允许集中验证的框架。可以在此post中找到一些示例验证框架。
但是,业务验证应属于您的域层,并且应保留在域服务层或域对象中。
我不同意您应该在DAO中执行验证。 DAO应该负责CRUD操作。如果他们做得更多,那么你就会有漏洞。如果你必须批量处理东西,那么你应该确保批处理来自服务层,这样你的批处理也会进行相同的验证。
答案 2 :(得分:1)
我可以添加到对话中的一个智慧是,永远不要相信客户。无论您的客户端是HTML,Flash / Flex还是其他任何东西,都有可能会有人破解它并尝试做一些您不希望他们做的事情。这里的后续工作是,如果有人可能会破解它,我们作为软件工程师必须假设它会被黑客入侵,所以虽然前端的检查很好,并且可以帮助您的应用程序可用性,你必须验证后端的所有输入,即使这会导致重复检查。