exception对象是一个例外对象,当一个页面在运行过程中发生了例外,就产
生这个对象。如果一个JSP页面要应用此对象,就必须把isErrorPage设为true,
否则无法编译。他实际上是Java.lang.Throwable的对象.
下面看一个错误提示页面配置实例
如果要配置全局错误页面,需要在web.xml中进行如下配置
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/errorpage/error.jsp</location>
</error-page>
我们需要配置 其下有两个属性需要配置,一个是
错误代码,也就是服务器所响应的错误代码。HTTP STATUS 200 500 404都有其特定的含义,这个code就规定了哪一种错误用其对应得location指定页面进行错误页面展示,发送到前台,展现给用户。便定义了errorpage所在位置。
下面看一下错误页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="refresh" content="3;url=${pageContext.request.contextPath}/index.jsp">
<title>错误信息提示</title>
</head>
<body>
对不起,出错了,请联系管理员解决!<br>
错误信息为:<%=exception.getMessage() %><br>
<img alt="对不起,你要访问的页面没有找到,请联系管理员处理!" src="${pageContext.request.contextPath}/img/error.png">
3秒钟后自动跳转回首页,如果没有跳转,请点击<a href="${pageContext.request.contextPath}/index.jsp">这里</a>
</body>
</html>
这里就用到了jsp内置的exception对象,当jsp页面需要用exception对象时,需要将page指令中的iserrorpage属性指定为true.
这样当Jsp引擎在将jsp页面翻译成Servlet的时候,在Servlet的 _jspService方法中会声明一个exception对象,然后将运行jsp出错的异常信息存储到exception对象中,由于Servlet的_jspService方法中声明了exception对象,那么就可以在error.jsp页面中使用exception对象,这样就可以在Jsp页面中拿到出错的异常信息了
下面看测试页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" errorPage="/WEB-INF/errorpage/error.jsp"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<% int i=1/0; %>
</body>
</html>
注意,以上的jsp代码片段中page指令中的 errorPage=”/WEB-INF/errorpage/error.jsp” 这是针对某个页面设置errorpage的做法
接下来列一下page指令的完整语法。
page指令的完整语法
<%@ page
[ language="java" ]
[ extends="package.class" ]
[ import="{package.class | package.*}, ..." ]
[ session="true | false" ]
[ buffer="none | 8kb | sizekb" ]
[ autoFlush="true | false" ]
[ isThreadSafe="true | false" ]
[ info="text" ]
[ errorPage="relative_url" ]
[ isErrorPage="true | false" ]
[ contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=ISO-8859-1" ]
[ pageEncoding="characterSet | ISO-8859-1" ]
[ isELIgnored="true | false" ]
%>
下面我们看一下在struts2中设置errorpage
首先配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>ReView_Struts2_1</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
我们主要关注struts.xml文件的配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<constant name="struts.devMode" value="true" />
<!-- 指定Web应用的默认编码集,相当于调用 HttpServletRequest的setCharacterEncoding方法 -->
<constant name="struts.i18n.encoding" value="UTF-8" />
<package name="struts" extends="struts-default" >
<global-results>
<result name="error">/WEB-INF/exception/error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping result="error" exception="wangcc.exception.GlobalException"></exception-mapping>
</global-exception-mappings>
</package>
<package name="login" namespace="/" extends="struts">
<interceptors>
<interceptor name="loginInterceptor" class="wangcc.interceptor.LoginInterceptor"></interceptor>
<interceptor-stack name="login">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="loginInterceptor"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!--
<default-interceptor-ref name="login"></default-interceptor-ref>
-->
<action name="view" class="wangcc.action.ViewAction">
<interceptor-ref name="login"></interceptor-ref>
<result name="success">
/WEB-INF/film/films.jsp
</result>
</action>
<action name="login" class="wangcc.action.LoginAction" method="login">
<result name="login">/WEB-INF/login/welcome.jsp</result>
<exception-mapping result="loginException" exception="wangcc.exception.LoginException"></exception-mapping>
<result name="loginException">
/WEB-INF/exception/exception.jsp
</result>
</action>
</package>
</struts>
下面我们来分析一下struts.xml中的配置
将该web项目设置成开发模式,当出错时,会在jsp页面上显示出详细的错误信息,有利于开发时更快找到错误。
<package name="struts" extends="struts-default" >
<global-results>
<result name="error">/WEB-INF/exception/error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping result="error" exception="wangcc.exception.GlobalException"></exception-mapping>
</global-exception-mappings>
</package>
这里我们设置一个基包(package),用来设置全局的errorpage,当action中抛出wangcc.exception.GlobalException异常时,统一跳到指定的error.jsp。error.jsp可以输出对应exception的相关信息。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isErrorPage="true"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="refresh" content="3;url=${pageContext.request.contextPath}/index.jsp">
<title>错误信息提示</title>
</head>
<body>
对不起,出错了,请联系管理员解决!<br>
错误信息为:<s:property value="exception.message"/><br>
<img alt="对不起,你要访问的页面没有找到,请联系管理员处理!" src="${pageContext.request.contextPath}/img/error.png">
3秒钟后自动跳转回首页,如果没有跳转,请点击<a href="${pageContext.request.contextPath}/index.jsp">这里</a>
</body>
</html>
GlobalException类相关代码
package wangcc.exception;
public class GlobalException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = 1L;
String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public GlobalException(String message) {
super(message);
this.message = message;
}
public GlobalException() {
super();
}
}
接下来看一下拦截器的配置
<interceptors>
<interceptor name="loginInterceptor" class="wangcc.interceptor.LoginInterceptor"></interceptor>
<interceptor-stack name="login">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="loginInterceptor"></interceptor-ref>
</interceptor-stack>
</interceptors>
注意interceptor的顺序。这个以后会详细讲
LoginInterceptor 验证登录,
package wangcc.interceptor;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class LoginInterceptor extends AbstractInterceptor {
public static final String CUSTOMER_LOGIN = "customerLogin";
@Override
public String intercept(ActionInvocation invocation) throws Exception {
// TODO Auto-generated method stub
ActionContext actionContext = invocation.getInvocationContext();
Map<String, Object> session = actionContext.getSession();
if (session.get("user") != null) {
invocation.invoke();
}
return CUSTOMER_LOGIN;
}
}
最后是局部exception的配置
</action>
<action name="login" class="wangcc.action.LoginAction" method="login">
<result name="login">/WEB-INF/login/welcome.jsp</result>
<exception-mapping result="loginException" exception="wangcc.exception.LoginException"></exception-mapping>
<result name="loginException">
/WEB-INF/exception/exception.jsp
</result>
</action>
package wangcc.exception;
public class LoginException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = 1L;
private String message;
public String getMessage() {
return message;
}
public LoginException() {
super();
}
public void setMessage(String message) {
this.message = message;
}
public LoginException(String message) {
super(message);
this.message = message;
}
}
下面是action
package wangcc.action;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
import wangcc.entity.User;
import wangcc.exception.GlobalException;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
public class LoginAction extends ActionSupport implements ModelDriven<User>,
SessionAware {
private User user = null;
protected Map<String, Object> session;
public String login() {
System.out.println(user.getUsername());
if (user.getUsername().equals("james")) {
System.out.println(user.getUsername() + "EXCEPTION");
throw new GlobalException("密码不正确");
// throw new LoginException("密码不正确");
} else {
if (user != null) {
session.put("user", user);
}
}
return LOGIN;
}
@Override
public User getModel() {
// TODO Auto-generated method stub
if (user == null) {
user = new User();
}
return user;
}
@Override
public void setSession(Map<String, Object> session) {
// TODO Auto-generated method stub
this.session = session;
}
}
在LoginAction中直接 throw new GlobalException(“密码不正确”);
// throw new LoginException(“密码不正确”);
并不需要捕获,因为LoginException和GlobalException都继承了RuntimeException,属于unchecked exception,不需要捕获。
在这里穿插着介绍一下异常的相关知识,后续在spring事务管理中也会讲到。以后应该会专门写一篇关于异常的文章。
异常的基类为Throwable。Throwable下有两个直接子类,一个为Exception,一个为ERROR。ERROR是不能处理的异常,因为这是系统内部的错误,JAVA虚拟机(JVM)运行出错,这种错误我们是无法处理的。Exception是可以处理的异常。其中RuntimeException是Exception异常的子类。RuntimeException异常可以处理,也可以不处理,不是必须要处理的异常。
下面来看一下checked exception 和 unchecked exception
unchecked Exception 包括Error和RuntimeException(如被0除,数组越界)
指的是程序瑕疵或逻辑错误,并且在运行时无法恢复,语法上不需要声明抛出异常
checked exception 包括Exception类下除RuntimeException的所有类
代表程序不能直接控制的无效外界情况(如用户输入,数据库操作,文件丢失等)这时,需要try catch捕获异常或者throws抛出异常。
package wangcc.action;
import com.opensymphony.xwork2.ActionSupport;
public class ViewAction extends ActionSupport {
public String execute() {
return SUCCESS;
}
}