Java異常統一處理


我們知道,當我們訪問某個網頁出錯的時候,會彈出這樣的信息

img

顯然,這樣對用戶是極不友好的,我們應該自定義異常頁面,對用戶顯示用戶能夠理解的錯誤信息

自定義異常頁面通常需要兩步:配置過濾器和使用異常工具類。

首先,我們先做好一些准備:

config4error.properties代碼:

e001=傳入參數為空
e002=參數轉換錯誤
###數據庫###
e101=數據庫錯誤:初始化失敗
e102=數據庫錯誤:連接創建失敗
e103=數據庫錯誤:Statement創建失敗
e104=數據庫錯誤:查詢語法失敗
e105=數據庫錯誤:更新語法失敗
e106=數據庫錯誤:資源釋放失敗
e107=數據庫錯誤:結果集處理失敗
###其它無考慮/處理的異常/錯誤###
e0001=系統異常
e0002=系統錯誤

Config4Error.java代碼:

package com.haigest.hx.util;

import com.leeyn.util.Configuration.Configuration;
import com.leeyn.util.path.GetRealPath;

public class Config4Error{    
	public static final String FILE_PATH = GetRealPath.getSrcOrClassesUrl("Classes")+"/config4error.properties";
    public static final Configuration CONF = new Configuration(FILE_PATH);   
}

BaseException.java代碼

(該自定義類繼承了RuntimeException類,並重寫了的方法,提供一系列的構造方法,將properties中鍵與錯誤類型聯系起來)

/***

Copyright 2006 bsmith@qq.com

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/

package com.haigest.hx.util;

/**
 * uniform exception class, uniform exception process with id+cause.
 * the final message is formated from localize message resource.
 * @author bsmith.zhao
 * @date 2006-05-16 11:22:12
 */
public class BaseException extends RuntimeException
{
    protected String key;
    protected Object[] args;
    /**
     * 
     * @param key 異常提示信息
     */
    public BaseException(String key)
    {
        super(key);
        this.key = key;
    }
    /**
     * 
     * @param key 異常提示信息
     * @param cause 異常對象
     */
    public BaseException(String key, Throwable cause)
    {
        super(key, cause);
        this.key = key;
    }
    /**
     * 
     * @param key 異常提示信息
     * @param args 在拋異常時把某些數據也拋給異常處理者
     */
    public BaseException(String key,  Object ... args)
    {
        super(key);
        this.key = key;
        this.args = args;
    }
    /**
     * 
     * @param key 異常提示信息
     * @param cause 異常對象
     * @param args 在拋異常時把某些數據也拋給異常處理者
     */
    public BaseException(String key, Throwable cause, Object ... args)
    {
        super(key, cause);
        this.key = key;
        this.args = args;
    }
    

    public String getKey()
    {
        return key;
    }

    public Object[] getArgs()
    {
        return args;
    }
}

過濾器:DoExceptionInViewFilter.java
思路:先判斷該異常是自定義異常還是系統產生的異常/錯誤,自定義的異常用doBaseException方法來處理,否則寫入日志,最后都要調用senderror將參數(error,error_id)傳到error頁面
值得注意的是,如果是經jsp,會把異常轉為jsp定義的異常,這里就接不了自己定義的BaseException,所以在這里要區分開

package com.haigest.hx.filter;

import java.io.IOException;
import java.util.UUID;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.haigest.hx.util.Config4Error;
import com.haigest.hx.util.BaseException;
/**
 * Exception統一捕捉處理過濾器
 * @author leeyn
 *
 */
public class DoExceptionInViewFilter implements javax.servlet.Filter {
	
