如何在 JSF 中导航?如何使 URL 反映当前页面(而不是前一个页面) [英] How to navigate in JSF? How to make URL reflect current page (and not previous one)
问题描述
我目前正在学习 JSF,当我意识到每当我们使用 <h:form>
时,JSF 的标准行为是总是向我显示 previous 浏览器中的页面,而不是 当前 页面的 URL.
I am currently learning JSF and was rather amazed and puzzled when I realized that whenever we use <h:form>
, the standard behavior of JSF is to always show me the URL of the previous page in the browser, as opposed to the URL of the current page.
我知道这与 JSF 总是将表单发布到同一页面的方式有关,然后只呈现控制器将其返回给不知道页面位置已更改的浏览器的任何页面.
I understand that this has to do with the way JSF always posts a form to the same page and then just renders whatever page the controller gives it back to the browser which doesn't know the page location has changed.
似乎 JSF 已经存在了很长时间,必须有一种干净、可靠的方法来处理这个问题.如果是这样,您介意分享吗?
我找到了各种解决方法,但遗憾的是没有一个看起来像真正可靠的解决方案.
I have found various workarounds, but sadly nothing that seems like a real solid solution.
- 简单地接受该网址具有误导性.
- 将
"?faces-redirect=true"
附加到 每个 bean 的操作的返回值,然后- 找出如何将
@RequestScoped
替换为其他内容(Flash Scopes、CDI 对话、@SessionScoped 等). - 接受对每个用户操作进行两次 HTTP 往返.
- Simply accept that the URL is misleading.
- Append
"?faces-redirect=true"
to the return value of every bean's action and then- figure out how to replace
@RequestScoped
with something else (Flash Scopes, CDI conversation, @SessionScoped, ...). - accept to have two HTTP round trips for every user action.
如果
"?faces-redirect=true"
已经足够好,有没有办法配置整个应用程序以这种方式处理所有请求?If
"?faces-redirect=true"
is as good as it gets, is there a way do configure an entire application to treat all requests this way?推荐答案
事实上,JSF 作为基于表单的应用程序目标 MVC 框架将 POST 表单提交到与带有
<h 的页面相同的 URL:form>
是被请求的表单.您可以通过查看生成的 HTML 输出的URL 来确认.这在 Web 开发术语中被称为 postback.默认情况下,回发导航不会导致对新 URL 的新请求,而是加载目标页面作为响应的内容.当您只想要页面到页面的导航时,这确实令人困惑.
Indeed, JSF as being a form based application targeted MVC framework submits the POST form to the very same URL as where the page with the
<h:form>
is been requested form. You can confirm it by looking at the<form action>
URL of the generated HTML output. This is in web development terms characterized as postback. A navigation on a postback does by default not cause a new request to the new URL, but instead loads the target page as content of the response. This is indeed confusing when you merely want page-to-page navigation.通常,导航/重定向的正确方法取决于业务需求和幂等性(阅读:书签性")请求(注意:有关具体代码示例,请参阅下面的另请参阅"链接).
Generally, the right approach as to navigation/redirection depends on the business requirements and the idempotence (read: "bookmarkability") of the request (note: for concrete code examples, see the "See also" links below).
If the request is idempotent, just use a GET form/link instead of POST form (i.e. use
<a>
,<form>
,<h:link>
or<h:button>
instead of<h:form>
and<h:commandXxx>
).
For example, page-to-page navigation, Google-like search form, etc.
如果请求是非幂等的,只需在同一个视图中有条件地显示结果(即从 action 方法返回
null
或void
并使用 eg
和/或rendered
).
例如,页内数据输入/编辑、多步向导、模态对话框、确认表单等.If the request is non-idempotent, just show results conditionally in the same view (i.e. return
null
orvoid
from action method and make use of e.g.<h:message(s)>
and/orrendered
).
For example, in-page data entry/edit, multi-step wizard, modal dialog, confirmation form, etc.如果请求是非幂等的,但目标页面是幂等的,只需在 POST 后发送重定向(即从 action 方法返回结果为
?faces-redirect=true
,或者手动调用ExternalContext#redirect()
,或将
放在遗留的 XML 导航案例中.
例如,编辑成功后显示所有数据的列表,登录后重定向等.If the request is non-idempotent, but the target page is idempotent, just send a redirect after POST (i.e. return outcome with
?faces-redirect=true
from action method, or manually invokeExternalContext#redirect()
, or put<redirect/>
in legacy XML navigation case).
For example, showing list of all data after successful editing, redirect after login, etc.请注意,纯页面到页面导航通常是幂等的,这就是许多 JSF 启动器因滥用命令链接/按钮而失败的地方,然后抱怨 URL 没有更改.另请注意,导航案例很少用于针对 SEO/UX 开发的实际应用程序中,而这正是许多 JSF 教程因让读者不相信而失败的地方.
Note that pure page-to-page navigation is usually idempotent and this is where many JSF starters fail by abusing command links/buttons for that and then complain afterwards that URLs don't change. Also note that navigation cases are very rarely used in real world applications which are developed with respect to SEO/UX and this is where many JSF tutorials fail by letting the readers believe otherwise.
另请注意,使用 POST 绝对不是更安全";不是 GET,因为请求参数在 URL 中不是立即可见的.它们在 HTTP 请求正文中仍然可见并且仍然可以操作.因此,绝对没有理由为了安全"而更喜欢 POST 的幂等请求.真正的安全在于使用 HTTPS 而不是 HTTP 并检查业务服务方法是否允许当前登录的用户查询实体 X 或操作实体 X 等.一个不错的安全框架为此提供了注释.
Also note that using POST is absolutely not "more secure" than GET because the request parameters aren't immediately visible in URL. They are still visible in HTTP request body and still manipulatable. So there's absolutely no reason to prefer POST for idempotent requests for the sake of "security". The real security is in using HTTPS instead of HTTP and checking in business service methods if currently logged-in user is allowed to query entity X, or to manipulate entity X, etc. A decent security framework offers annotations for this.
- 重定向和导航/转发之间有什么区别以及何时使用什么?
- JSF 隐式导航与显式导航
- 使用哪个 URL 链接/导航到其他 JSF 页面
- 通过查看参数功能添加书签
- 什么可以<f:metadata>、<f:viewParam>和 <f:viewAction>用于?
- 我什么时候应该使用 h:outputLink 而不是 h:commandLink?
- 为实体创建主从页面、如何链接它们以及选择哪个 bean 范围
- 在 JSF 表单提交上保留 GET 请求查询字符串参数
- 在不使用 GET 参数的情况下在 @ViewScoped bean 之间传递对象
这篇关于如何在 JSF 中导航?如何使 URL 反映当前页面(而不是前一个页面)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- figure out how to replace
- 找出如何将