faces-redirect和返回按钮导致其他链接无法正常工作 [英] faces-redirect and the back button cause other links to work incorrectly

查看:90
本文介绍了faces-redirect和返回按钮导致其他链接无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对人脸导航存在疑问.

I have a question surrounding faces navigation.

因此,我有一个页面,该页面带有一个请求参数来加载特定用户.此页面显示commandLink的列表,单击该链接时,将使用隐式导航重定向到另一个页面.通过在"preRenderView"中调用方法来加载用户.

So I have a page that takes a request parameter to load a specific user. This page displays a list of commandLink that, when clicked, redirect to another page using implicit navigation. The user is loaded by calling a method in a "preRenderView".

我们重定向到的页面还带有一个request参数,以确定要加载哪种情况.该页面还使用了preRenderView.

The page that we redirect to also takes a request parameter to determine which case to load. The page is also using a preRenderView.

两个页面都具有视图范围内的bean.

Both pages have beans that are view scoped.

对于所按的FIRST链接,这一切都很棒.第一页将重定向到新的URL,案例将按预期加载.

This all works awesome for the FIRST link that is pressed. The first page redirects to the new URL and the case loads as expected.

但是,如果我单击浏览器的后退按钮,然后单击另一个链接,则该页面不会重定向.它会刷新(而不是刷新),并且显然不会购物.

HOWEVER, if I click the browser's back button and then click another link the page DOESN'T redirect. It refreshes (instead) and, obviously, doesn't shop the case.

刷新后,我可以单击一个链接,它将正确重定向.

After the refresh, I can click a link and it will redirect properly.

现在,当将第一页的Bean保留在会话中时,所有这些工作都很好,但是我不想滥用会话状态,并且我认为不需要将这些数据保留在会话中会议.

Now, all of this works totally fine when the first page's bean is kept in the session but I don't want to abuse the session state and I don't think it should be required for me to keep this data in the session.

我知道我可以通过单击后退按钮时自动重新加载页面来解决此问题(因为将重新创建视图),但是我不确定这是否是正确的解决方案. (我也不知道该如何强制执行此操作)

I know I can fix this by having the page automatically reload when I click the back button (because the view will be recreated) but I'm not sure if that's the correct solution either. (nor am I sure how I would force this)

有人有什么建议吗?这似乎是一个相当普遍的用例,但我真的找不到任何示例.

Does anyone have any suggestions? This seems like a fairly common use case but I couldn't really find any examples.

谢谢!

推荐答案

基本上,您需要告诉浏览器在将视图状态保存方法设置为(默认)server时,不要缓存动态生成的JSF页面.视图状态由生成的JSF页面形式的<input type="hidden" name="javax.faces.ViewState">字段跟踪,其中视图状态标识符作为输入值.当您提交页面并导航到其他页面时,视图状态将在服务器端被丢弃,并且不再存在.从浏览器缓存中取回页面仍会为您提供旧视图状态标识符作为隐藏输入的值.提交该表单完全无效,因为找不到服务器端的视图状态.

Basically, you need to tell the browser to not cache the dynamically generated JSF pages while having view state saving method set to (default) server. The view state is tracked by a <input type="hidden" name="javax.faces.ViewState"> field in the form of the generated JSF page with the view state identifier as input value. When you submit a page and navigate to a different page, then the view state is trashed in the server side and do not exist anymore. Getting the page back from the browser cache would still give you that old view state identifier as value of the hidden input. Submitting that form won't work at all as no view state in the server side can be found.

您想直接从服务器而不是从浏览器缓存中获取一个全新的页面.为了告诉浏览器执行此操作,请创建一个如下所示的Filter:

You want to get a fresh new page straight from the server instead of from the browser cache. In order to tell the browser to do that, create a Filter like this:

@WebFilter(servletNames={"Faces Servlet"})
public class NoCacheFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpReq = (HttpServletRequest) request;
        HttpServletResponse httpRes = (HttpServletResponse) response;

        if (!httpReq.getRequestURI().startsWith(httpReq.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) { // Skip JSF resources (CSS/JS/Images/etc)
            httpRes.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
            httpRes.setHeader("Pragma", "no-cache"); // HTTP 1.0.
            httpRes.setDateHeader("Expires", 0); // Proxies.
        }

        chain.doFilter(request, response);
    }

    // ...
}

通过这种方式,后退按钮将发送一个有价值的HTTP请求,该请求将重新创建视图状态,并导致页面的表单具有正确的视图状态隐藏字段值.

This way the back button will send a fullworthy HTTP request which should recreate the view state and result in a page with a form with the proper view state hidden field value.

这篇关于faces-redirect和返回按钮导致其他链接无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