Search code examples
jsfomnifaces

How to invalidate views for the current session in JSF?


We have an application (Mojarra 2.3) where a user can change a global filter of the data it sees. When that happens, I want to keep the session, but invalidate the active views (which are server side).

I found this question which enables you to count the number of views: How do I count the number of views in a user's JSF session (JSF 2.2)?

Based on that I figured I could remove the attribute in which the views are stored. I came up with this method:

public static void invalidateViews() {
  final HttpSession session = Faces.getSession();
  List.of("com.sun.faces.application.view.activeViewContexts",
          "com.sun.faces.application.view.activeViewMaps",
          "com.sun.faces.renderkit.ServerSideStateHelper.LogicalViewMap",
          "org.jboss.weld.context.ConversationContext.conversations")
          .forEach(session::removeAttribute);
  Faces.redirect(Faces.getRequest().getRequestURL().toString());
}

The com.sun.faces.renderkit.ServerSideStateHelper.LogicalViewMap was mentioned in the linked question's answer. I kind of guessed that it would not hurt to remove the other attributes. The answer also mentions that it is Mojarra only.

It seems to work so far, but I would like to ask this: should one clear server side views like this? And, if so, how can I support MyFaces as well?


Solution

  • It seems to work so far, but I would like to ask this: should one clear server side views like this?

    Given that there is no standard API call for this, this is about the best you can do, yes. I have during the JSF 2.3 work requested for a more specific variant of this functionality to exist in the standard API because I needed to be able to destroy view scoped beans associated with a specific JSF view state (for the OmniFaces view scope unload functionality, see Hacks#removeViewState()). But this has unfortunately not yet been fleshed out because of difficulties with Portlets.

    And, if so, how can I support MyFaces as well?

    As seen in the OmniFaces Hacks helper class, the session attribute key for MyFaces 2.x is org.apache.myfaces.application.viewstate.ServerSideStateCacheImpl.SERIALIZED_VIEW and 4.x org.apache.myfaces.application.viewstate.StateCacheServerSide.SERIALIZED_VIEW.

    By the way,

    Faces.redirect(Faces.getRequest().getRequestURL().toString());
    

    this is shorter:

    Faces.refreshWithQueryString();