Javaweb異常提示信息統一處理


轉載: Javaweb異常提示信息統一處理

一、前言

后台出現異常如何友好而又高效地回顯到前端呢?直接將一堆的錯誤信息拋給用戶界面,顯然不合適。

先不考慮代碼實現,我們希望是這樣的:

(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異常封裝(自己定義錯誤碼和描述,附源碼)

二、實例詳解

本實例使用的環境 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代碼沒什么好解釋的,下面我們直接看結果吧:

(1)如果跳轉頁面過程中出現異常,訪問http://localhost:8080/web_exception_project/exceptionForPageJumps.jhtml的結果:

(2)如果ajax請求過程中出現異常,訪問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://download.csdn.net/detail/u013142781/9424969


免責聲明!

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



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