Google app engine 查看时如何保存和检索视图';需要什么

Google app engine 查看时如何保存和检索视图';需要什么,google-app-engine,jsf,jsf-2.2,Google App Engine,Jsf,Jsf 2.2,我的目标是使会话大小尽可能小。(为什么?。这是另一个话题)。 我在faces-config.xml中声明了阶段侦听器 <lifecycle> <phase-listener>mypackage.listener.PhaseListener</phase-listener> </lifecycle> mypackage.listener.PhaseListener 我想在一些memcache中保存除最后一个(最多两个)之外

我的目标是使会话大小尽可能小。(为什么?。这是另一个话题)。 我在faces-config.xml中声明了阶段侦听器

<lifecycle>
        <phase-listener>mypackage.listener.PhaseListener</phase-listener>   
</lifecycle>

mypackage.listener.PhaseListener
我想在一些memcache中保存除最后一个(最多两个)之外的所有其他视图。获取会话映射:

Map<String, Object> sessionMap = event.getFacesContext().getExternalContext().getSessionMap();
Map sessionMap=event.getFacesContext().getExternalContext().getSessionMap();

在beforePhase(PhaseEvent事件)中,方法允许我访问所有视图。因此,在这里,我可以将所有视图保存到memcache,并从会话中删除它们。问题是,在jsf中,这些仍然加载在浏览器中的视图在哪里被请求,以便我可以在需要时重新填充该视图。有可能吗?谢谢。

要解决您问题的核心,请实现一个,您可以在其中控制
恢复视图
渲染响应
阶段/过程。您将在
RENDER\u RESPONSE
期间保存视图,并在
restore\u view
阶段选择性地恢复视图。您的视图处理程序可以如下所示

   public class CustomViewHandlerImpl extends ViewHandlerWrapper{

        @Inject ViewStore viewStore; //hypothetical storage for the views. Could be anything, like a ConcurrentHashMap
        ViewHandler wrapped;

        public CustomViewHandlerImpl(ViewHandler toWrap){          
           this.wrapped = toWrap;
        }

        public UIViewRoot restoreView(FacesContext context, String viewId) throws IOException{

            //this assumes you've previously saved the view, using the viewId

            UIViewRoot theView = viewStore.get(viewId);

            if(theView == null){

               theView = getWrapped().restoreView(context, viewId);              
            }

           return theView;       
        } 


      public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException{

          viewStore.put(viewToRender.getId(),viewToRender);

          getWrapped().renderView(context, viewToRender);

      }

   }
只需插入自定义viewhandler,使用

<view-handler>com.you.customs.CustomViewHandlerImpl</view-handler>

我正在使用谷歌应用程序引擎。在网络上,我找不到任何可读的东西来保存google app engine memcache中的会话,这就是为什么我尝试通过jsf将视图保存在memcache中,而不是在memcache中进行完整的会话管理,因为memcache随时都可以被清除,这是很危险的。我会更新我的问题标签,因为你的答案是不可能只用jsf生命周期来完成的。不幸的是,我不熟悉无状态视图。目前我正在阅读JSF2.2和WELD的CDI。需要对自己进行更多的教育。问题来自jsf在使用bean操作方法时没有清除其ViewScope bean。(尽管我在JSF2.2中读到了这个bug),所以当我点击同一个选项卡几次时,就会在会话中保存多个ViewScope bean。但是GAE中的会话不能超过1MB。我的选择:使用正确管理的作用域或自己管理视图。现在,我正试图按照BalucS的建议制作我的自定义viewscope。我不知道他为什么要删除他的评论。有一种更强大的方法来管理您的viewscope,使用自定义viewhandler@makkasi。将作用域设置为无状态是一个非常简单的更改。但是,主动管理viewscope要复杂一些。我仍在充实我的回答。我会尝试一下你在第一位提出的建议,希望它能奏效。若ViewScope不使用无状态,那个么使用无状态看起来并不是我的选择,因为这是我的首选范围。谢谢你几个月后我又回到这个问题上了。我正在尝试您的解决方案,但作为viewToRender.getId()收到的是'j_id1',我将视图保存在此键下,但在restoreView中,viewId是'/login.xhtml'。为什么会这样,以及如何在put和get中使用相同的ID。这非常令人惊讶@makkasi。请参阅我的编辑。还有,为什么要花这么长时间来报告你的问题?它是否在某个点工作,然后就停止了?
ExternalContext extCtxt = FacesContext.getCurrentInstance().getExternalContext();
String viewName = ((HttpServletRequest)extCtxt.getRequest()).getRequestURI();  //use this id as the key to store your views instead