### 一、前言
后臺出現異常如何友好而又高效地回顯到前端呢?直接將一堆的錯誤信息拋給用戶界面,顯然不合適。
先不考慮代碼實現,我們希望是這樣的:
(1)如果是頁面跳轉的請求,出現異常了,我們希望跳轉到一個異常顯示頁面,如下:

當然,這里的界面不夠美觀,但是理論是這樣的。
(2)如果是ajax請求,那么我們,希望后臺將合理的錯誤顯示返回到ajax的回調函數里面,如下:
~~~
$.ajax({
type: "post",
url: "<%=request.getContextPath()%>" + "/businessException.json",
data: {},
dataType: "json",
contentType : "application/json",
success: function(data) {
if(data.success == false){
alert(data.errorMsg);
}else{
alert("請求成功無異常");
}
},
error: function(data) {
alert("調用失敗....");
}
});
~~~
將回調函數的data.errorMsg打印出來:

下面,我們根據上面的思路我們來看看代碼的實現。因此本文實例包含了異常自定義分裝,為了無障礙閱讀下文,請猿友移步先看完博主的另外一篇文章:[Java異常封裝(自己定義錯誤碼和描述,附源碼)](http://blog.csdn.net/u013142781/article/details/50609488)。
### 二、實例詳解
本實例使用的環境 eclipse+maven,其中maven只是為了方便引入jar包。?
使用的技術:springmvc
在Spring MVC中,所有用于處理在請求映射和請求處理過程中拋出的異常的類,都要實現HandlerExceptionResolver接口。HandlerExceptionResolver接口有一個方法resolveException,當controller層出現異常之后就會進入到這個方法resolveException。
**下面我們直接實現HandlerExceptionResolver接口,代碼如下:**
~~~
package com.luo.exceptionresolver;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.druid.support.json.JSONUtils;
import com.luo.exception.BusinessException;
import org.springframework.web.servlet.HandlerExceptionResolver;
public class MySimpleMappingExceptionResolver implements
HandlerExceptionResolver {
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object object, Exception exception) {
// 判斷是否ajax請求
if (!(request.getHeader("accept").indexOf("application/json") > -1 || (request
.getHeader("X-Requested-With") != null && request.getHeader(
"X-Requested-With").indexOf("XMLHttpRequest") > -1))) {
// 如果不是ajax,JSP格式返回
// 為安全起見,只有業務異常我們對前端可見,否則否則統一歸為系統異常
Map<String, Object> map = new HashMap<String, Object>();
map.put("success", false);
if (exception instanceof BusinessException) {
map.put("errorMsg", exception.getMessage());
} else {
map.put("errorMsg", "系統異常!");
}
//這里需要手動將異常打印出來,由于沒有配置log,實際生產環境應該打印到log里面
exception.printStackTrace();
//對于非ajax請求,我們都統一跳轉到error.jsp頁面
return new ModelAndView("/error", map);
} else {
// 如果是ajax請求,JSON格式返回
try {
response.setContentType("application/json;charset=UTF-8");
PrintWriter writer = response.getWriter();
Map<String, Object> map = new HashMap<String, Object>();
map.put("success", false);
// 為安全起見,只有業務異常我們對前端可見,否則統一歸為系統異常
if (exception instanceof BusinessException) {
map.put("errorMsg", exception.getMessage());
} else {
map.put("errorMsg", "系統異常!");
}
writer.write(JSONUtils.toJSONString(map));
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
~~~
上面的代碼,歸結為以下幾點:?
(1)判斷如果不是ajax請求,那么統一跳轉到error.jsp頁面,否則返回json數據。?
(2)如果是業務異常,我們直接打印異常信息,否則,我們統一歸為系統異常,如果不明白這里的業務異常為何物,請閱讀博主博客:[Java異常封裝(自己定義錯誤碼和描述,附源碼)](http://blog.csdn.net/u013142781/article/details/50609488)。
另外,需要在springmvc配置文件添加如下配置:
~~~
<!-- 框架異常處理Handler -->
<bean id="exceptionResolver" class="com.luo.exceptionresolver.MySimpleMappingExceptionResolver"></bean>
~~~
**下面我們直接看controller代碼:**
~~~
package com.luo.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.luo.errorcode.LuoErrorCode;
import com.luo.exception.BusinessException;
@Controller
public class UserController {
@RequestMapping("/index.jhtml")
public ModelAndView getIndex(HttpServletRequest request) throws Exception {
ModelAndView mav = new ModelAndView("index");
return mav;
}
@RequestMapping("/exceptionForPageJumps.jhtml")
public ModelAndView exceptionForPageJumps(HttpServletRequest request) throws Exception {
throw new BusinessException(LuoErrorCode.NULL_OBJ);
}
@RequestMapping(value="/businessException.json", method=RequestMethod.POST)
@ResponseBody
public String businessException(HttpServletRequest request) {
throw new BusinessException(LuoErrorCode.NULL_OBJ);
}
@RequestMapping(value="/otherException.json", method=RequestMethod.POST)
@ResponseBody
public String otherException(HttpServletRequest request) throws Exception {
throw new Exception();
}
}
~~~
關于controller代碼沒什么好解釋的,下面我們直接看結果吧:
(1)如果跳轉頁面過程中出現異常,訪問[http://localhost:8080/web_exception_project/exceptionForPageJumps.jhtml](http://localhost:8080/web_exception_project/exceptionForPageJumps.jhtml)的結果:

(2)如果ajax請求過程中出現異常,訪問[http://localhost:8080/web_exception_project/index.jhtml](http://localhost:8080/web_exception_project/index.jhtml),然后,點擊業務異常按鈕結果:

點擊其他異常按鈕結果:

(3)HandlerExceptionResolver接口并不能處理404錯誤,這種錯誤我們再web.xml里面添加如下配置:
~~~
<!-- 錯誤跳轉頁面 -->
<error-page>
<!-- 路徑不正確 -->
<error-code>404</error-code>
<location>/WEB-INF/view/404.jsp</location>
</error-page>
~~~
然后404.jsp代碼如下:
~~~
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<taglib uri="http://java.sun.com /jsp/jstl/core" prefix="c" />
<html>
<head>
<title>錯誤頁面</title>
</head>
<body>
頁面被黑洞吸走了......
</body>
</html>
~~~
然后訪問一個不存在的連接:[http://localhost:8080/web_exception_project/123456.jhtml](http://localhost:8080/web_exception_project/123456.jhtml),結果如下:

### 三、本工程源碼下載
[http://download.csdn.net/detail/u013142781/9424969](http://download.csdn.net/detail/u013142781/9424969)
- 前言
- Java生成中間logo的二維碼(還可以加上二維碼名稱哦)
- Java我的高效編程之常用函數
- AES加密解密&&SHA1、SHA加密&&MD5加密
- Java中synchronized的使用實例
- Java基礎之集合
- Java基礎之泛型
- Java基礎之枚舉妙用
- 那些年用過的一些前端框架
- 關于正則,那些年一直存在的疑惑解答(正則菜鳥不容錯過)
- 給pdf文件添加防偽水印logo(附工程源碼下載)
- SpringMVC+BUI實現文件上傳(附詳解,源碼下載)
- Java異常封裝(自己定義錯誤碼和描述,附源碼)
- javaweb異常提示信息統一處理(使用springmvc,附源碼)
- 關于Java,那些我心存疑惑的事(不斷更新中...)
- 深入Java虛擬機(1)——Java體系結構
- 深入Java虛擬機(2)——Java的平臺無關性
- 深入Java虛擬機(3)——安全
- 深入Java虛擬機(4)——網絡移動性
- Linux文件編輯命令詳細整理
- 阿里云服務器云數據庫免費體驗(Java Web詳細實例)
- 項目部署、配置、查錯常用到的Linux命令
- Shell腳本了解
- Ajax原理學習
- linux下安裝apache(httpd-2.4.3版本)各種坑
- JSP九大內置對象
- Servlet再度學習
- 開發人員系統功能設計常用辦公軟件分享
- java.lang.ClassNotFoundException:org.springframework.web.context.ContextLoaderListener問題解決
- tomcat內存溢出解決,java.lang.OutOfMemoryError: PermGen space
- 《Java多線程編程核心技術》推薦
- 關于跳槽,是我心浮氣躁?還是我確實該離開了?
- Java I/O學習(附實例和詳解)
- Java經典設計模式之五大創建型模式(附實例和詳解)
- Java經典設計模式之七大結構型模式(附實例和詳解)
- Java經典設計模式之十一種行為型模式(附實例和詳解)
- Java內存管理
- SQL實例整理
- 數據庫面試常問的一些基本概念