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 条评论
登录 后参与评论

相关文章

来自专栏名山丶深处

springboot集成redis(mybatis、分布式session)

2924
来自专栏开发技术

从源码来理解slf4j的绑定,以及logback对配置文件的加载

  项目中的日志系统使用的是slf4j + logback。slf4j作为一个简单日志门面,为各种loging APIs(像java.util.logging,...

1194
来自专栏大大的微笑

java使用mina和websocket通信

这里以mina整合springMVC为例: //springMVC的配置: <!-- mina --> <bean class="org.spring...

80410
来自专栏IT笔记

Grafana+Prometheus系统监控之SpringBoot

前言 前一段时间使用SpringBoot创建了一个webhook项目,由于近期项目中也使用了不少SpringBoot相关的项目,趁着周末,配置一下使用prome...

3916
来自专栏Jerry的SAP技术分享

使用ABAP代码返回S/4HANA Material上维护的Attachment明细

1443
来自专栏用户画像

spring定时任务之quartz

Spring整合Quartz实现定时任务步骤很简单,大致需要经过如下几步:创建任务(Job)、配置JobDetail、配置触发器(Trigger)、配置Sche...

411
来自专栏Aloys的开发之路

Eclipse+Spark搭建源码分析环境问题分析

Scala IDE complains about ‘... is cross-compiled with an incompatible version of...

1715
来自专栏大内老A

如何实现对上下文(Context)数据的统一管理 [提供源代码下载]

在应用开发中,我们经常需要设置一些上下文(Context)信息,这些上下文信息一般基于当前的会话(Session),比如当前登录用户的个人信息;或者基于当前方法...

2696
来自专栏wannshan(javaer,RPC)

dubbo监控机制之监控中心实现分析

这里的监控中心以dubbo-ops\dubbo-monitor-simple项目说 总的来说是监控中心启动一个sevlet容器,通过web页面向用户多维度的展...

3626
来自专栏程序员宝库

【译】深入研究 Laravel 的依赖注入容器

原文地址:Laravel's Dependency Injection Container in Depth 下面是中文翻译。 Laravel拥有强大的控制反转...

4337

扫描关注云+社区