JSP页面元素的解析顺序
2015-04-21 20:51
204 查看
【转载】http://www.bingfengsa.com/old/archives/9921.html
根据源码,我看到JSP编译的顺序是这样的: 1– getJspConfigPageEncoding2– determineSyntaxAndEncoding3– 解析成 Node.Nodes parsedPage 对象,即取出所有节点4– 解析每个节点 第1步,是从web.xml等配置文件中去读取配置(里面有个<jsp-config>配置),如果配置时设置了统一编码,则使用这种类型的编码,第2步,是根据文件来获取编码,注意看如下一段代码: if ((jspReader.matches(“tag ”)) || (jspReader.matches(“page”))) { jspReader.skipSpaces(); Attributes attrs = Parser.parseAttributes(this, jspReader); encoding = getPageEncodingFromDirective(attrs, ”pageEncoding”); if (encoding != null) { break; } encoding = getPageEncodingFromDirective(attrs, ”contentType”); if (encoding != null) { saveEncoding = encoding; } } }程序首先判断有无编译指令tag或者page,如果有,则检查编译指令是否指定了pageEncoding属性或者contentType属性。根据这种逻辑,可知如下这种写法:<%@ page contentType=”text/html;charset=utf-8″ pageEncoding=”UTF-8″%>其实是重复指定了编码,解析时会以pageEncoding为准。 第4步,解析每个节点:while (reader.hasMoreInput()) { parser.parseElements(root); }这里又分为几个步骤,先看程序: private void parseElements(Node parent) throws JasperException { this.start = this.reader.mark(); if (this.reader.matches(“<%–”)) { parseComment(parent); } else if (this.reader.matches(“<%@”)) { parseDirective(parent); } else if (this.reader.matches(“<jsp:directive.”)) { parseXMLDirective(parent); } else if (this.reader.matches(“<%!”)) { parseDeclaration(parent); } else if (this.reader.matches(“<jsp:declaration”)) { parseXMLDeclaration(parent); } else if (this.reader.matches(“<%=”)) { parseExpression(parent); } else if (this.reader.matches(“<jsp:expression”)) { parseXMLExpression(parent); } else if (this.reader.matches(“<%”)) { parseScriptlet(parent); } else if (this.reader.matches(“<jsp:scriptlet”)) { parseXMLScriptlet(parent); } else if (this.reader.matches(“<jsp:text”)) { parseXMLTemplateText(parent); } else if ((!(this.pageInfo.isELIgnored())) && (this.reader.matches(“${“))) { parseELExpression(parent, ’$'); } else if ((!(this.pageInfo.isELIgnored())) && (this.reader.matches(“#{“))) { parseELExpression(parent, ’#'); } else if (this.reader.matches(“<jsp:”)) { parseStandardAction(parent); } else if (!(parseCustomTag(parent))) { checkUnbalancedEndTag(); parseTemplateText(parent); } } 处理的顺序如下:1– “<%– –%>”类型的注释2– “<%@ %>”编译指令3– “<jsp:directive. %>”编译指令4– “<%! %>”声明指令5– “<%= %>”表达式指令6– “<% %>”嵌入脚本7– “<jsp:text >”嵌入文本8– “${ }”EL表达式9– “#{ }”EL表达式10– “<jsp: >”其他jsp动作指令11– 自定义的tag标签 然后,再看看jsp中的java代码(ScriptingElement)是怎么执行的: 第一步:new一个Node节点,然后把java的字符串完整地赋值给Node的text属性,然后把node添加到Parent Node 队列(List)里面。 第二步:读取这些Nodes,将其转换成java源代码,然后在调用java编译器将源代码编译成class文件。(注意:这个功能相当于是把字符串,转换成了java字节码)这个过程,调用了SmapUtil将上面那些nodes转换成Java源文件,然后调用JDTCompiler工具类,将Java源文件编译成.class文件,我看Tomcat调用的是org.eclipse.jdt.internal.compiler.*包下面的编译工具,实际上JDK也为我们提供了自己手动编译Java文件的方法,JDK 1.6可以用javax.tools.JavaCompiler。
根据源码,我看到JSP编译的顺序是这样的: 1– getJspConfigPageEncoding2– determineSyntaxAndEncoding3– 解析成 Node.Nodes parsedPage 对象,即取出所有节点4– 解析每个节点 第1步,是从web.xml等配置文件中去读取配置(里面有个<jsp-config>配置),如果配置时设置了统一编码,则使用这种类型的编码,第2步,是根据文件来获取编码,注意看如下一段代码: if ((jspReader.matches(“tag ”)) || (jspReader.matches(“page”))) { jspReader.skipSpaces(); Attributes attrs = Parser.parseAttributes(this, jspReader); encoding = getPageEncodingFromDirective(attrs, ”pageEncoding”); if (encoding != null) { break; } encoding = getPageEncodingFromDirective(attrs, ”contentType”); if (encoding != null) { saveEncoding = encoding; } } }程序首先判断有无编译指令tag或者page,如果有,则检查编译指令是否指定了pageEncoding属性或者contentType属性。根据这种逻辑,可知如下这种写法:<%@ page contentType=”text/html;charset=utf-8″ pageEncoding=”UTF-8″%>其实是重复指定了编码,解析时会以pageEncoding为准。 第4步,解析每个节点:while (reader.hasMoreInput()) { parser.parseElements(root); }这里又分为几个步骤,先看程序: private void parseElements(Node parent) throws JasperException { this.start = this.reader.mark(); if (this.reader.matches(“<%–”)) { parseComment(parent); } else if (this.reader.matches(“<%@”)) { parseDirective(parent); } else if (this.reader.matches(“<jsp:directive.”)) { parseXMLDirective(parent); } else if (this.reader.matches(“<%!”)) { parseDeclaration(parent); } else if (this.reader.matches(“<jsp:declaration”)) { parseXMLDeclaration(parent); } else if (this.reader.matches(“<%=”)) { parseExpression(parent); } else if (this.reader.matches(“<jsp:expression”)) { parseXMLExpression(parent); } else if (this.reader.matches(“<%”)) { parseScriptlet(parent); } else if (this.reader.matches(“<jsp:scriptlet”)) { parseXMLScriptlet(parent); } else if (this.reader.matches(“<jsp:text”)) { parseXMLTemplateText(parent); } else if ((!(this.pageInfo.isELIgnored())) && (this.reader.matches(“${“))) { parseELExpression(parent, ’$'); } else if ((!(this.pageInfo.isELIgnored())) && (this.reader.matches(“#{“))) { parseELExpression(parent, ’#'); } else if (this.reader.matches(“<jsp:”)) { parseStandardAction(parent); } else if (!(parseCustomTag(parent))) { checkUnbalancedEndTag(); parseTemplateText(parent); } } 处理的顺序如下:1– “<%– –%>”类型的注释2– “<%@ %>”编译指令3– “<jsp:directive. %>”编译指令4– “<%! %>”声明指令5– “<%= %>”表达式指令6– “<% %>”嵌入脚本7– “<jsp:text >”嵌入文本8– “${ }”EL表达式9– “#{ }”EL表达式10– “<jsp: >”其他jsp动作指令11– 自定义的tag标签 然后,再看看jsp中的java代码(ScriptingElement)是怎么执行的: 第一步:new一个Node节点,然后把java的字符串完整地赋值给Node的text属性,然后把node添加到Parent Node 队列(List)里面。 第二步:读取这些Nodes,将其转换成java源代码,然后在调用java编译器将源代码编译成class文件。(注意:这个功能相当于是把字符串,转换成了java字节码)这个过程,调用了SmapUtil将上面那些nodes转换成Java源文件,然后调用JDTCompiler工具类,将Java源文件编译成.class文件,我看Tomcat调用的是org.eclipse.jdt.internal.compiler.*包下面的编译工具,实际上JDK也为我们提供了自己手动编译Java文件的方法,JDK 1.6可以用javax.tools.JavaCompiler。
相关文章推荐
- Struts2中访问web元素的四种方式及前台jsp页面获取后台值的方式
- jsp页面中的代码执行加载顺序介绍
- JSP获得当前页面名称后判断是否显示页面元素的方法
- servlet2.4与jsp2.0之前jsp页面中如何解析EL
- struts2返回到JSP页面的html字符串如何在JSP页面上解析成html标签
- jsp页面中的代码加载执行顺序
- jsp页面无法解析el表达式
- HTML页面元素加载顺序----Script标签在Firefox下对背景图片的影响
- js获取后台json数据显示在jsp页面元素
- struts2返回到JSP页面的html字符串如何在JSP页面上解析成html标签
- JSP页面无法解析EL表达式
- JSP开发时, 在页面中格式化和解析日期始终是个头疼的事情. 可以用JSTL和JavaScript搞定.
- jsp页面中的EL表达式不被解析的问题
- php页面字符集解析的先后顺序
- JSP页面元素
- 用定制标签库和配置文件实现对JSP页面元素的访问控制
- jsp页面解析不出来
- JSP页面 鼠标移动到页面元素上时,显示完整内容
- 上机实验十五思考题:JSP常用页面元素
- jsp页面中EL表达式不能被解析