	private static Logger logger = Logger.getLogger(DoExceptionInViewFilter.class.getName());
	/**
	 *當請求到達時,會首先被此攔截器攔截,當數據經過獲取並在V層顯示完畢(響應完畢)后,
	 *又回到此Filter內部,途中如果下層有異常拋出,在這里進行攔截捕捉,並統一處理
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
			throws IOException, ServletException {
		try{
			chain.doFilter(request, response);
		}
		catch(BaseException e){	//---自己定義、轉換的異常---
			doBaseException((HttpServletResponse)response, e);
			return;
		}
		catch(Exception e){		//---其它無考慮/處理的異常---		
			if(e.getCause() instanceof BaseException){  	
              //如果是經jsp,會把異常轉為jsp定義的異常,這里就接不了自己定義的BaseException,所以在這里要區分開
				doBaseException((HttpServletResponse)response, (BaseException)e.getCause());
				return;				
			}else{	
				String uuid = UUID.randomUUID().toString();
				logger.error(Config4Error.CONF.findProperty("e0001") + uuid, e);
				senderror((HttpServletResponse)response, "e0001", uuid);
				return;
			}
		}
		catch(Error e){			
          //---其它無考慮/處理的錯誤---	
          //error如果經過servlet一般都會被轉化成異常,所以一般也就到不了這里
			String uuid = UUID.randomUUID().toString();
			logger.error(Config4Error.CONF.findProperty("e0002") + uuid, e);
			senderror((HttpServletResponse)response, "e0002", uuid);
			return;
		}	
	}

	public void doBaseException(HttpServletResponse response, BaseException e)
			throws ServletException, IOException {
		String e_id = null;
		if(e.getArgs()!=null && e.getArgs().length != 0){
			e_id = (String)e.getArgs()[0];
		}
		senderror(response, e.getKey(), e_id);
	}
	
	public void senderror(HttpServletResponse response, String error, String error_id)
			throws ServletException, IOException {
		if(error_id == null){
			response.sendRedirect("/hx/hx/error.jsp?error="+error);
		}else{
			response.sendRedirect("/hx/hx/error.jsp?error="+error+"&error_id="+error_id);
		}
	}
	public void init(FilterConfig arg0) throws ServletException {
	
	}

	public void destroy() {
	
	}
}
<%@ page language="java" import="com.haigest.hx.util.Config4Error" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%
	//設置請求編碼
	request.setCharacterEncoding("utf-8");
	//獲取參數
	String error = request.getParameter("error");
	String error_id = request.getParameter("error_id");
	String user_type = (String)session.getAttribute("user_type");

%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>系統錯誤頁面</title>


<!-- basic styles -->

<link href="css/error/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="css/error/font-awesome.min.css" />

<!--[if IE 7]>
		  <link rel="stylesheet" href="assets/css/font-awesome-ie7.min.css" />
		<![endif]-->

<!-- page specific plugin styles -->

<!-- fonts -->

<link rel="stylesheet"
	href="http://fonts.googleapis.com/css?family=Open+Sans:400,300" />

<!-- ace styles -->

<link rel="stylesheet" href="css/error/ace.min.css" />
<link rel="stylesheet" href="css/error/ace-rtl.min.css" />
<link rel="stylesheet" href="css/error/ace-skins.min.css" />

<!--[if lte IE 8]>
		  <link rel="stylesheet" href="assets/css/ace-ie.min.css" />
		<![endif]-->

<!-- inline styles related to this page -->

<!-- ace settings handler -->



<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->

<!--[if lt IE 9]>
		<script src="assets/js/html5shiv.js"></script>
		<script src="assets/js/respond.min.js"></script>
		<![endif]-->
</head>
<body>

	<div class="main-container" id="main-container">
		<div class="page-content">
			<div class="row">
				<div class="col-xs-12">
					<!-- PAGE CONTENT BEGINS -->

					<div class="error-container">
						<div class="well">
							<h1 class="grey lighter smaller">
								<span class="blue bigger-125">
									<%
										if(error!=null && !"".equals(error)){
											out.println(Config4Error.CONF.findProperty(error));
										}
									%>
								</span>
								<br/><br/>
								<%
									if(error_id!=null && !"".equals(error_id)){
										out.println("錯誤id:"+error_id);
									}
								%>
							</h1>

							<hr />
							<h3 class="lighter smaller">
								抱歉,網站出現錯誤,請重試或聯系網站管理員!
							</h3>

							<div class="space"></div>

							<div>
								
								<!--  
								<ul class="list-unstyled spaced inline bigger-110 margin-15">
									<li> Read the faq</li>

									<li> Give us more info
										on how this specific error occurred!</li>
								</ul>
								-->
							</div>

							<hr />
							<div class="space"></div>

							<div class="center">
							<%
								if("admin".equals(user_type)){
							%>
								<a href="admin/index.jsp" class="btn btn-primary"> 返回首頁 </a>
							<%
								}else if("tutor".equals(user_type)){
							%>
								<a href="teacher/index.jsp" class="btn btn-primary"> 返回首頁 </a>
							<%
								}else if("student".equals(user_type)){
							%>
								<a href="student/index.jsp" class="btn btn-primary"> 返回首頁 </a>
							<%
								}
							%>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>

</body>
</html>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM