【问题标题】:Problems with Spring Forms and ValidationSpring 表单和验证的问题
【发布时间】:2014-03-28 19:53:31
【问题描述】:

我是 Spring 新手,之前我曾使用 PHP 和 Python。我在理解 Spring 表单的工作方式和验证方式时遇到了一些问题。到目前为止,我的理解是,当您使用表单时,您的表单由 bean 支持,这意味着您必须向 JSP 提供一个 bean。您也可以使用标准 HTML 表单,但您必须在控制器中手动检索请求参数。

这是我遇到的问题。我有一个使用 Hibernate Validator 的用户 bean,并且我为用户添加、编辑页面。问题是我不希望密码字段出现在编辑页面上,密码无论如何都会是垃圾,因为它使用 BCrypt。但是,当提交表单时,验证失败,因为它希望密码存在。似乎无论如何都没有使用 Spring Form 进行部分 bean 实现。

如果可能的话,我想使用 Spring Form,因为它减少了重复的验证代码,而且它总是很好地处理对象。我现在的想法是创建一个中间对象,然后将数据从该对象转换到我的 bean。看起来很乏味,并且可能导致创建许多对象的方式。我的另一个想法是只使用普通的旧 HTML 表单并自己拉参数并在对象中设置值。

我不确定什么是最好的方法,或者我什至不知道我是否在正确的轨道上思考。 Spring Forms 和验证提供似乎很棒,但似乎不是特别灵活。就像我说的我是 Spring 新手,所以我可能只是遗漏了一些东西或不理解。

我一直在努力解决的另一个问题是表单上需要多个对象。假设我有一个用户 bean,它具有以下属性。

私人角色角色; 私人国家;

所以我需要将 User、List 和 List 传递给我的 JSP。我可以让它们正常显示,但是如果表单验证在返回该页面时失败,我将失去我的角色和国家对象,除非我在返回视图名称之前将它们重新添加到模型中。我在这里遗漏了什么还是那是常态。这是一个请求对象,所以我想这是有道理的,但每次都必须重新添加它们似乎很乏味。

【问题讨论】:

    标签: spring validation spring-mvc spring-form


    【解决方案1】:

    到目前为止,我的理解是,当您使用表单时 由 bean 支持,这意味着您必须向 JSP 提供 bean。

    我会说大部分是真的。表单由 bean 支持,但 Spring JSTL 标记知道如何根据设置的 modelAttribute 获取 bean。该 bean 存在于您认为的“页面”范围内,除非您添加将模型属性设置为处于会话中。无论哪种方式,如果您使用 Spring JSTL 标签,它们都会去一个或另一个地方获取它。

    您也可以使用标准 HTML 表单,但您必须手动 检索控制器中的请求参数。

    不正确。您可以“模拟”Spring JSTL 标记正在执行的相同操作。了解 JSTL 标记非常类似于宏。他们只是将一些预先确定的代码块复制到带有一些非常基本的条件语句的输出中。 Spring MVC 需要在 Controller 端连接 Model Attribute 的关键位是 namevalue,它们很容易理解它们是如何生成/连接在一起的。

    但是,当表单提交时,验证失败,因为它期望 要显示的密码。

    您可以创建“DTO”或“数据传输对象”,它基本上是从 UI 获取值并在 Controller/Service 层转换为后端的真实模型对象的中间人。或者,如果您像我一样懒惰,请将 User 放在会话范围内,在这种情况下,您不必发布该值,因为 Spring 会将其从会话中取出并更新您发布的一两个字段。不要贴密码,Spring不会设置密码。

    我现在的想法是创建一个中间对象然后 将其中的数据翻译成我的 bean。

    是的,这就是我提到的 DTO。你只需要在你需要的地方做。

    我不确定什么是最好的方法,或者我什至在考虑 正确的轨道。

    在编码中可能有成千上万种方法可以做任何事情,有些方法比其他方法更正确或错误。我认识一些设计纳粹的开发人员,他们会说你应该总是以这样或那样的方式去做,但我不是那些人中的一员。我认为,只要您始终如一,并且您没有做一些完全愚蠢的事情,那么您就走在了正确的轨道上。我对我编写的所有代码的第一个关注是可维护性。我

    1. 不想花 20 小时试图重新学习我 6 个月前所做的事情,所以我倾向于选择更简单的选项
    2. 讨厌重复代码,所以我倾向于选择更多的模块设计
    3. 讨厌不得不花 20 小时来重新学习我 6 个月前所做的事情,因此倾向于大量使用 JavaDoc 和 cmets,因为我发现代码很棘手(很多循环、做一些奇怪的事情等)

    我一直在努力解决的另一个问题是拥有多个对象 需要在表单上。

    也有几种方法可以解决这个问题。我从未使用过它,但实际上你可以有多个模型属性与同一个表单和控制器处理程序相关联。我认为您使用<spring:bind> 标签或其他东西。我已经看过周围的示例,所以如果您认为需要,请在 Google 上搜索。

    我的方法通常是将某些东西放在会话中,或者构建一个 DTO 来保存我需要的所有东西。第一个我更多地用于列表之类的东西来驱动构建视图,例如,如果我有一个来自表格的状态下拉列表。我会在会话中列出一个州列表,然后从那里使用它们,这样我只追踪它们一次就完成了。

    当我需要一次性更改一大堆复杂的东西,但这些东西不一定直接连接时,我会使用 DTO 方法(有些人可能称之为 Form Bean)。只是要指出:您可以在模型属性中包含嵌套对象,并在 Spring JSTL 标记中使用它们。你也可以在你的模型属性中包含集合(列表、集合、映射)并获取这些集合,尽管 Spring 不能很好地处理嵌套集合。

    希望对您有所帮助。

    【讨论】:

    • 哇,很好的答案,感谢您的解释。这有助于为我指明正确的方向。我将研究 DTO 概念。再次感谢您花时间整理出一个解释清楚的答案!
    猜你喜欢
    • 2011-06-21
    • 1970-01-01
    • 1970-01-01
    • 2015-04-23
    • 2021-05-18
    • 2013-01-01
    • 2015-07-18
    • 2021-03-24
    • 2014-08-16
    相关资源
    最近更新 更多