在还原视图阶段重用UIViewRoot对象

时间:2016-07-08 06:31:41

标签: performance jsf viewhandler

似乎可以在JSF的恢复视图阶段重用UIViewRoot对象,如link here

中所建议的那样

我正在处理一个包含数百个数据元素的非常大的表单,并且在对应用程序进行概要分析时,我发现RestoreView阶段花费的时间最长。

因此,按照这个建议,我尝试在会话对象中缓存UIViewRoot对象,它似乎可以正常工作并提高性能。

但我需要知道的是,它会导致框架出现任何问题(类似陈旧数据或任何其他已知问题)。

是否有其他方法可以缓存View Root。

每次调用FullVisitContext时,都需要很长时间,PartialVisitContext对我不起作用。

这是我在视图处理程序

中编写的内容
    package com.app.customviewhandler;      

    import java.io.IOException;     
    import java.util.Enumeration;       

    import javax.faces.FacesException;      
    import javax.faces.application.ViewHandler;     
    import javax.faces.application.ViewHandlerWrapper;      
    import javax.faces.component.UIViewRoot;        
    import javax.faces.context.FacesContext;        
    import javax.servlet.http.HttpServletRequest;       
    import javax.servlet.http.HttpSession;      

    import configuration.ComponentConfigurationContext;     
    import configuration.ComponentConfigurationFactory;     
    import logging.LoggingService;      
    import com.app.common.utilities.StringUtils;        

    public class CustomViewHandler extends ViewHandlerWrapper {     

        private ViewHandler wrapped;        
        private static LoggingService loggingService;       
        private static final String _USER_CURRENT_VIEW_ID = "USER_CURRENT_VIEW_ID";     
        private static final String _CURRENT_REQUEST_URI = "CURRENT_REQUEST_URI";       
        private static final String _PREVIOUS_REQUEST_URI = "PREVIOUS_REQUEST_URI";     
        static {        
        ComponentConfigurationContext ctx = ComponentConfigurationFactory.getInstance().getComponentConfigurationContext(); 
        loggingService = (LoggingService) ctx.getObject("loggingService");  
        }       

        /**     
         *      
         */     
        public CustomViewHandler(ViewHandler wrapped) {     
        this.wrapped = wrapped; 
        loggingService.info(this, "JSF: Registered a new instance of CustomViewHandler");   
        }       

        public UIViewRoot restoreView(FacesContext context, String viewId) {        
        try {   

        loggingService.info(this, "JSF: restoreView: start");   
        HttpSession session = (HttpSession) context.getCurrentInstance().getExternalContext().getSession(true); 
        HttpServletRequest request = (HttpServletRequest) context.getCurrentInstance().getExternalContext().getRequest();   

        /** 
         * Whenever an URL redirection occurs, we have to reset the cache   
         */ 
        /** 
         * Set the current view name    
         */ 
        request.setAttribute(_USER_CURRENT_VIEW_ID, viewId);    
        loggingService.info(this, "JSF: restoreView: setting _USER_CURRENT_VIEW_ID[" + viewId + "]");   
        UIViewRoot cachedView = null;   
        String previousRequestURI = (String)session.getAttribute(_PREVIOUS_REQUEST_URI);    
        String currentRequestURI = request.getRequestURI(); 
        if(StringUtils.checkNullOrEmpty(previousRequestURI)){   
            loggingService.info(this, "JSF: restoreView: _PREVIOUS_REQUEST_URI is null");   
            resetCachedView(context);   
        }else{  
            loggingService.info(this, "JSF: restoreView: _PREVIOUS_REQUEST_URI["+previousRequestURI+"] for viewId[" + viewId + "]");    
            if(StringUtils.checkNullOrEmpty(currentRequestURI)){    
            loggingService.info(this, "JSF: restoreView: current request does not have any requestURI for viewId[" + viewId + "]");
             resetCachedView(context);
            }else{  
            if(!previousRequestURI.equalsIgnoreCase(currentRequestURI)){
                loggingService.info(this, "JSF: restoreView: URL redurection has occured. resetCachedViews()");
                resetCachedView(context);
            }else{
                loggingService.info(this, "JSF: restoreView: URL same URI requested["+currentRequestURI+"] for viewId[" + viewId + "]");
                cachedView = (UIViewRoot) (session.getAttribute(viewId));
            }
            }   
        }   
        if (cachedView == null) {   
            loggingService.info(this, "JSF: restoreView: cachedView is null. So the view will be restored now");    
            cachedView = getWrapped().restoreView(context, viewId); 
        } else {    
            loggingService.info(this, "JSF: restoreView: the cachedView instance is not null. Returning the cached view."); 
        }   
        session.setAttribute(_PREVIOUS_REQUEST_URI, currentRequestURI); 
        loggingService.info(this, "JSF: restoreView: end"); 
        return cachedView;  
        } catch (Exception e) { 
               loggingService.error(this, "JSF restoreView exception", e);
               throw new RuntimeException(e);
        }   
        }       

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

        try {   

            loggingService.info(this, "JSF: renderView: start");    

            HttpSession session = (HttpSession) context.getCurrentInstance().getExternalContext().getSession(true); 
            HttpServletRequest request = (HttpServletRequest) context.getCurrentInstance().getExternalContext().getRequest();   
            String viewName = (String) request.getAttribute(_USER_CURRENT_VIEW_ID); 
            if (viewName != null) { 
            session.setAttribute(viewName, viewToRender);
            }   
            loggingService.info(this, "JSF: renderView: caching the UIViewRoot");   
            getWrapped().renderView(context, viewToRender); 
            loggingService.info(this, "JSF: renderView: end");  

        } catch (IOException ioException) { 
            loggingService.error(this, "JSF renderView exception", ioException);    
            throw ioException;  
        } catch (FacesException facesException) {   
            loggingService.error(this, "JSF renderView exception", facesException); 
            throw facesException;   
        } catch (Exception e) { 
            loggingService.error(this, "JSF renderView exception", e);  
            throw new RuntimeException(e);  
        }   
        }       

        @Override       
        public ViewHandler getWrapped() {       
        return this.wrapped;    
        }       


        /**     
         * Every time a menu navigation is performed, this method is called. From TemplateManagedBean#gotoPage().       
         * This is to reset the cached UIViewRoot Instance      
         * @param context       
         */     
        public static void resetCachedView(FacesContext context){       
        loggingService.info(CustomViewHandler.class, "JSF: resetCachedView: start");    
        HttpSession session = (HttpSession) context.getCurrentInstance().getExternalContext().getSession(true); 
        Enumeration<String> sessionAttributeNames = session.getAttributeNames();    
        if(sessionAttributeNames!=null){    
            while(sessionAttributeNames.hasMoreElements()){ 
            String sessionAttributeName = sessionAttributeNames.nextElement();
            if(session.getAttribute(sessionAttributeName) instanceof UIViewRoot){
                session.removeAttribute(sessionAttributeName);
                loggingService.info(CustomViewHandler.class, "JSF: resetCachedView: removing cached view root :"+sessionAttributeName);
            }
            }   
        }   
        loggingService.info(CustomViewHandler.class, "JSF: resetCachedView: end");  
        }       

    }       

0 个答案:

没有答案