1. 程式人生 > >springboot(九)--統一異常處理(500)、錯誤頁處理(404)

springboot(九)--統一異常處理(500)、錯誤頁處理(404)

如題,本篇我們介紹下springboot中統一異常500處理,以及錯誤頁404處理。

一、統一異常處理(500)

主要針對於伺服器出現500異常的情況,返回自定義的500頁面到使用者瀏覽器,或者輸出錯誤json資料到使用者瀏覽器。

如果ex是業務層丟擲的自定義異常則或取自定義異常的自定義狀態碼和自定義訊息+錯誤堆疊資訊;如果ex不是自定義異常,則獲取ex的錯誤堆疊資訊。

MvcExceptionResolver.java

package com.tingcream.springWeb.mvc;
 
import java.io.IOException;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
 
import com.alibaba.fastjson.JSON;
import com.tingcream.springWeb.exception.ServiceCustomException;
import com.tingcream.springWeb.util.AjaxUtil;
 
/**
 * mvc異常處理器
 * @author jelly
 *
 */
@Component
public class MvcExceptionResolver  implements HandlerExceptionResolver{
     private   Logger logger = Logger.getLogger(MvcExceptionResolver.class);
 
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex) {
 
         response.setContentType("text/html;charset=UTF-8");
         response.setCharacterEncoding("UTF-8");
         try {
                  String errorMsg="";
                  boolean isAjax= "1".equals(request.getParameter("isAjax"));
                  
                  //ex 為業務層丟擲的自定義異常
                  if(ex instanceof ServiceCustomException){
                      ServiceCustomException customEx=    (ServiceCustomException)ex;
                      
                      errorMsg ="customStatus:"+customEx.getCustomStatus() +",customMessage:"+customEx.getCustomMessage()
                              +"\r\n"+ ExceptionUtils.getStackTrace(customEx);
                      logger.error(errorMsg);
                  }else{
                    //ex為非自定義異常,則
                      errorMsg=ExceptionUtils.getStackTrace(ex);
                      logger.error(errorMsg);
                       
                  }
              
                  if(isAjax){
                        
                      response.setContentType("application/json;charset=UTF-8");
                       response.getWriter().write(JSON.toJSONString(AjaxUtil.messageMap(500, errorMsg)));
                       return new   ModelAndView();
                  }else{
                      //否則,  輸出錯誤資訊到自定義的500.jsp頁面
                      ModelAndView mv = new ModelAndView("/error/500.jsp");
                      mv.addObject("errorMsg", errorMsg);
                      return mv ;
                  }
            } catch (IOException e) {
                logger.error(ExceptionUtils.getStackTrace(e));
            }
             return new   ModelAndView();
         
    }
     
}

ServiceCustomException.java 

package com.tingcream.springWeb.exception;
 
/**
 * 業務自定義異常
 * @author jelly
 *
 */
public class ServiceCustomException  extends RuntimeException{
     
    private  Integer customStatus;
    private String customMessage;
      
    private static final long serialVersionUID = 1L;
     
    public ServiceCustomException() {
        super();
    }
 
    public ServiceCustomException(Integer customStatus ,String customMessage) {
        this.customStatus=customStatus;
        this.customMessage=customMessage;
    }
     
    public ServiceCustomException(Integer customStatus ,String customMessage,Throwable cause) {
        super(cause);
        this.customStatus=customStatus;
        this.customMessage=customMessage;
    }
 
 
    public Integer getCustomStatus() {
        return customStatus;
    }
 
 
    public void setCustomStatus(Integer customStatus) {
        this.customStatus = customStatus;
    }
 
 
    public String getCustomMessage() {
        return customMessage;
    }
 
 
    public void setCustomMessage(String customMessage) {
        this.customMessage = customMessage;
    }
     
 
}

500.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE html>
<html>
  <head>
    <base href="<%=basePath%>">
    <title>500</title>
  </head>
  <body>
  
    <h3>糟糕! 伺服器出錯啦~~(>_<)~~</h3>
    <div>
      異常資訊如下:<br/>
      ${errorMsg }
      
      
    </div>
  </body>
</html>

我們在controller方法中模擬丟擲一個異常

@RequestMapping("/")
    public  String home(HttpServletRequest request, HttpServletRequest response){
         
         int a =3/0;//不能被0除異常
         
        request.setAttribute("message", "早上好,朋友們!");
         
        return "/home.jsp";
}

AjaxUtil.java

package com.tingcream.springWeb.util;

import java.util.HashMap;
import java.util.Map;


public class AjaxUtil {
	  //得到一個map
	   public static Map<String,Object> getMap(){
		 return new HashMap<String,Object>();
	   }
	   
	   //返回json資料 狀態
	   public static Map<String,Object> messageMap(int status){
		    Map<String,Object>  map=new HashMap<String,Object>();
		    map.put("status", status);
		    	return map; 
		    }
	   //返回json資料 狀態、訊息
	    public static Map<String,Object> messageMap(int status,String message){
	    	Map<String,Object>  map=new HashMap<String,Object>();
	    	map.put("status", status);
	    	map.put("message", message);
	    	return map;
	    }
	    //返回json資料 狀態、訊息 和一個引數
	    public  static Map<String,Object> messageMap(int status,String message,
	    		String paramName,Object paramValue){
	    	Map<String,Object>  map=new HashMap<String,Object>();
	    	map.put("status", status);
	    	map.put("message", message);
	    	map.put(paramName, paramValue);
	    	return map;
	    }
	    //返回json資料 狀態、訊息 和多個引數
	    public static Map<String,Object> messageMap(int status,String message,
	    		String[] paramNames,Object[] paramValues){
	    	Map<String,Object>  map=new HashMap<String,Object>();
	    	map.put("status", status);
	    	map.put("message", message);
	    	if(paramNames!=null&&paramNames.length>0){
	    		for(int i=0;i<paramNames.length;i++){
	        		map.put(paramNames[i], paramValues[i]);
	        	}
	    	}
	    	return map;
	    }
}

用瀏覽器訪問首頁,發現報錯了,進入了500.jsp頁面 。

ok,說明500異常處理配置成功 !!

二、錯誤頁處理(404)

主要針對404請求的情況,如使用者在瀏覽器中隨意地輸入了一個不存在的路徑。

ErrorPageController.java

package com.tingcream.springWeb.mvc;
 
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
/**
 * 錯誤頁(404) 處理
 * @author jelly
 *
 */
 
@Controller
public class ErrorPageController implements ErrorController {
 
     private static final String ERROR_PATH = "/error";
      
        @RequestMapping(ERROR_PATH)
        public String error(){
            return "/error/404.jsp";
        }
        @Override
        public String getErrorPath() {
            return ERROR_PATH;
        }
}

404.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
 
<!DOCTYPE html >
<html>
  <head>
    <base href="<%=basePath%>">
    <title>404</title>
  </head>
  <body>
   <h2>404</h2>
    <h3>抱歉,您訪問的頁面好像被火星汪叼走了!</h3>
  </body>
</html>

啟動伺服器,隨便訪問一個不存在的路徑。。

ok,說明錯誤頁(404) 配置成功 !!