zoukankan      html  css  js  c++  java
  • OFBiz:初始RequestHandler

    RequestHandler,可以称之为请求处理器,在ControlServlet.init()中初始化:

    public class ControlServlet extends HttpServlet {
            public void init(ServletConfig config) throws ServletException {
            super.init(config);
    
            // configure custom BSF engines
            configureBsf();
            
            // initialize the request handler
            getRequestHandler();
        }
        
        protected RequestHandler getRequestHandler() {
            return RequestHandler.getRequestHandler(getServletContext());
        }
    }


    ControlServlet没有为RequestHandler定义变量,而是放在ServletContext中。一个ServletContext只允许有一个RequestHandler。

    public class RequestHandler {
        public static RequestHandler getRequestHandler(ServletContext servletContext) {
            RequestHandler rh = (RequestHandler) servletContext.getAttribute("_REQUEST_HANDLER_");
            if (rh == null) {
                rh = new RequestHandler();
                servletContext.setAttribute("_REQUEST_HANDLER_", rh);
                rh.init(servletContext);
            }
            return rh;
        }
    }


    RequestHandler的构造器是空的,它的初始化放在init()中。

    public class RequestHandler {
        public void init(ServletContext context) {
            this.context = context;
    
            // init the ControllerConfig, but don't save it anywhere
            // 初始化ControllerConfig, 但是不要保存它
            this.controllerConfigURL = ConfigXMLReader.getControllerConfigURL(context);
            ConfigXMLReader.getControllerConfig(this.controllerConfigURL);
            
            this.viewFactory = new ViewFactory(this);
            this.eventFactory = new EventFactory(this);
        }
    }

    RequestHandler对应的配置文件是WEB-INF/controller.xml,透过ConfigXMLReader处理。OFBiz处理controller.xml使用了缓存,超时时会被自动清理。所以,当OFBiz类中需要ControllerConfig时,不会定义一个变量保存ControllerConfig,而只是定义一个controller.xml对应的URL变量,因为ConfigXMLReader以URL为Key缓存ControllerConfig。RequestHandler的doRequest()获取ControllerConfig就是这样处理的:

    public class RequestHandler {
        public void doRequest(HttpServletRequest request, HttpServletResponse response, String chain,
                GenericValue userLogin, Delegator delegator) throws RequestHandlerException {
            ... ...
    
            // get the controllerConfig once for this method so we don't have to get it over and over inside the method
            ConfigXMLReader.ControllerConfig controllerConfig = this.getControllerConfig();
            Map<String, ConfigXMLReader.RequestMap> requestMapMap = controllerConfig.getRequestMapMap();
            
            ... ...
        }
        
        public ConfigXMLReader.ControllerConfig getControllerConfig() {
            return ConfigXMLReader.getControllerConfig(this.controllerConfigURL);
        }
    }


    RequestHandler包含了一个ViewFactory对象和一个EventFactory对象。ViewFactory对象的初始化由自身的构造器完成。

    public class ViewFactory {
        public ViewFactory(RequestHandler requestHandler) {
            this.handlers = FastMap.newInstance();
            this.requestHandler = requestHandler;
            this.context = requestHandler.getServletContext();
    
            // pre-load all the view handlers
            try {
                this.preLoadAll();
            } catch (ViewHandlerException e) {
                Debug.logError(e, module);
                throw new GeneralRuntimeException(e);
            }
        }
    }


    ViewFactory初始时,调用preLoadAll()装入所有在controller.xml中定义的ViewHandler。

    public class ViewFactory {
        private void preLoadAll() throws ViewHandlerException {
            Set<String> handlers = this.requestHandler.getControllerConfig().getViewHandlerMap().keySet();
            if (handlers != null) {
                for (String type: handlers) {
                    this.handlers.put(type, this.loadViewHandler(type));
                }
            }
    
            // load the "default" type
            if (!this.handlers.containsKey("default")) {
                try {
                    ViewHandler h = (ViewHandler) ObjectType.getInstance("org.ofbiz.webapp.view.JspViewHandler");
                    h.init(context);
                    this. handlers.put("default", h);
                } catch (Exception e) {
                    throw new ViewHandlerException(e);
                }
            }
        }
    }


    loadViewHandler()执行具体的ViewHandler初始化。

    public class ViewFactory {
        private ViewHandler loadViewHandler(String type) throws ViewHandlerException {
            ViewHandler handler = null;
            String handlerClass = this.requestHandler.getControllerConfig().getViewHandlerMap().get(type);
            if (handlerClass == null) {
                throw new ViewHandlerException("Unknown handler type: " + type);
            }
    
            try {
                handler = (ViewHandler) ObjectType.getInstance(handlerClass);
                handler.setName(type);
                handler.init(context);
            } catch (ClassNotFoundException cnf) {
                //throw new ViewHandlerException("Cannot load handler class", cnf);
                Debug.logWarning("Warning: could not load view handler class because it was not found; note that some views may not work: " + cnf.toString(), module);
            } catch (InstantiationException ie) {
                throw new ViewHandlerException("Cannot get instance of the handler", ie);
            } catch (IllegalAccessException iae) {
                throw new ViewHandlerException(iae.getMessage(), iae);
            }
    
            return handler;
        }
    }


    ViewHandler对象创建后,紧接着执行其init()方法。以具体的VelocityViewHandler为例,其inti()方法就完成了VelocityEngine的初始化。

    public class VelocityViewHandler extends AbstractViewHandler {
        public void init(ServletContext context) throws ViewHandlerException {
            try {
                Debug.logInfo("[VelocityViewHandler.init] : Loading...", module);
                ve = new VelocityEngine();
                // set the properties
                // use log4j for logging
                // use classpath template loading (file loading will not work in WAR)
                ve.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS,
                    "org.apache.velocity.runtime.log.Log4JLogSystem");
                ve.setProperty("runtime.log.logsystem.log4j.category", module);
    
                Properties props = null;
                try {
                    props = UtilProperties.getProperties(context.getResource("/WEB-INF/velocity.properties"));
                    Debug.logInfo("[VelocityViewHandler.init] : Loaded /WEB-INF/velocity.properties", module);
                } catch (MalformedURLException e) {
                    Debug.logError(e, module);
                }
                if (props == null) {
                    props = new Properties();
                    Debug.logWarning("[VelocityViewHandler.init] : Cannot load /WEB-INF/velocity.properties. " +
                        "Using default properties.", module);
                }
    
                // set the file loader path -- used to mount the webapp
                if (context.getRealPath("/") != null) {
                    props.setProperty("file.resource.loader.path", context.getRealPath("/"));
                    Debug.logInfo("[VelocityViewHandler.init] : Got true webapp path, mounting as template path.", module);
                }
    
                ve.init(props);
            } catch (Exception e) {
                throw new ViewHandlerException(e.getMessage(), e);
            }
        }
    }
  • 相关阅读:
    csrf跨站请求伪造
    IO 之 InputStream 和 Reader
    javadoc tags
    java this
    递归
    java 文件中 定义一个字符串,它的默认编码是什么?
    合并数组
    << 移位运算
    final static T
    Base64.java 工具类
  • 原文地址:https://www.cnblogs.com/eastson/p/3582068.html
Copyright © 2011-2022 走看看