为啥选择浏览器刷新按钮不会将我的 JSF 表单中的已编辑字段替换为来自服务器的值? [复制]

Posted

技术标签:

【中文标题】为啥选择浏览器刷新按钮不会将我的 JSF 表单中的已编辑字段替换为来自服务器的值? [复制]【英文标题】:Why does selecting the browser Refresh button not replace edited fields in my JSF form with values from server? [duplicate]为什么选择浏览器刷新按钮不会将我的 JSF 表单中的已编辑字段替换为来自服务器的值? [复制] 【发布时间】:2019-03-25 02:19:06 【问题描述】:

在正常操作期间,我在 GlassFish 4.1.2 上运行并将 STATE_SAVING_METHOD 设置为服务器的 Java EE 笔记应用程序运行良好。我可以在我的 Firefox 浏览器中打开 ViewScoped Note.xhtml 客户端;在 CKEditor 字段中输入文本;选择 [创建] 按钮将便笺保存到 Derby 数据库;编辑文本,最后选择[更新]按钮更新数据库中的笔记信息。

我遇到的唯一问题是当我编辑我的笔记并且在视图过期之前没有选择创建或更新时。发生这种情况时,服务器会报告 ViewExpiredException,我会看到默认的 PrimeFaces 错误页面。

幸运的是,我发现我可以执行以下步骤来保存编辑过的数据。

    选择浏览器后退按钮。 选择浏览器刷新按钮。 选择客户端上的创建或更新按钮。

当我选择浏览器后退按钮时,我看到了之前编辑的页面。我相信这是因为浏览器在本地缓存了页面并显示了上一页的缓存版本。当我选择后退按钮时,浏览器似乎没有与服务器通信。

如果我在选择后退按钮后立即选择创建或更新按钮,我会再次看到 ViewExpiredException。

但是,如果我选择返回按钮,然后选择刷新按钮,我可以保存或更新我编辑的笔记。

我相信选择刷新按钮会为页面创建一个新视图,但我不明白为什么我不会丢失我的编辑。当我选择刷新按钮时,服务器报告它创建了一个新的支持 bean 并转到服务器以获取数据以进行注释。我本来希望服务器将此信息发送回客户端并覆盖编辑的值,但事实并非如此。刷新后,会创建一个新视图(我认为?),但客户端仍然具有编辑后的值。当我选择更新按钮时,编辑的值将保存在数据库中。

我很高兴它以这种方式工作,因为如果不这样做,每次视图过期时我都会丢失我的编辑。

我的问题是为什么它会这样工作。关于允许浏览器使用包含已编辑数据的表单创建新视图的 JSF 生命周期,我缺少什么?

我在发布这个问题之前阅读了javax.faces.application.ViewExpiredException: View could not be restored。此问题建立在该问题的基础上,通过专门查看在视图过期时刷新页面时表单中编辑的数据发生了什么,原始问题中没有解决。

【问题讨论】:

我读了那个问题,也读了你的书 The Definitive Guide to JSF 的第 2 章,但是,这两个来源都没有回答我的问题。我想知道为什么用编辑过的数据刷新页面不会丢失编辑过的数据。权威指南指出,在第 1 阶段,组件“.. 将根据视图中定义的组件标签进行实例化,并填充视图中定义的所有属性。”并且在第 6 阶段 JSF 将“......基于视图定义构建完整的组件树”。这让我觉得我在非回发请求期间提交的编辑值将被覆盖。 我分析了网络流量并意识到选择刷新和导航到页面都使用 HTTP Get 并且都返回相同的响应。不同之处在于浏览器在刷新时维护已编辑的表单数据,但在导航时替换已编辑的数据。换句话说,在刷新期间,浏览器会忽略响应数据并在表单上保留已编辑的数据。这让我感到惊讶,但却是一个很棒的功能。我也很惊讶这个话题没有被更频繁地讨论,因为在编辑表单时不丢失数据至关重要。 我无法想象浏览器会得到一个新的完整响应并忽略它。这听起来像是浏览器中的一个错误!如果应用程序设计正确,这并不重要。 事实证明这是标准的浏览器行为。如果你谷歌“浏览器表单刷新”,你会看到几个参考。当事实证明 JSF 将页面刷新与页面非回发请求完全相同但浏览器对响应的处理方式不同时,我被 JSF 生命周期的结果所困扰。 请提供明确的链接,以确保我们阅读的是同一篇文章 【参考方案1】:

要在用户刷新页面时摆脱设置值,请将 textbox/textarea 自动完成设置为关闭或创建一个函数,该函数将在 prerenderview 事件或构造函数中检查变量是否为空。如果它们不为 null,则将它们设为 null。

【讨论】:

你是说视图过期时的页面刷新像回发请求一样处理?我原以为它将作为非回发请求处理,因此从第 1 阶段“恢复视图”直接进入第 6 阶段“呈现响应”并跳过第 2 阶段“应用请求值”。

以上是关于为啥选择浏览器刷新按钮不会将我的 JSF 表单中的已编辑字段替换为来自服务器的值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

我的支付宝按钮不会链接到贝宝。它只刷新页面,为啥?

button按钮自动刷新页面

访问VBA无法刷新表单

JSF 2 + Spring 3 + Shiro - 会话超时不重定向到登录页面

jquery ajaxfileupload为啥会刷新页面

为啥我的大型 JSF 数据表不是仅在 IE 中填充?