处理用户操纵的表单数据的正确方法是什么?

What is the proper way to handle user manipulated form data?

快速概览:

我有一个飞行员和船舶实体。一名飞行员可以拥有几艘飞船,但一次只能激活一艘。
现在,假设一名飞行员想要激活另一艘飞船。在这种情况下,提交了一个包含船舶 ID 的表单,我必须显示一条包含结果的消息(激活或未激活)。

假设用户更改了 html 中的飞船 ID(更改为不存在的飞船或其他用户的飞船),这两种可能性中哪种更 "appropriate"?

选项 1:
在负责激活飞船的服务层函数中执行检查,如果出现问题则抛出异常。然后由控制器处理异常,并将适当的消息添加到模型中。

选项 2:
在控制器内部执行验证并调用服务层函数,仅当数据正确时才激活飞船。

我认为第二种选择一开始似乎更好,但缺点是我必须进行两次精确的数据库查询才能找到这艘船。一个在控制器中用于验证目的,然后另一个在服务层中实际激活它。服务方法是@Transactional,所以如果我将找到的控制器作为参数传递,Hibernate 无论如何都会从数据库中检索它,所以现在我选择了选项 1 以避免重复数据库调用,因为这看起来很糟糕。

我仍在学习,所以我很想听听更有经验的用户在这种情况下必须说些什么。如果有更好的方法,我也愿意接受建议。提前致谢。

您的业务逻辑应该在实体或服务中 class,或者使用类似 Hibernate Validator 的东西。 Spring 不是很 DDD,所以服务是正常路线。

在控制器中保留尽可能少的逻辑。如果您切换到不同类型的用户界面,例如 REST API.

,这会使您的模型更有用

顺便说一下,公开您的数据库密钥是可以的,只要您使用 Spring 安全 ACL 之类的东西来避免将数据公开给错误的用户。

  1. GET 控制器从数据库构建一个 List,它存储在会话中,并传递给视图。
  2. View 迭代并显示列表。 HTML 表单通过其列表索引(从 0 开始)引用每个项目
  3. POST 控制器根据会话列表验证返回的表单数据。如果无效,将使用相同的列表重新显示表单。如果有效,所选项目的数据库 ID 将成为列表中的数据之一,列表从会话中删除,流程继续...