jsp的Directive指令有三种
<%@Directive 属性="属性值" %>
其中Directive可以是:
1.page 2.include 3.taglib
当时page时候,有一个属性和值是
errorPage="errorPageUrl"
isErrorPage="true|false"
使用这两个属性,可以在jsp页面出错的时候,把错误的处理指向一个页面。有如下jsp代码
<%@page errorPage="ErrPage.jsp"%>
<%
String s="123Plus";
int i=Integer.parseInt(s);
out.println("s=" + s + " i=" + i);
%>
当页面出错的时候,指向的处理页面是ErrPage.jsp。看下由tomcat自动生成的对应的Servlet如下:
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/7.0.29
* Generated at: 2012-07-24 10:54:50 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class TestErr_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private javax.el.ExpressionFactory _el_expressionfactory;
private org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public void _jspInit() {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html");
pageContext = _jspxFactory.getPageContext(this, request, response,
"ErrPage.jsp", 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');
String s="123Plus";
int i=Integer.parseInt(s);
out.println("s=" + s + " i=" + i);
out.write('\r');
out.write('\n');
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.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 throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
在第53,54行,_jspxFactory调用了getPageContext方法,结果赋值给了pageContext,向上观察_jspxFactory是一个javax.servlet.jsp.JspFactory对象,JspFactory是一个抽象类,所以这里的_jspxFactory肯定是继承了JspFactory抽象类的类的对象。JspFactory的方法public static
JspFactory
getDefaultFactory()返回一个这样的对象。这个对象通过多态调用JspFactory中的
public abstract PageContext getPageContext(Servlet servlet,
ServletRequest request,
ServletResponse response,
java.lang.String errorPageURL,
boolean needsSession,
int buffer,
boolean autoflush)
这里面的很多参数就是page指令中可以设置的参数,当tomcat将jsp转换为Servlet时,若遇到Directive指令时就在这里设置相应的参数,通过53,54行可以发现这一点。这个方法返回一个PageContext对象,这里是赋值给了pageContext这个引用了。那么这个pageContext是干嘛用的?看56-59这四行,这不就是获得jsp中的内置对象的么,呵呵。这就是为什么我们在jsp中可以直接用out输出的原因吧。但是若在jsp中用session=false 指令禁掉session的话,这里就不会获得session对象,那么在对应的jsp页面中就不能用session对象了。
下面看看这个页面对应的错误处理页面ErrPage.jsp。这里面最关键的是第7行,这里的exception是什么东东?
<%-- ********* ErrPage.jsp ********** --%>
<%@ page contentType="text/html;charset=gb2312" %>
<%@ page isErrorPage="true" %>
<HTML>
<BODY TEXT="red">
错误信息:<%= exception.getMessage() %>
</BODY>
</HTML>
呵呵,还是直接看看对应生成的Servlet,一切就明了了。
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/7.0.29
* Generated at: 2012-07-24 10:54:03 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class ErrPage_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private javax.el.ExpressionFactory _el_expressionfactory;
private org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public void _jspInit() {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
java.lang.Throwable exception = org.apache.jasper.runtime.JspRuntimeLibrary.getThrowable(request);
if (exception != null) {
response.setStatus(javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=gb2312");
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\n");
out.write("\r\n");
out.write("\r\n");
out.write("<HTML>\r\n");
out.write("<BODY TEXT=\"red\">\r\n");
out.write("\r\n");
out.write("错误信息:");
out.print( exception.getMessage() );
out.write("\r\n");
out.write("</BODY>\r\n");
out.write("</HTML>\r\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.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 throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
看53行java.lang.Throwable exception = org.apache.jasper.runtime.JspRuntimeLibrary.getThrowable(request);这里的exception是一个Throwable类的对象,Throwable是一个普通的java类,是一切异常类的基类。查看tomcat文档是一个普通的类
org.apache.jasper.runtime
Class JspRuntimeLibrary
java.lang.Objectorg.apache.jasper.runtime.JspRuntimeLibrary
public class JspRuntimeLibrary extends Object
getThrowable
public static Throwable getThrowable(ServletRequest request)
- Returns the value of the javax.servlet.error.exception request attribute value, if present, otherwise the value of the javax.servlet.jsp.jspException request attribute value. This method is called at the beginning of the generated servlet code for a JSP error page, when the "exception" implicit scripting language variable is initialized.
若观察上面的生成的Servlet,其中就没有生成这个exception对象,这个对象只有当jsp代码中有<%@ page isErrorPage="true" %>时,才会生成。所以在jsp代码中可以直接使用这个对象,exception.getMessage()调用的相应的Throwable子类的方法,获得相应的错误信息。