【问题标题】:Prepopulate AND redisplay an HTML Form预填充并重新显示 HTML 表单
【发布时间】:2011-10-24 18:04:00
【问题描述】:

创建表单的最佳非框架(仅限 JSP/Servlet)方法是什么:

  1. 使用从数据库加载的默认值/数据预填充
  2. 重新显示未通过验证的提交值

做一个或另一个似乎相当简单,但创建一个同时支持两者的表单是很棘手的。

例如使用

${param.scheduledDate}

非常适合在验证失败时重新显示日期,但无法在页面加载时以编程方式轻松设置。反之,

${myBean.scheduledDate} 

非常适合显示从数据库加载的值,但无法在验证失败时重新显示数据,因为 bean 使用的是 Date 类型的对象,而不是字符串。

想到了一些事情,但似乎并不是那么好:

  • 使用仅包含字符串的中间 bean
  • 使用 servlet 过滤器在页面加载时设置参数

【问题讨论】:

    标签: jsp servlets


    【解决方案1】:

    在视图侧执行此操作。在 EL 中使用条件运算符?:

    <input name="foo" value="${fn:escapeXml(empty bean.foo ? param.foo : bean.foo)}" />
    

    请注意,我假设与 GET 不同,POST 请求不会在验证成功之前预先填充 ${bean}

    顺便说一句,这种冗长是 MVC 框架存在的原因之一。例如JSF 通过EditableValueHolder 接口完全透明地处理这个问题,该接口由UIInput 组件等实现。

    【讨论】:

    • 这可能行得通,但它似乎有一些限制,例如您只能使用请求范围的 bean,并且 bean 属性不能为空/空。
    • @Ryan:为什么要使用会话范围 bean 来请求范围数据?只有在同一会话中的多个浏览器窗口/选项卡上显示相同的表单时,才会导致不直观的网站行为(和不良用户体验)。你不想拥有那个。仅将会话范围用于真实会话范围的数据,例如登录用户、其首选项、区域设置等。顺便说一下,JSF 具有完全符合您目的的“视图范围”(具有浏览器窗口/选项卡特定范围) .另见this
    • @BalusC - 我实际上并没有使用会话范围 - 只是想找到一个通用的解决方案。我认为在控制器中设置一个布尔值来指示视图是否是重新显示而不是检查 bean 值是否为空可能会解决我对范围和属性值都允许 null 的担忧。顺便说一句,我在上一个项目中实际上使用了带有 PrimeFaces 的 JSF。我目前的项目非常小,我只是想更好地了解 Java JSP/Servlet 编程。无需尝试在 JSF 上推销我。不过,我现在开始更加欣赏 JSF 了 :)
    • 不需要布尔值。只需在 doGet() 中执行 GET 操作(显示初始表单)并在 doPost() 中执行 POST 操作(提交表单)并将每个请求视为完全独立的请求。最好通过请求参数传递任何其他状态(顺便说一下,这是 JSF 对 javax.faces.ViewState 所做的;是的,我知道您使用 JSF,但我的回答更多地针对 Stack Overflow 社区,而不仅仅是您:)想要更好地理解 JSP/Servlet,肯定会导致更好地理解 MVC 框架存在的原因以及它们是如何工作的)。
    • 是的,例如 ID 应该放在隐藏字段中。在验证成功时,您还会如何准备相同的实体?不是通过将其存储在会话中,对吧?
    【解决方案2】:

    将 HTTP 请求转发回发布表单的同一页面违反了Post-Redirect-Get 最佳实践,应该避免。可以保存用户在会话中提交的内容或使用 URL 参数来保存用户提交的值并重定向回原始页面,但这并不优雅。表单提交的最佳解决方案之一是使用 AJAX 提交表单。

    【讨论】:

    • 这与PRG无关。 PRG 只是为了确保您在将当前浏览器的地址栏 URL 复制粘贴/共享/链接到新的浏览器会话/窗口/选项卡时获得所需的结果。验证失败后的转发根本不会导致这个问题。供阅读:stackoverflow.com/a/15523045(正确,JSF 目标,但适用于任何其他 web 应用)。
    • PRG 是关于可书签性的,也是为了维护浏览器后退按钮的功能并避免重复提交表单。如果您在发布未在响应中包含重定向的表单后刷新页面,您的浏览器将重新提交表单。即使忽略 PRG / 页面导航问题,“使用 AJAX”的解决方案也具有其他优势,例如提交表单时的性能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-20
    • 2012-06-06
    • 2011-04-11
    相关资源
    最近更新 更多