如何在JSF中导航? 如何使URL反映当前页面(而不是以前的页面)

我目前正在学习JSF,当我意识到每当我们使用<h:form> ,JSF的标准行为就是始终向浏览器显示一页的URL,而不是URL 当前页面。

我明白,这与JSF总是将表单张贴到同一页面然后呈现控制器将其返回到不知道页面位置已经改变的浏览器的任何页面的方式有关。

JSF似乎已经存在很长时间了,必须有一个干净而坚实的方法来解决这个问题。 如果是这样,你介意分享吗?

我已经find了各种解决方法,但遗憾的是,这似乎不是一个真正的解决scheme。

  • 只要接受该url是误导性的。
  • "?faces-redirect=true"附加到每个 bean动作的返回值上
    • 弄清楚如何用别的东西replace@RequestScoped (Flash Scopes,CDI对话,@SessionScoped,…)。
    • 接受每个用户操作都有两次HTTP往返。
  • 使用一些方法(例如第三方库或自定义代码)来隐藏URL中的页面名称,每个页面始终使用相同的通用URL。

如果"?faces-redirect=true"是一样的好,有没有办法configuration整个应用程序来处理所有的请求?

实际上,JSF作为一种基于表单的应用程序,目标MVC框架将POST表单提交到与具有<h:form>的页面被请求的页面完全相同的URL。 您可以通过查看生成的HTML输出的<form action> URL来确认它。 这是以网页开发术语为特征的回传 。 回发上的导航在默认情况下不会引起对新URL的新请求,而是将目标页面加载为响应的内容。 当你仅仅需要页面到页面的导航时,这确实是令人困惑的。

通常,导航/redirect的正确方法取决于请求的业务需求和幂等 (读性:“书签能力”)。

  • 如果请求是幂等的,只需使用GET表单/链接而不是POST表单(即使用<form><h:link><h:button>而不是<h:form><h:commandXxx> )。
    例如,页面到页面的导航,类似Google的search表单等

  • 如果请求是非幂等的,只要有条件地在同一个视图中显示结果(即返回nullvoid ,并使用例如<h:message(s)>和/或rendered )。
    例如,数据input/编辑,多步向导,modal dialog,确认表单等

  • 如果请求是非幂等的,但目标页面是幂等的,只需在POST之后发送一个redirect(即返回结果?faces-redirect=true<redirect/> )。
    例如,显示成功编辑后所有数据的列表,login后redirect等。

请注意,纯页面到页面导航通常是幂等的,这是许多JSF初学者滥用命令链接/button失败的地方,然后抱怨URL不会改变。 还要注意的是,在SEO / UX开发的现实应用程序中很less使用导航工具,而这正是许多JSF教程通过让读者相信其他方式而失败的地方。

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

也可以看看:

  • redirect和导航/转发和何时使用什么有什么区别?
  • JSF隐式与显式导航
  • 可collections性通过查看参数function
  • 什么可以使用<f:元数据>,<f:viewParam>和<f:viewAction>?
  • 什么时候应该使用h:outputLink而不是h:commandLink?
  • 为实体创build主 – 细节页面,如何链接它们以及select哪个bean范围
  • 保留JSF表单提交的GET请求查询string参数
  • 在@ViewScoped bean之间传递一个对象而不使用GET参数