ofbiz view渲染处理机制

来源:互联网 发布:mac os x 10.12.6 编辑:程序博客网 时间:2024/06/01 16:23

1.1.1.1  初始化

       ControlServlet.java 这是一个servlet,其配置文件在web.xml里

      <servlet>              <servlet-name>ControlServlet</servlet-name>              <display-name>ControlServlet</display-name>              <description>MainControl Servlet</description>              <servlet-class>org.apache.ofbiz.webapp.control.ControlServlet</servlet-class>              <load-on-startup>1</load-on-startup>       </servlet>       <servlet-mapping>              <servlet-name>ControlServlet</servlet-name>              <url-pattern>/control/*</url-pattern>       </servlet-mapping>
      这也是为什么大多数请求都是组件名/control/*

 

      首先在第一次请求时经过Servlet的init方法,该Servlet方法如下:

   public void init(ServletConfig config) throws ServletException {       super.init(config);       if (Debug.infoOn()) {           ServletContext servletContext = config.getServletContext();           String webappName = servletContext.getContextPath().length() != 0 ?servletContext.getContextPath().substring(1) : "";           Debug.logInfo("Loading webapp [" + webappName + "],located at " + servletContext.getRealPath("/"), module);   }        //配置默认脚本引擎,默认有beanshell和平台自定义的minilang脚本,可扩展其它脚本       configureBsf();       // 初始化request处理句柄,实质就是加载controller.xml中handler节点中class属性值对应类的实例化和初始化       getRequestHandler();   }


 

该方法中的getRequestHandler就是获取所有的handler节点,加载方式如下

/**    * @Title: getRequestHandler    * @Description: 获取request的处理句柄,request处理分两类,一类是view,    * 另一类是event,对应controller.xml中handler节点的配置信息的获取    * @return: RequestHandler    */   protected RequestHandler getRequestHandler() {       return RequestHandler.getRequestHandler(getServletContext());}

 
/**    * @Title: getRequestHandler    * @Description: 在上下文中新建一个requesthandler,命名为_REQUEST_HANDLER_,    * 构造方法为private,此方法共外界获取实例,为单例模式使用,requesthandler配置来至    * 处理controller.xml中handler节点的配置数据    * @param servletContext    * @return: RequestHandler    */   public static RequestHandler getRequestHandler(ServletContextservletContext) {       RequestHandler rh = (RequestHandler)servletContext.getAttribute("_REQUEST_HANDLER_");       if (rh == null) {           rh = newRequestHandler(servletContext);           servletContext.setAttribute("_REQUEST_HANDLER_", rh);       }       return rh;}

 

其中的RequestHandler方法如下

/**    * @author jack    * 第一步:将controller.xml的解析信息加入到缓存中    * */   private RequestHandler(ServletContext context) {       // init the ControllerConfig, but don't save it anywhere, just load itinto the cache       this.controllerConfigURL = ConfigXMLReader.getControllerConfigURL(context);       try {            //将controller.xml的解析信息加入到缓存中           ConfigXMLReader.getControllerConfig(this.controllerConfigURL);       } catch (WebAppConfigurationException e) {           // FIXME: controller.xml errors should throw an exception.           Debug.logError(e, "Exception thrown while parsing controller.xmlfile: ", module);       }       //加载ViewHandler实现类的实例,其为controller.xml中handler的类型为view       this.viewFactory = new ViewFactory(context,this.controllerConfigURL);       //加载EventHandler实现类的实例,其为controller.xml中handler的类型为非view的情况       this.eventFactory = new EventFactory(context, this.controllerConfigURL);        this.forceHttpSession ="true".equalsIgnoreCase(context.getInitParameter("forceHttpSession"));       this.trackServerHit =!"false".equalsIgnoreCase(context.getInitParameter("track-serverhit"));       this.trackVisit =!"false".equalsIgnoreCase(context.getInitParameter("track-visit"));       this.cookies = !"false".equalsIgnoreCase(context.getInitParameter("cookies"));       this.charset = context.getInitParameter("charset");}


 

其具体存储方式如下

/**    * @author jack    * 构建ViewHandler实现类的map,对handler节点的class属性值对应的类进行实例化和初始化,    * 并设置key=default时,其value=com.hanlin.fadp.webapp.view.JspViewHandler的实例    * @param context    * @param controllerConfigURL    */   public ViewFactory(ServletContext context, URL controllerConfigURL) {       // load all the view handlers        try {           Set<Map.Entry<String,String>> handlerEntries =ConfigXMLReader.getControllerConfig(controllerConfigURL).getViewHandlerMap().entrySet();           if (handlerEntries != null) {                for(Map.Entry<String,String> handlerEntry: handlerEntries) {                                          //将对应的handler给实例化                    ViewHandlerhandler = (ViewHandler) ObjectType.getInstance(handlerEntry.getValue());                   handler.setName(handlerEntry.getKey());                    handler.init(context);                    this.handlers.put(handlerEntry.getKey(),handler);                }           }           // load the "default" type           if (!this.handlers.containsKey("default")) {                ViewHandler defaultHandler =(ViewHandler) ObjectType.getInstance("com.hanlin.fadp.webapp.view.JspViewHandler");                defaultHandler.init(context);                this.handlers.put("default", defaultHandler);           }       } catch (Exception e) {           Debug.logError(e, module);           throw new GeneralRuntimeException(e);       }    }


 

1.1.1.2  渲染处理

      在经过多contoller文件的request 和response标签处理后,其中的response中对应type=“view”会到对应的view-map标签处理,最终处理如下:

     try {            if (Debug.verboseOn())Debug.logVerbose("Rendering view [" + nextPage + "] of type[" + viewMap.type + "]", module);            ViewHandlervh = viewFactory.getViewHandler(viewMap.type);            vh.render(view,nextPage, viewMap.info, contentType, charset, req, resp);        } catch (ViewHandlerException e) {            Throwable throwable = e.getNested()!= null ? e.getNested() : e;             throw newRequestHandlerException(e.getNonNestedMessage(), throwable);        }


 

       标记的第一步是根据key获取上文初始化中的对应ViewHandler实例,这个key来自于view-map中的screen.具体操作如下

   public ViewHandlergetViewHandler(String type) throws ViewHandlerException {        if (UtilValidate.isEmpty(type)) {            type = "default";        }        // get the view handler by type fromthe contextHandlers        ViewHandler handler =handlers.get(type);        if (handler == null) {            throw newViewHandlerException("No handler found for type: " + type);        }        return handler;    }


       标记的第二步是进行具体的渲染,针对于不同类型有不同实现类进行处理,在这里只是展示一下它的接口

   /**     * Render the page.     *     * @param name The name of the view.     * @param page The source of the view;could be a page, url, etc depending on the type of handler.     * @param info An info string attached tothis view     * @param request The HttpServletRequestobject used when requesting this page.     * @param response The HttpServletResponseobject to be used to present the page.     * @throws ViewHandlerException     */    public void render(String name, Stringpage, String info, String contentType, String encoding, HttpServletRequestrequest, HttpServletResponse response) throws ViewHandlerException;


 

         至此view的大致处理过程就清楚了。

原创粉丝点击