Jsp在某种程度上就是一种servelt。
来看看tomcat容器如何将jsp页面翻译成一个”servlet”。
一、
F:\apache-tomcat-6.0.51\work\Catalina\localhost\day0416\org\apache\jsp
这个路径是容器翻译后的java代码和字节码文件的存放路径,当然必须在访问了这个jsp页面后才会生成,大家都知道jsp页面在第一次被访问的时候会被翻译成“类servlet”文件。
但是,如果你写一个servlet,然后部署访问后,这个路径是不会有相应字节码文件的。
二、
首先看引入的包
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
引入了servlet相关的几个包,说明这个“类servlet”文件和原始的servlet类有很大的联系。但是又有些细微差别。
public final class jsp1_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent{}
这个地方继承了apache的一个什么类,还实现了个接口,都是和jsp运行环境有关的。
三、与原生servlet的几个异同点
public void _jspInit() {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());
}
原生的servlet中有初始化方法Init(),在翻译后的“类servlet”文件,变成了_jspInit()方法。
类似的还有_jspDestroy()等方法。实现的与原生servlet类似的功能。
四、_jspService()方法
与原生servlet的类似,_jspService()也传入了HttpServletRequest request, HttpServletResponse response两个对象,这样就能与容器良好的适配了。
异常也同样的跑出了ServletException,如果有输出还会抛出IOException。
(测试了一下,如果jsp里是一个空页面,任何内容都没有,仍然会抛出IO异常,并且response.setContentType(“text/html”),默认还是个页面,然后后面的的异常处理也是完整的,不会因为你内容少而减少处理)
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
JspWriter _jspx_out = null;
PageContext _jspx_page_context = null;
在这里声明了8个对象,其实是10个,包括传进来的请求对象、响应对象。
其中很有意思的是JspWriter _jspx_out = null; JspWriter其实就相当于PrintWriter对象,而且它还会和OutputStream对象争宠,两者在一个页面中总能用一个。
五、响应的正文内容
response.setContentType(“text/html; charset=UTF-8”)会将jsp页面中使用page指令的相关设置写进了,最重要的就是这个charset编码了。
后面异常处理语句写的非常经典,简直是异常处理的典范,值得多读几遍。
try {
response.setContentType("text/html; charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.print("</br>这里是jsp1");
out.flush();
} catch (Throwable t) {
if (!(t instanceof SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else log(t.getMessage(), t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
下面是源代码:
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class jsp1_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();
private static java.util.List _jspx_dependants;
private javax.el.ExpressionFactory _el_expressionfactory;
private org.apache.AnnotationProcessor _jsp_annotationprocessor;
public Object getDependants() {
return _jspx_dependants;
}
public void _jspInit() {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());
}
public void _jspDestroy() {
}
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException {
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
JspWriter _jspx_out = null;
PageContext _jspx_page_context = null;
try {
response.setContentType("text/html; charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write('\r');
out.write('\n');
out.write("\r\n");
out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");
out.write("<title>Insert title here</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.print("</br>这里是jsp1,引入了jsp2.jsp");
out.flush();
out.write("\r\n");
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>");
} catch (Throwable t) {
if (!(t instanceof SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else log(t.getMessage(), t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}