Springboot異常處理的五種方式——SpringBoot學習

  SpringBoot 框架異常處理有五種處理方式,從範圍來說包括有全局異常捕獲處理方式和局部異常捕獲處理方式,接下來通過使用下面的後端代碼一一對這五種捕獲方式講解。

package com.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

/**
* @Description 拋出異常 Controller,測試異常
* @author 歐陽
* @since 2019年4月12日 下午12:48:31
* @version V1.0
*/

@Controller
public class ExceptionController {
	
	private static final Logger log = LoggerFactory.getLogger(ExceptionController.class);
	
	@RequestMapping("/exceptionMethod")
	public String exceptionMethod(Model model) throws Exception {
		
		model.addAttribute("msg", "沒有拋出異常");
		
		int num = 1/0;   //a處
		log.info(String.valueOf(num));
		
		return "home";
	}

}

  上述代碼將會在 a處拋出 ArithmeticException 異常。

一、自定義異常錯誤頁面

  相信大家有過這樣的經歷,在遇到異常時,SpringBoot 會自動跳到一個統一的異常頁面,沒錯,SpringBoot 默認的已經提供了一套處理異常的機制,我們只需要自定義該錯誤頁面就可以,所以這種方式就是自定義這個異常的錯誤頁面。
  SpringBoot 默認的異常處理機制:一旦程序中出現了異常 SpringBoot 就會請求 /error 的 url 。在 SpringBoot 中提供了一個叫 BasicExceptionController 來處理 /error 請求,然後跳轉到默認顯示異常的頁面來展示異常信息。接下來就是自定義異常錯誤頁面了,方法很簡單,就是在目錄 src/main/resources/templates/ 下定義一個叫 error 的文件,可以是 jsp 也可以是 html 。
在指定目錄添加 error.html 頁面前效果
  上圖爲在指定目錄 src/main/resources/templates/ 添加 error.html 頁面前效果。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>自定義 springboot 異常處理頁面</title>
</head>
<body>
Springboot BasicExceptionController  錯誤頁面
<br>
<span th:text="${msg}"></span>
</body>
</html>

  在指定目錄添加 error.html 頁面後效果圖:
在指定目錄添加 error.html 頁面後效果

  注意:必須是在目錄 src/main/resources/templates/ 下定義 error 的文件。

二、使用 @ExceptionHandler 註解處理局部異常

  使用這個註解就容易了,但是隻能處理使用 @ExceptionHandler 註解的方法的 Controller 的異常,對於其他 Controller 的異常就無能爲力了,只能再使用同樣的方法將使用 @ExceptionHandler 註解的方法寫入要捕獲異常的 Controller 中,所以不推薦使用。

  使用方式:在最上面的 ExceptionController 中加入使用 @ExceptionHandler 註解的方法代碼,整個 ExceptionController 代碼如下:

package com.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;

/**
* @Description 拋出異常 Controller,測試異常
* @author 歐陽
* @since 2019年4月12日 下午12:48:31
* @version V1.0
*/

@Controller
public class ExceptionController {
	
	private static final Logger log = LoggerFactory.getLogger(ExceptionController.class);
	
	@RequestMapping("/exceptionMethod")
	public String exceptionMethod(Model model) throws Exception {
		
		model.addAttribute("msg", "沒有拋出異常");
		
		int num = 1/0;
		log.info(String.valueOf(num));
		
		return "home";
	}
	
	/**
	 * 描述:捕獲 ExceptionController 中的 ArithmeticException 異常
	 * @param model 將Model對象注入到方法中
	 * @param e 將產生異常對象注入到方法中
	 * @return 指定錯誤頁面
	 */
	@ExceptionHandler(value = {ArithmeticException.class})
	public String arithmeticExceptionHandle(Model model, Exception e) {
		
		model.addAttribute("msg", "@ExceptionHandler" + e.getMessage());
		log.info(e.getMessage());
		
		return "error";
	}
}

  代碼說明:註解 @ExceptionHandlervalue 的值爲數組,表示指定捕獲的異常類型,這裏表示捕獲 ArithmeticException 異常,因爲 a 處 拋出的是 ArithmeticException 異常,跳轉的頁面爲統一的 error.html 頁面,但描述信息不同,以用來區分是 SpringBoot 處理的異常還是我們自己的方法處理的異常,下面也是使用這個方式來區分。

  當訪問 http://localhost:8080/exceptionMethod 時,跳轉到下面頁面,顯示 @ExceptionHandler/ by zero ,表示我們使用 @ExceptionHandler 註解處理異常成功。
