1、緣由:我們?cè)谧鲰?xiàng)目中肯定都會(huì)遇到自定義業(yè)務(wù)異常 ,然后將業(yè)務(wù)異常信息跳轉(zhuǎn)的統(tǒng)一的信息提示頁(yè)面的情況,比如我們?cè)趕truts的時(shí)候我們會(huì)用到struts的異常處理機(jī)制,我們?cè)跇I(yè)務(wù)層會(huì)跑出我們遇到業(yè)務(wù)處理異常 ,然后交由struts處理將提示信息到一個(gè)頁(yè)面進(jìn)行顯示,來(lái)提示用戶的相關(guān)操作,這里我們會(huì)根據(jù)以上情景設(shè)計(jì)一下怎么來(lái)顯示該功能。
2、解決方法:我們的業(yè)務(wù)異常通常都是拋出的,就是unchecked exception,所以最后總會(huì)到達(dá)調(diào)用該方法的最外層進(jìn)行捕獲,一般我們都會(huì)在action中調(diào)用我們的業(yè)務(wù)方法 ,而業(yè)務(wù)方法可能會(huì)跑出異常,此時(shí)我們就可以在此時(shí)做些文章了, 我們可以利用filter,來(lái)捕獲我們拋出的異常,然后跳轉(zhuǎn)到一個(gè)統(tǒng)一頁(yè)面,進(jìn)行信息提示了。
3、具體代碼:
①自定義異常類(lèi),我想這個(gè)就不用多說(shuō)了 ,大家都是會(huì)的:
BsException.java
package com.ajun.exception;
/**
* 業(yè)務(wù)異常類(lèi)
* @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;
/**
* 業(yè)務(wù)異常類(lèi)
* @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 ,自然少不了實(shí)現(xiàn)Filter接口,攔截你想要的請(qǐng)求,然后,就可以捕獲異常了,此時(shí)你可以對(duì)你的chain.doFilter進(jìn)行try catch,然后判斷你想捕獲的異常,很簡(jiǎn)單 ,請(qǐng)看代碼:
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;
/**
* 業(yè)務(wù)異常過(guò)濾器
* @author ajun
* @http://blog.csdn.net/ajun_studio
*/
public class ExceptionFiler implements Filter {
private String errorPage;//跳轉(zhuǎn)的錯(cuò)誤信息頁(yè)面
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
//捕獲你拋出的業(yè)務(wù)異常
try {
chain.doFilter(req, res);
} catch (RuntimeException e) {
if(e instanceof BsException){//如果是你定義的業(yè)務(wù)異常
request.setAttribute("BsException", e);//存儲(chǔ)業(yè)務(wù)異常信息類(lèi)
request.getRequestDispatcher(errorPage).forward(request, response);//跳轉(zhuǎn)到信息提示頁(yè)面??!
}
e.printStackTrace();
}
}
//初始化讀取你配置的提示頁(yè)面路徑
public void init(FilterConfig config) throws ServletException {
//讀取錯(cuò)誤信息提示頁(yè)面路徑
errorPage = config.getInitParameter("errorPage");
if(null==errorPage || "".equals(errorPage)){
throw new RuntimeException("沒(méi)有配置錯(cuò)誤信息跳轉(zhuǎn)頁(yè)面,請(qǐng)?jiān)賥eb.xml中進(jìn)行配置\n<init-param>\n<param-name>errorPage</param-name>\n<param-value>/error.jsp</param-value>\n </init-param>\n路徑可以是你自己設(shè)定的任何有效路徑頁(yè)面!!");
//System.out.println("沒(méi)有配置錯(cuò)誤信息跳轉(zhuǎn)頁(yè)面");
}
}
}
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;
/**
* 業(yè)務(wù)異常過(guò)濾器
* @author ajun
* @http://blog.csdn.net/ajun_studio
*/
public class ExceptionFiler implements Filter {
private String errorPage;//跳轉(zhuǎn)的錯(cuò)誤信息頁(yè)面
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
//捕獲你拋出的業(yè)務(wù)異常
try {
chain.doFilter(req, res);
} catch (RuntimeException e) {
if(e instanceof BsException){//如果是你定義的業(yè)務(wù)異常
request.setAttribute("BsException", e);//存儲(chǔ)業(yè)務(wù)異常信息類(lèi)
request.getRequestDispatcher(errorPage).forward(request, response);//跳轉(zhuǎn)到信息提示頁(yè)面?。?br /> }
e.printStackTrace();
}
}
//初始化讀取你配置的提示頁(yè)面路徑
public void init(FilterConfig config) throws ServletException {
//讀取錯(cuò)誤信息提示頁(yè)面路徑
errorPage = config.getInitParameter("errorPage");
if(null==errorPage || "".equals(errorPage)){
throw new RuntimeException("沒(méi)有配置錯(cuò)誤信息跳轉(zhuǎn)頁(yè)面,請(qǐng)?jiān)賥eb.xml中進(jìn)行配置\n<init-param>\n<param-name>errorPage</param-name>\n<param-value>/error.jsp</param-value>\n </init-param>\n路徑可以是你自己設(shè)定的任何有效路徑頁(yè)面??!");
//System.out.println("沒(méi)有配置錯(cuò)誤信息跳轉(zhuǎn)頁(yè)面");
}
}
}
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>
下面寫(xiě)個(gè)servlet ,在請(qǐng)求的時(shí)候拋出你定義業(yè)務(wù)異常來(lái)試驗(yàn)一下吧
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();//模擬調(diào)用業(yè)務(wù)層方法,在此方法內(nèi)拋出異常,此異常會(huì)在filter中進(jìn)行捕獲。
}
}
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();//模擬調(diào)用業(yè)務(wù)層方法,在此方法內(nèi)拋出異常,此異常會(huì)在filter中進(jìn)行捕獲。
}
}
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>
測(cè)試時(shí)在servlet中被調(diào)用的業(yè)務(wù)類(lèi)
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!!");//拋出異常,根據(jù)你的業(yè)務(wù)邏輯
}
}
}
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!!");//拋出異常,根據(jù)你的業(yè)務(wù)邏輯
}
}
}
現(xiàn)在部署項(xiàng)目,在你的瀏覽器內(nèi)輸入:http://localhost:8080/BsException/ajun.do
成功跳轉(zhuǎn)到error.jsp:顯示:in add() throws exception!!
在后臺(tái)得到:
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