4. 模板引擎:
模板引擎的工作分为三步:
1. 取得模板文件并确认其中的模板语言符合规范。
比如velocity,确定#if有对应得#end等。Xml+xslt的模型中,xml文件标签是否完整等。在完成这些工作后,模板引擎通常会把模板文件解析成一颗节点树(包含模板文件的静态内容节点和模板引擎所定义的特殊节点)。
2. 取得数据对象。
该数据对象一般通过程序传递引用实现。现有的大量框架在程序底层完成,处理方式也各自不同,有两种技术分别为推技术和拉技术。推技术:controller调用set方法把动态数据注入,模板引擎通过get方法获得,典型代表:Struts;拉技术:模板引擎根据配置信息,找到与view对应的model,调用model的get方法取得数据,典型代表:Tapestry。
3. 合并模板文件(静态内容)和数据对象(动态内容),并生成最终页面。
合并的机制一般如下,模板引擎遍历这颗节点树的每一个节点,并render该节点,遇到静态内容节点按正常输入,遇到特殊节点就从数据对象中去得对应值,并执行其表达式语句(如果有的话)。
以下详细说明:
|
Velocity |
|
Template template = Velocity.getTemplate("test.wm"); Context context = new VelocityContext(); context.put("foo", "bar"); context.put("customer", new Customer()); template.merge(context, writer); 当调用Velocity.getTemplate 方法时,将调用ResourceManger的对应方法。 ResourceManger先查看该模板文件是否在cache中,如果没有就去获取,生成resource对象并调用process()方法,确定该模板是否有效,如果有效,则在内存中生成一个Node树。 当调用template.merge()时,遍历这颗Node树,并调用每个Node的render方法。对于模板中的变量和对象Node,还将调用execute()方法,从context中取得value。 注:ResourceManger在runtime\resource包下,Node在runtime\parser\node包下 |
|
Tapestry |
|
Tapestry比较麻烦,先介绍一下http请求的处理过程。 当httprequest请求到达时。该请求被ApplicationServlet捕获,随后ApplicationServlet通过getEngine取到对应的Engine,通过该engine的getService拿到对应的service,调用其service方法执行http请求。 每个service通过RequestCycle对象的getPage方法取得Page对象,并将其设置为该Cycle对象的active Page。之后service调用renderResponse方法执行输出。 renderResponse调用page的getResponseWriter(output)取得writer对象,并把它传给cycle.renderPage(writer)方法,该方法调用page的renderPage方法。 Page执行renderPage时,首先判断是否有listener的请求,如果有则处理listener请求;然后调用BaseComponentTemplateLoader的process方法把模板文件载入并形成一个component节点树,依次执行节点的renderComponent方法。 每个component对象将通过ongl的机制取得对象属性。并把该值写入输入流。 例如:insert component protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) { if (cycle.isRewinding()) return; Object value = getValue(); if (value == null) return; String insert = null; Format format = getFormat(); if (format == null) { insert = value.toString(); } else{ try{ insert = format.format(value); } catch (Exception ex) { throw new ApplicationRuntimeException( Tapestry.format("Insert.unable-to-format",value),this, getFormatBinding().getLocation(), ex); } } String styleClass = getStyleClass(); if (styleClass != null) { writer.begin("span"); writer.attribute("class", styleClass); renderInformalParameters(writer, cycle); } if (getRaw()) writer.printRaw(insert); else writer.print(insert); if (styleClass != null) writer.end(); // <span> } getValue为取得insert的value属性。 |
三、JSP技术分析
1. JSP技术:
JSP,一个伪装后的servlet。web server会对任何一个jsp都生成一个对应jsp类,打开这个类,就会发现,jsp提供的是一个代码生成机制,把jsp文件中所有的scriptlet原封不动的copy的到生成的jsp类中,同时调用println把所有的html标签输出。
|
Test.jsp: <html> <head><title>jsp test</title></head> <body> <table width="226" border="0" cellspacing="0" cellpadding="0"> <tr><td><font face="Arial" size="2" color="#000066"> <b class="headlinebold">The jsp test file</b> </tr></td> </font> </table> <body> </html> |
|
Test_jsp.java: package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; import org.apache.jasper.runtime.*; public class Test _jsp extends HttpJspBase { private static java.util.Vector _jspx_includes; public java.util.List getIncludes() { return _jspx_includes; } public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException { JspFactory _jspxFactory = null; javax.servlet.jsp.PageContext pageContext = null; HttpSession session = null; ServletContext application = null; ServletConfig config = null; JspWriter out = null; Object page = this; JspWriter _jspx_out = null; try { _jspxFactory = JspFactory.getDefaultFactory(); response.setContentType("text/html;charset=ISO-8859-1"); pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true); application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out; out.write("<html>\r\n"); out.write("<head><title>jsp test</title></head> \r\n"); out.write("<body>\r\n"); out.write("<table width=\"226\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\r\n "); out.write("<tr><td><font face=\"Arial \" size=\"2\" color=\"#000066\"> \r\n\t "); out.write("<b class=\"headlinebold\">The jsp test file"); out.write("</b>\r\n\t "); out.write("</tr></td></font>\r\n\t "); out.write("</table>\r\n"); out.write("<body>\r\n"); out.write("</html>"); } catch (Throwable t) { out = _jspx_out; if (out != null && out.getBufferSize() != 0) out.clearBuffer(); if (pageContext != null) pageContext.handlePageException(t); } finally { if (_jspxFactory != null) _jspxFactory.releasePageContext(pageContext); } } } |
更多内容请看PCdog.com--jsp文摘专题
