专栏首页编码小白ofbiz view渲染处理机制

ofbiz view渲染处理机制

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的大致处理过程就清楚了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • activiti学习笔记(三) 监听生命周期

    activiti监听生命周期 activiti生命周期的作用 生命周期的作用是在构建processEngine实例时候或者关闭的时候调用对应处理方法,比如我在启...

    cfs
  • activiti学习笔记(二) 获取流程实例

    获取流程实例 流程实例获取的源码解析        以获取默认的流程实例为例,来解释整个流程实例的获取过程 文件位置:/org/activiti/engine/...

    cfs
  • tomcat请求处理分析(六)servlet的处理过程

    1.1.1.1  servlet的解析过程 servlet的解析分为两步实现,第一个是匹配到对应的Wrapper,第二个是加载对应的servlet并进行数据,这...

    cfs
  • abstract virtaul override new 及多态

    abstract 修饰符可以和类、方法、属性、索引器及事件一起使用。在类声明中使用 abstract 修饰符以指示某个类只能是其他类的基类。标记为抽象或包含在抽...

    lulianqi
  • 有关Oracle role的总结

    oracle的role算是对sys privilege 和object privilege的打包。 今天深入的测试了下,还算有不少的东西。 role不是sche...

    jeanron100
  • 微软研究院主管Eric Horvitz:我们决定让AI理解幽默

    幽默是人类独有的特质,在日常生活中扮演着至关重要的作用。心理学家指出幽默在人类认知中发挥重要作用,包括它与学习、解决问题过程的惊人联系,以及幽默在社会参与中的重...

    机器之心
  • 硬连接与软连接,inode与links当访问一个文件的时候,发生了什么INODE的内容建一个硬连接发生了什么?访问硬连接的过程注意建一个软连接发生了什么?访问一个软连接注意

    硬连接和软连接,第一感觉就像是window的快捷方式,实则不然 要说硬连接和软连接,那就必须了解inode和block以及分区了 EXT文件系统在创建分区的时候...

    用户1174983
  • 钟南山团队首篇新冠病毒论文:一半以上患者早期不发热,最长潜伏期24天,基于迄今最大规模样本分析

    这篇刚刚预印发布的论文中,钟南山及其研究团队分析了1099病例后,得出最新感染新冠病毒患者的临床表现:

    量子位
  • 【DB笔试面试572】在Oracle中,模糊查询可以使用索引吗?

    (1)若SELECT子句只检索索引字段,那么模糊查询可以使用索引,例如,“SELECT ID FROM TB WHERE ID LIKE '%123%';”可以...

    小麦苗DBA宝典
  • 微信小程序项目实战

    微信小程序开发设置的背景图片不显示,这是由于:background-image 只能用网络url或者base64图片编码 ,本地图片只能用 image标签src...

    生南星

扫码关注云+社区

领取腾讯云代金券