浏览器后退+ Viewscope Bean [英] browser back + viewscope beans

查看:114
本文介绍了浏览器后退+ Viewscope Bean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题出在: 单击浏览器的后退按钮->打开一个页面,该页面的viewscoped-managedbean已被破坏->从带有网格记录选择的页面的commandButton提交请求?

What the problem is : What happens when clicking on the browser back button --> opens up a page whose viewscoped-managedbean is already destroyed --> submit a request from a commandButton from that page with grid-record-selections ?

我期望的结果: 关联的viewscope-managebean被重新创建,接收到网格记录选择,并像处理浏览器的后退按钮一样处理它们.

What i expect : The associated viewscope-managebean is re-created, receives the grid-record-selections, and deal with them as if the browser back button is never involved.

我的经验: 关联的viewscope-managebean未重新创建,未收到网格记录选择.单击浏览器后退按钮后,必须重新输入URL或F5,才能使其再次正常工作.

What i experience : The associated viewscope-managebean is NOT re-created, doesnt receive the grid-record-selections. Have to reenter the URL, or F5 after clicking on the browser-back button for it to work properly again.

因此,这是成功的情况,所有bean都是可观察范围的bean:

So here's the success scenario, all beans are viewscoped beans :

  1. 获取page1.xhtml-> page1Bean,在@PostConstruct中查询数据等
  2. 从数据表中检查/选择几条记录,单击处理"按钮
  3. page1Bean的处理方法将选定的记录存储在flash对象中,并重定向到page2.xhtml
  4. page1Bean已销毁,page2Bean已创建,并在preRenderView侦听器方法中,从Flash对象中获取选定的记录,并对其进行处理
  5. 单击转到主页"命令按钮以重定向到page1.xhtml,并破坏page2Bean,再次创建page1Bean
  6. 从2到5的循环仍然可行

现在,这是错误的情况,其中涉及浏览器的后退按钮(从#6开始发生了很多变化):

Now, this is the errornous scenario involving the browser back button (different stuffs happening starting from #6) :

  1. 获取page1.xhtml-> page1Bean,在@PostConstruct中查询数据等
  2. 从数据表中检查/选择几条记录,单击处理"按钮
  3. page1Bean的处理方法将选定的记录存储在flash对象中,并重定向到page2.xhtml
  4. page1Bean已销毁,page2Bean已创建,并在preRenderView侦听器方法中,从Flash对象中获取选定的记录,并对其进行处理
  5. 单击浏览器后退按钮page2Bean未销毁,page1Bean未创建
  6. 从数据表中检查/选择几条记录,单击处理"按钮
  7. page1Bean方法执行(很奇怪,因为page1Bean应该已经被破坏了),但是看不到所做的记录选择,并重定向到page2.xhtml
  8. page1Bean没有被销毁(没有日志输出),page2Bean没有被创建(因为它没有被销毁),像往常一样执行了preRenderView侦听器,但是这次,闪存对象中没有选定的记录
  1. GET page1.xhtml --> page1Bean created, querying data, etc in @PostConstruct
  2. check/select several records from a datatable, click on process button
  3. page1Bean's process method stores the selected records in the flash object, and redirect to the page2.xhtml
  4. page1Bean destroyed, page2Bean created, and in preRenderView listener method, fetches the selected records from the flash object, and deal with them
  5. click the browser back button page2Bean is not destroyed, page1Bean is not created
  6. check/select several records from a datatable, click on process button
  7. the page1Bean method executes (strange, because the page1Bean should've been destroyed), but cannot see the record-selections made, and redirect to page2.xhtml
  8. page1Bean is not destroyed (no logging output), page2Bean is not created (since it's not been destroyed), executes the preRenderView listener as usual, but this time, no selected records in the flash object

使用带浏览器后退按钮的viewscope-bean是否有正常的体验(就像没有浏览器后退按钮一样)?

Is it possible to have the normal experience (as if without the browser back button) with viewscope-beans with the browser back button ?

这是我的依赖物:

<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.faces</artifactId>
    <version>2.1.3</version>
    <scope>compile</scope>
</dependency>

请分享您的想法!

推荐答案

在将JSF状态保存方法设置为<的同时,浏览器似乎已经从其缓存中提供了该页面,而不是向服务器发送了完全有价值的HTTP GET请求. c0>(默认设置).

The browser seems to have served the page from its cache instead of sending a fullworthy HTTP GET request to the server, while you have JSF state saving method set to server (which is the default).

有两种方法可以解决此问题:

There are 2 ways to solve this problem:

  1. 告诉浏览器不要缓存动态JSF页面.您可以在过滤器的帮助下完成此操作.

  1. Tell the browser to not cache the dynamic JSF pages. You can do this with help of a filter.

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

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

    chain.doFilter(request, response);
}

将过滤器映射到FacesServlet或其相同的URL模式.

Map the filter on the FacesServlet or its same URL-pattern.

将JSF状态保存方法设置为客户端,以便将整个视图状态存储在表单的隐藏字段中,而不是存储在服务器端的会话中.

Set the JSF state saving method to client, so that the entire view state is stored in a hidden field of the form instead of in the session in the server side.

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>

首选过滤方式.

这篇关于浏览器后退+ Viewscope Bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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