1、緣由:我們在做項目中肯定都會遇到自定義業務異常 ,然后將業務異常信息跳轉的統一的信息提示頁面的情況,比如我們在struts的時候我們會用到struts的異常處理機制,我們在業務層會跑出我們遇到業務處理異常 ,然后交由struts處理將提示信息到一個頁面進行顯示,來提示用戶的相關操作,這里我們會根據以上情景設計一下怎么來顯示該功能。
2、解決方法:我們的業務異常通常都是拋出的,就是unchecked exception,所以最后總會到達調用該方法的最外層進行捕獲,一般我們都會在action中調用我們的業務方法 ,而業務方法可能會跑出異常,此時我們就可以在此時做些文章了, 我們可以利用filter,來捕獲我們拋出的異常,然后跳轉到一個統一頁面,進行信息提示了。
3、具體代碼:
①自定義異常類,我想這個就不用多說了 ,大家都是會的:
BsException.java
package com.ajun.exception;
/**
* 業務異常類
* @author ajun
* @http://blog.csdn.net/ajun_studio
*/
public class BsException extends RuntimeException {
//異常代碼
private String key;
private Object[] values;//一些其他信息
public BsException() {
super();
}
public BsException(String message, Throwable throwable) {
super(message, throwable);
}
public BsException(String message) {
super(message);
}
public BsException(Throwable throwable) {
super(throwable);
}
public BsException(String message,String key){
super(message);
this.key = key;
}
public BsException(String message,String key,Object value){
super(message);
this.key = key;
this.values = new Object[]{value};
}
public BsException(String message,String key,Object[] values){
super(message);
this.key = key;
this.values = values;
}
public String getKey() {
return key;
}
public Object[] getValues() {
return values;
}
}
package com.ajun.exception;
/**
* 業務異常類
* @author ajun
* @http://blog.csdn.net/ajun_studio
*/
public class BsException extends RuntimeException {
//異常代碼
private String key;
private Object[] values;//一些其他信息
public BsException() {
super();
}
public BsException(String message, Throwable throwable) {
super(message, throwable);
}
public BsException(String message) {
super(message);
}
public BsException(Throwable throwable) {
super(throwable);
}
public BsException(String message,String key){
super(message);
this.key = key;
}
public BsException(String message,String key,Object value){
super(message);
this.key = key;
this.values = new Object[]{value};
}
public BsException(String message,String key,Object[] values){
super(message);
this.key = key;
this.values = values;
}
public String getKey() {
return key;
}
public Object[] getValues() {
return values;
}
}
既然要用到filter ,自然少不了實現Filter接口,攔截你想要的請求,然后,就可以捕獲異常了,此時你可以對你的chain.doFilter進行try catch,然后判斷你想捕獲的異常,很簡單 ,請看代碼:
package com.ajun.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ajun.exception.BsException;
/**
* 業務異常過濾器
* @author ajun
* @http://blog.csdn.net/ajun_studio
*/
public class ExceptionFiler implements Filter {
private String errorPage;//跳轉的錯誤信息頁面
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
//捕獲你拋出的業務異常
try {
chain.doFilter(req, res);
} catch (RuntimeException e) {
if(e instanceof BsException){//如果是你定義的業務異常
request.setAttribute("BsException", e);//存儲業務異常信息類
request.getRequestDispatcher(errorPage).forward(request, response);//跳轉到信息提示頁面?。?nbsp;
}
e.printStackTrace();
}
}
//初始化讀取你配置的提示頁面路徑
public void init(FilterConfig config) throws ServletException {
//讀取錯誤信息提示頁面路徑
errorPage = config.getInitParameter("errorPage");
if(null==errorPage || "".equals(errorPage)){
throw new RuntimeException("沒有配置錯誤信息跳轉頁面,請再web.xml中進行配置\n<init-param>\n<param-name>errorPage</param-name>\n<param-value>/error.jsp</param-value>\n </init-param>\n路徑可以是你自己設定的任何有效路徑頁面??!");
//System.out.println("沒有配置錯誤信息跳轉頁面");
}
}
}
package com.ajun.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ajun.exception.BsException;
/**
* 業務異常過濾器
* @author ajun
* @http://blog.csdn.net/ajun_studio
*/
public class ExceptionFiler implements Filter {
private String errorPage;//跳轉的錯誤信息頁面
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
//捕獲你拋出的業務異常
try {
chain.doFilter(req, res);
} catch (RuntimeException e) {
if(e instanceof BsException){//如果是你定義的業務異常
request.setAttribute("BsException", e);//存儲業務異常信息類
request.getRequestDispatcher(errorPage).forward(request, response);//跳轉到信息提示頁面??!
}
e.printStackTrace();
}
}
//初始化讀取你配置的提示頁面路徑
public void init(FilterConfig config) throws ServletException {
//讀取錯誤信息提示頁面路徑
errorPage = config.getInitParameter("errorPage");
if(null==errorPage || "".equals(errorPage)){
throw new RuntimeException("沒有配置錯誤信息跳轉頁面,請再web.xml中進行配置\n<init-param>\n<param-name>errorPage</param-name>\n<param-value>/error.jsp</param-value>\n </init-param>\n路徑可以是你自己設定的任何有效路徑頁面!!");
//System.out.println("沒有配置錯誤信息跳轉頁面");
}
}
}
Filter在web.xml中的配置如下:
view plaincopy to clipboardprint?
<filter>
<filter-name>ExceptionFilter</filter-name>
<filter-class>com.ajun.filter.ExceptionFiler</filter-class>
<init-param>
<param-name>errorPage</param-name>
<param-value>/error.jsp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>ExceptionFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<filter>
<filter-name>ExceptionFilter</filter-name>
<filter-class>com.ajun.filter.ExceptionFiler</filter-class>
<init-param>
<param-name>errorPage</param-name>
<param-value>/error.jsp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>ExceptionFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
下面寫個servlet ,在請求的時候拋出你定義業務異常來試驗一下吧
package com.ajun.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ExServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
TestService t = new TestService();
t.add();//模擬調用業務層方法,在此方法內拋出異常,此異常會在filter中進行捕獲。
}
}
package com.ajun.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ExServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
TestService t = new TestService();
t.add();//模擬調用業務層方法,在此方法內拋出異常,此異常會在filter中進行捕獲。
}
}
web.xml配置上述servlet
view plaincopy to clipboardprint?
<servlet>
<servlet-name>ExServlet</servlet-name>
<servlet-class>com.ajun.servlet.ExServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ExServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ExServlet</servlet-name>
<servlet-class>com.ajun.servlet.ExServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ExServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
測試時在servlet中被調用的業務類
TestService.java
view plaincopy to clipboardprint?
package com.ajun.servlet;
import com.ajun.exception.BsException;
public class TestService {
public void add(){
System.out.println("add () was called!!");
if(true){
throw new BsException("in add() throws exception!!");//拋出異常,根據你的業務邏輯
}
}
}
package com.ajun.servlet;
import com.ajun.exception.BsException;
public class TestService {
public void add(){
System.out.println("add () was called!!");
if(true){
throw new BsException("in add() throws exception!!");//拋出異常,根據你的業務邏輯
}
}
}
現在部署項目,在你的瀏覽器內輸入:http://localhost:8080/BsException/ajun.do
成功跳轉到error.jsp:顯示:in add() throws exception!!
在后臺得到:
com.ajun.exception.BsException: in add() throws exception!!
at com.ajun.servlet.TestService.add(TestService.java:11)
at com.ajun.servlet.ExServlet.doPost(ExServlet.java:26)
at com.ajun.servlet.ExServlet.doGet(ExServlet