58

我目前正在学习 JSF,当我意识到每当我们使用 时<h:form>,JSF 的标准行为总是在浏览器中显示上一页的 URL ,而不是当前页面的 URL,这让我感到非常惊讶和困惑。

我知道这与 JSF 总是将表单发布到同一页面然后只是将控制器返回给不知道页面位置已更改的浏览器的任何页面呈现给浏览器的方式有关。

似乎 JSF 已经存在了足够长的时间,必须有一个干净、可靠的方法来处理这个问题。如果是这样,你介意分享吗?

我找到了各种解决方法,但遗憾的是,似乎没有一个真正可靠的解决方案。

  • 只需接受 URL 具有误导性即可。
  • 附加"?faces-redirect=true"每个bean 动作的返回值,然后
    • 弄清楚如何@RequestScoped用其他东西替换(Flash Scopes,CDI 对话,@SessionScoped,...)。
    • 接受为每个用户操作进行两次 HTTP 往返。
  • 使用某种方法(例如 3rd 方库或自定义代码)隐藏 URL 中的页面名称,始终为每个页面使用相同的通用 URL。

如果"?faces-redirect=true"尽可能好,有没有办法配置整个应用程序以这种方式处理所有请求?

4

1 回答 1

88

<h:form>事实上,JSF 作为基于表单的应用程序目标 MVC 框架将 POST 表单提交到与请求表单的页面相同的 URL 。您可以通过查看<form action>生成的 HTML 输出的 URL 来确认。这在 web 开发术语中被称为postback。默认情况下,回发上的导航不会导致对新 URL 的新请求,而是将目标页面加载为响应的内容。当您只想要页面到页面导航时,这确实令人困惑。

通常,导航/重定向的正确方法取决于业务需求和请求的幂等性(阅读:“书签性”)(注意:有关具体代码示例,请参阅下面的“另请参阅”链接)。

  • 如果请求是幂等的,只需使用 GET 表单/链接而不是 POST 表单(即使用,<a><form>代替and )。 例如,逐页导航、类似 Google 的搜索表单等。<h:link><h:button><h:form><h:commandXxx>

  • 如果请求是非幂等的,只需在同一视图中有条件地显示结果(即返回nullvoid从动作方法并使用例如<h:message(s)>和/或rendered)。
    例如,页内数据输入/编辑、多步向导、模态对话框、确认表单等。

  • 如果请求是非幂等的,但目标页面是幂等的,则只需在 POST 之后发送重定向(即使用?faces-redirect=truefrom action 方法返回结果,或手动调用ExternalContext#redirect(),或放入<redirect/>遗留的 XML 导航案例)。
    例如,编辑成功后显示所有数据列表,登录后重定向等。

请注意,纯页面到页面导航通常是幂等的,这就是许多 JSF 初学者因滥用命令链接/按钮而失败的地方,然后抱怨 URL 没有改变。另请注意,导航案例很少用于针对 SEO/UX 开发的实际应用程序中,这是许多 JSF 教程失败的地方,让读者不相信。

另请注意,使用 POST 绝对不会比 GET“更安全”,因为请求参数不会立即在 URL 中可见。它们在 HTTP 请求正文中仍然可见并且仍然可以操作。因此,为了“安全”,绝对没有理由将 POST 用于幂等请求。真正的安全性在于使用 HTTPS 而不是 HTTP,并在当前登录的用户被允许查询实体 X 或操作实体 X 等情况下检查业务服务方法。一个体面的安全框架为此提供了注释。

也可以看看:

于 2013-03-20T12:05:48.207 回答