javaweb異常提示資訊統一處理(使用springmvc,附原始碼)
一、前言
後臺出現異常如何友好而又高效地回顯到前端呢?直接將一堆的錯誤資訊拋給使用者介面,顯然不合適。
先不考慮程式碼實現,我們希望是這樣的:
(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打印出來:
下面,我們根據上面的思路我們來看看程式碼的實現。因此本文例項包含了異常自定義分裝,為了無障礙閱讀下文,請猿友移步先看完博主的另外一篇文章:
二、例項詳解
本例項使用的環境 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異常封裝(自己定義錯誤碼和描述,附原始碼)。
另外,需要在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程式碼沒什麼好解釋的,下面我們直接看結果吧:
點選其他異常按鈕結果:
(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>