ofbiz view渲染处理机制
时间:2022-05-03
本文章向大家介绍ofbiz view渲染处理机制,主要内容包括1.1.1.1 初始化、1.1.1.2 渲染处理、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
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的大致处理过程就清楚了。
- 客户关系管理系统
- 016 Java中的动态代理
- JSON就是这么简单
- 017 Java中的静态代理、JDK动态代理、cglib动态代理
- 我的学习、归纳方法(以学习 Maven 为例)
- JDBC面试题都在这里
- 018 final 关键字的用途
- 04-01.总结switch,for,while,do。while跳转语句
- JDBC【介绍JDBC、使用JDBC连接数据库、简单的工具类】
- 019 单例模式的5种写法
- 图书管理系统【部署开发环境、解决分类、图书、前台页面模块】
- 图书管理系统【用户、购买、订单模块、添加权限】
- 04-02.总结switch,for,while,do。while跳转语句
- 图书管理系统【总结】
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 基于Java的俄罗斯方块游戏的设计与实现
- Docker中部署RabbitMQ并使用Python3.x操作全书(Python操作RabbitMQ看这一篇就够了)
- 【CPP】模板类线性表
- leetcode 剑指 Offer 32 - II. 从上到下打印二叉树 II
- Matlab系列之程序优化
- 基于BS架构微博系统
- 10分钟学会pillow图像处理16式
- 编译原理课程设计词法分析
- 30分钟学会XGBoost
- Linux页框分配器之内存碎片化整理
- 手把手教你实现"短信轰炸"
- 最全总结!聊聊 Python 调用 JS 的几种方式
- 爬取小说网站章节和小说语音播放
- JavaScript原型、原型链及原型链污染
- 报刊订阅管理系统的设计与实现