@ExceptionHandler/ by zero

三、使用 @ControllerAdvice + @ExceptionHandler 註解處理全局異常

  使用 @ControllerAdvice + @ExceptionHandler 註解能夠處理全局異常,這種方式推薦使用,可以根據不同的異常對不同的異常進行處理。
  使用方式:定義一個類,使用 @ControllerAdvice 註解該類,使用 @ExceptionHandler 註解方法,這裏我定義了一個 GlobalException 類表示來處理全局異常,代碼如下:

package com.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

/**
* @Description 全局異常處理類
* @author 歐陽
* @since 2019年4月12日 下午3:52:04
* @version V1.0
*/
@ControllerAdvice
public class GlobalException {
	
	private static final Logger log = LoggerFactory.getLogger(GlobalException.class);

	
	/**
	 * 描述:捕獲 ArithmeticException 異常
	 * @param model 將Model對象注入到方法中
	 * @param e 將產生異常對象注入到方法中
	 * @return 指定錯誤頁面
	 */
	@ExceptionHandler(value = {ArithmeticException.class})
	public String arithmeticExceptionHandle(Model model, Exception e) {
		
		model.addAttribute("msg", "@ControllerAdvice + @ExceptionHandler :" + e.getMessage());
		log.info(e.getMessage());
		
		return "error";
	}
	
}

   如果需要處理其他異常,例如 NullPointerException 異常,則只需要在 GlobalException 類中定義一個方法使用 @ExceptionHandler(value = {NullPointerException.class}) 註解該方法,在該方法內部處理異常就可以了。

  當訪問 http://localhost:8080/exceptionMethod 時,跳轉到下面頁面,顯示 @ControllerAdvice + @ExceptionHandler :/ by zero ,表示我們使用 @ControllerAdvice + @ExceptionHandler 註解處理異常成功。
使用 @ControllerAdvice + @ExceptionHandler 註解處理異常成功

四、配置 SimpleMappingExceptionResolver 類處理異常

  通過配置 SimpleMappingExceptionResolver 類處理異常也是全局範圍的,通過將 SimpleMappingExceptionResolver 類注入到 Spring 容器。

package com.config;

import java.util.Properties;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

/**
* @Description 配置 SimpleMappingExceptionResolver 類處理異常
* @author 歐陽
* @since 2019年4月12日 下午5:01:08
* @version V1.0
*/

@Configuration
public class GlobalException {
	
	@Bean
	public SimpleMappingExceptionResolver
		getSimpleMappingExceptionResolver(){
		SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
		
		Properties mappings = new Properties();
		/*
		 * 參數一:異常的類型,注意必須是異常類型的全名
		 * 參數二:視圖名稱
		 */
		mappings.put("java.lang.ArithmeticException", "errors");
		
		//設置異常與視圖映射信息的
		resolver.setExceptionMappings(mappings);
		
		return resolver;
	}
}

  注意:在類上加上 @Configuration 註解,在方法上加上 @Bean 註解,方法返回值必須是 SimpleMappingExceptionResolver

  編寫 errors.html 頁面

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>自定義 springboot 異常處理頁面</title>
</head>
<body>
配置 SimpleMappingExceptionResolver 類處理異常
</body>
</html>

  訪問 http://localhost:8080/exceptionMethod 鏈接後拋出 ArithmeticException 異常,跳轉到 errors.html 頁面,效果圖如下所示:
配置 SimpleMappingExceptionResolver 類處理異常

五、實現 HandlerExceptionResolver 接口處理異常

  通過實現 HandlerExceptionResolver 接口處理異常,第一步是編寫類實現 HandlerExceptionResolver 接口。

package com.config;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

/**
* @Description 實現 HandlerExceptionResolver 接口處理異常
* @author 歐陽
* @since 2019年4月12日 下午5:13:58
* @version V1.0
*/

@Configuration
public class HandlerExceptionResolverImpl implements HandlerExceptionResolver {

	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
			Exception ex) {
		ModelAndView modelAndView = new ModelAndView();
		
		modelAndView.addObject("msg", "實現 HandlerExceptionResolver 接口處理異常");
		
		//判斷不同異常類型,做不同視圖跳轉
		if(ex instanceof ArithmeticException){
			modelAndView.setViewName("error");
		}
		
		return modelAndView;
	}

}

  注意:在類上加上 @Configuration 註解。

  配置完後訪問 http://localhost:8080/exceptionMethod 後效果:
實現 HandlerExceptionResolver 接口處理異常

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章