jsp加载顺序.docx
- 文档编号:29129926
- 上传时间:2023-07-20
- 格式:DOCX
- 页数:10
- 大小:17.77KB
jsp加载顺序.docx
《jsp加载顺序.docx》由会员分享,可在线阅读,更多相关《jsp加载顺序.docx(10页珍藏版)》请在冰豆网上搜索。
jsp加载顺序
1、page、include、taglib这三个编译指令,执行的顺序是什么?
2、JSP文件中的Java代码、编译指令、动作指令、EL标签、第三方标签、静态文本等,被编译的顺序是什么?
3、常用的、与JSP解析/编译相关的类有哪些?
换句话说,JSP解析、编译技术是建立在哪些接口和工具之上的?
4、JSP技术所有的编译指令和动作指令有哪些?
5、JSP技术是由谁发起的,现在有哪几个标准?
都有哪些服务器或者项目支持JSP的解析和编译?
回答问题5:
JSP的发起者为——Sun Microsystems, Inc.
JSP是由Java Servlets发展而来。
JSP和Servlet一样,都是在Java Community Process(Java社区组织)等众多人参与下,共同开发出来的,并且最终制定了一些规范和标准。
Java体系中的规范和技术,会被制定成JSR规范。
JSP和Servlet也属于这个规范之中,例如JSR-53规定了JSP 1.2和Servlet 2.4的规范,JSR-152规定了JSP 2.0的规范。
(详见http:
//zh.wikipedia.org/wiki/JSR)
JSP常用的版本有1.2、2.0和2.1(最新版本),其中1.2版本最大的进步在于优化了JSTL(JavaServer Pages Standard Tag Library),已经过时了(因为它不支持EL表达式),2.0在1.2的基础上有了巨大的进步,因为它引入了Expression Language(EL表达式)、简化了tag标签的扩展、增强了XML的语法,以及其他一些重要改进,我是翻译过来的,官方原文如下:
目前支持JSP的引擎有很多,NB的人自己都可以写一套出来,最常见的WebLogic、Tomcat、WebSphere、Resin(据说效率比Tomcat等要高,网易等大网站都在用)
3、常用的、与JSP解析/编译相关的类有哪些?
换句话说,JSP解析、编译技术是建立在哪些接口和工具之上的?
第一个想到的就是Java Servlet API,即servlet-api.jar ,然后JSP的解析有一个工具包,即jasper-compiler.jar,因为JSP是一个标准,那么在解析工具包之上,应该有一个规范的API包,即jsp-api.jar,JSTL是JSP规范的一部分,故还有jstl-api.jar,另外,还有expression language扩展包,el-api.jar。
还注意到一点,JSP是基于XML的,故也涉及到XML的解析(用的是SAX)。
补充一点,可以手动调用程序来解析(也叫预编译)JSP,在Tomcat或WebSphere下,是调用JspC这个工具类:
Tomcat下,jsp是通过org.apache.jasper.JspC编译工具将JSP 页面的预编译,在WAS下,是通过 com.ibm.websphere.ant.tasks.JspC进行预编译
回答问题4和1:
4、JSP技术所有的编译指令和动作指令有哪些?
2、page、include、taglib这三个编译指令,执行的顺序是什么?
ATTRIBUTE_ACTION"attribute"
ATTRIBUTE_DIRECTIVE_ACTION"directive.attribute"
BODY_ACTION"body"
DECLARATION_ACTION"declaration"
DIRECTIVE_ACTION"directive."
DOBODY_ACTION"doBody"
ELEMENT_ACTION"element"
EXPRESSION_ACTION"expression"
FALLBACK_ACTION"fallback"
FORWARD_ACTION"forward"
GET_PROPERTY_ACTION"getProperty"
INCLUDE_ACTION"include"
INCLUDE_DIRECTIVE_ACTION"directive.include"
INVOKE_ACTION"invoke"
JSP_ATTRIBUTE_ACTION"jsp:
attribute"
JSP_ATTRIBUTE_DIRECTIVE_ACTION"jsp:
directive.attribute"
JSP_BODY_ACTION"jsp:
body"
JSP_DECLARATION_ACTION"jsp:
declaration"
JSP_DOBODY_ACTION"jsp:
doBody"
JSP_ELEMENT_ACTION"jsp:
element"
JSP_EXPRESSION_ACTION"jsp:
expression"
JSP_FALLBACK_ACTION"jsp:
fallback"
JSP_FORWARD_ACTION"jsp:
forward"
JSP_GET_PROPERTY_ACTION"jsp:
getProperty"
JSP_INCLUDE_ACTION"jsp:
include"
JSP_INCLUDE_DIRECTIVE_ACTION"jsp:
directive.include"
JSP_INVOKE_ACTION"jsp:
invoke"
JSP_OUTPUT_ACTION"jsp:
output"
JSP_PAGE_DIRECTIVE_ACTION"jsp:
directive.page"
JSP_PARAM_ACTION"jsp:
param"
JSP_PARAMS_ACTION"jsp:
params"
JSP_PLUGIN_ACTION"jsp:
plugin"
JSP_ROOT_ACTION"jsp:
root"
JSP_SCRIPTLET_ACTION"jsp:
scriptlet"
JSP_SET_PROPERTY_ACTION"jsp:
setProperty"
JSP_TAG_DIRECTIVE_ACTION"jsp:
directive.tag"
JSP_TAGLIB_DIRECTIVE_ACTION"jsp:
taglib"
JSP_TEXT_ACTION"jsp:
text"
JSP_USE_BEAN_ACTION"jsp:
useBean"
JSP_VARIABLE_DIRECTIVE_ACTION"jsp:
directive.variable"
OUTPUT_ACTION"output"
PAGE_DIRECTIVE_ACTION"directive.page"
PARAM_ACTION"param"
PARAMS_ACTION"params"
PLUGIN_ACTION"plugin"
ROOT_ACTION"root"
SCRIPTLET_ACTION"scriptlet"
SET_PROPERTY_ACTION"setProperty"
TAG_DIRECTIVE_ACTION"directive.tag"
TAGLIB_DIRECTIVE_ACTION"taglib"
TEXT_ACTION"text"
USE_BEAN_ACTION"useBean"
VARIABLE_DIRECTIVE_ACTION"directive.variable"
其中directive就是编译指令,总结起来,有:
page、include、taglib、tag、attribute、variable,关于他们的执行顺序,看解析程序是最有说服力的,程序如下:
[ 摘自piler.Parser ]
private void parseDirective(Node parent)
throws JasperException
{
this.reader.skipSpaces();
String directive = null;
if (this.reader.matches("page")) {
directive = "<%@ page";
if (this.isTagFile) {
this.err.jspError(this.reader.mark(), "jsp.error.directive.istagfile", directive);
}
parsePageDirective(parent);
} else if (this.reader.matches("include")) {
directive = "<%@ include";
parseIncludeDirective(parent);
} else if (this.reader.matches("taglib")) {
if (this.directivesOnly)
{
return;
}
directive = "<%@ taglib";
parseTaglibDirective(parent);
} else if (this.reader.matches("tag")) {
directive = "<%@ tag";
if (!
(this.isTagFile)) {
this.err.jspError(this.reader.mark(), "jsp.error.directive.isnottagfile", directive);
}
parseTagDirective(parent);
} else if (this.reader.matches("attribute")) {
directive = "<%@ attribute";
if (!
(this.isTagFile)) {
this.err.jspError(this.reader.mark(), "jsp.error.directive.isnottagfile", directive);
}
parseAttributeDirective(parent);
} else if (this.reader.matches("variable")) {
directive = "<%@ variable";
if (!
(this.isTagFile)) {
this.err.jspError(this.reader.mark(), "jsp.error.directive.isnottagfile", directive);
}
parseVariableDirective(parent);
} else {
this.err.jspError(this.reader.mark(), "jsp.error.invalid.directive");
}
this.reader.skipSpaces();
if (!
(this.reader.matches("%>")))
this.err.jspError(this.start, "jsp.error.unterminated", directive);
}
2、JSP文件中的Java代码、编译指令、动作指令、EL标签、第三方标签、静态文本等,被编译的顺序是什么?
根据源码,我看到JSP编译的顺序是这样的:
1-- getJspConfigPageEncoding
2-- determineSyntaxAndEncoding
3-- 解析成 Node.Nodes parsedPage 对象,即取出所有节点
4-- 解析每个节点
第1步,是从web.xml等配置文件中去读取配置(里面有个
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(" directive.")) { parseXMLDirective(parent); } else if (this.reader.matches("<%! ")) { parseDeclaration(parent); } else if (this.reader.matches(" declaration")) { parseXMLDeclaration(parent); } else if (this.reader.matches("<%=")) { parseExpression(parent); } else if (this.reader.matches(" expression")) { parseXMLExpression(parent); } else if (this.reader.matches("<%")) { parseScriptlet(parent); } else if (this.reader.matches(" scriptlet")) { parseXMLScriptlet(parent); } else if (this.reader.matches(" 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(" ")) { parseStandardAction(parent); } else if (! (parseCustomTag(parent))) { checkUnbalancedEndTag(); parseTemplateText(parent); } } 处理的顺序如下: 1-- “<%-- --%>”类型的注释 2-- “<%@ %>”编译指令 3-- “ directive. %>”编译指令 4-- “<%! %>”声明指令 5-- “<%= %>”表达式指令 6-- “<% %>”嵌入脚本 7-- “ text >”嵌入文本 8-- “${ }”EL表达式 9-- “#{ }”EL表达式 10-- “ >”其他jsp动作指令->jstl表达式 11-- 自定义的tag标签拼接的jsp文档 然后,再看看jsp中的java代码(ScriptingElement)是怎么执行的: 第一步: new一个Node节点,然后把java的字符串完整地赋值给Node的text属性,然后把node添加到Parent Node 队列(List)里面。 第二步: 读取这些Nodes,将其转换成java源代码,然后在调用java编译器将源代码编译成class文件。 (注意: 这个功能相当于是把字符串,转换成了java字节码) 这个过程,调用了SmapUtil将上面那些nodes转换成Java源文件,然后调用JDTCompiler工具类,将Java源文件编译成.class文件,我看Tomcat调用的是piler.*包下面的编译工具,实际上JDK也为我们提供了自己手动编译Java文件的方法,JDK 1.6可以用javax.tools.JavaCompiler。 借鉴这个过程,我自己也实现了“字符串——生成Java文件——编译成class文件”的全自动化过程。 这个过程很有用,可以允许我们自己在网站上 上传Java文件并编译运行!
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- jsp 加载 顺序