【问题标题】:What is the proper way to handle user manipulated form data?处理用户操作的表单数据的正确方法是什么?
【发布时间】:2015-01-06 23:22:42
【问题描述】:

快速概览:

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

假设用户更改了 html 中的船 id(更改为不存在的船或另一用户的船),这两种可能性中哪一种更“合适”?

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

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

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

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

【问题讨论】:

  • 不要将您的数据库 ID 暴露给最终用户。在Controller中,创建一个列表,在表单上,​​迭代列表并使用列表中的迭代次数(索引)。
  • 例如,如果用户有 3 艘船的 id: 5,8,11 我应该创建一个列表并将其索引添加到 html 表单中,因此 1 代表 5、2 -> 8 和 3 -> 11. 我理解正确吗?
  • 是的。然后,您只需根据列表验证表单返回的索引。
  • 这是一个非常好的建议。谢谢你。
  • 这个方法我有点问题。假设我在 GET 控制器中使用船舶填充列表,将列表添加到模型中,一切都很好。但是,如何在 POST 控制器中检索此列表?经过一番谷歌搜索后,我发现@SessionAttributes 可以用来实现这一点。问题是:有没有更好的方法?另外,我猜会话属性保存在服务器上,因此用户无权访问它们,因此将 ID 放在那里是安全的。如果我错了,请纠正我。

标签: java spring hibernate model-view-controller


【解决方案1】:

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

在控制器中保持尽可能少的逻辑。如果您切换到不同类型的用户界面(例如 REST API),这会使您的模型更加有用。

顺便公开你的数据库密钥是可以的,只要你使用像 Spring Security ACL 这样的东西来不向错误的用户公开数据。

【讨论】:

  • 我没有使用 ACL,但是在快速谷歌搜索之后,一旦我有空闲时间,我肯定会了解更多有关它的信息。谢谢你提到它。同时,如果我在服务器端执行验证,是否仍然可以公开 id?例如:用户更改 Pilot id,服务器检查给定 id 的船是否属于用户,如果是则继续,如果不则抛出异常。
【解决方案2】:
  1. GET 控制器从数据库中构建一个List,并将其存储在会话中,并传递给视图。
  2. View 迭代并显示列表。 HTML 表单通过列表索引引用每个项目(从 0 开始)
  3. POST 控制器根据会话列表验证返回的表单数据。如果无效,表格将重新显示相同的列表。如果有效,所选项目的数据库 ID 将是列表中的数据之一,列表从会话中删除,流程继续...

【讨论】:

  • 是的,这正是我的想法。问题是,如果用户触发 GET 控制器但未提交表单,则列表将保留在会话中。如果将其乘以存储会话属性的控制器数量,是否会出现内存问题?
  • 这是您必须自己进行的计算。默认会话超时通常为 30 分钟。有多少用户?每个项目在内存中有多大?它们是从数据库中延迟加载的吗? Hibernate 是否使用缓存?如果这是一个真正的问题,也许考虑实现该项目的“精简”版本,或者使用来自java.lang.ref 的东西或实现一个番石榴Supplier
  • 感谢您的意见。我希望我能接受多个答案,因为两者都很好,具体取决于具体情况。我喜欢这种方法,但我被告知要尽可能避免使用会话属性,所以我只是要确保用户只能查看他们自己的内容。我能做的至少是投票。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-25
  • 1970-01-01
  • 2015-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多