SpringMVC-6

m0_52014011發表於2020-11-14

SpringMVC異常處理

SpringMVC通過HandlerExceptionResolver處理程式的異常,包括Handler對映、資料繫結以及目標方法執行時發生的異常。
SpringMVC提供的HandlerException是一個介面,它的實現類:
1.AbstractHandlerExceptionResolver它還有自己的子類
1.AnnotationMethodExceptionResolver
2.DefaultHandlerExceptionResolver
3.ResponseStatusExceptionResolver
4.SimpleMappingExceptionResolver
2.HandlerExceptionResolverComposite

DispatcherServlet預設裝配的HandlerResolvedr:
1.AnnotationMethodExceptionResolver
2.DefaultHandlerExceptionResolver
3.ResponseStatusExceptionResolver

如果我們使用了mvc:annotation-driven/
AnnotationMethodExceptionResolver
ExceptionHanlderExceptionResolver
DefaultHandlerExceptionResolver
ResponseStatusExceptionResolver

ExceptionHandlerExceptionResolver:

主要處理Handler中使用@ExceptionHandler註解定義的方法
@ExceptionHandler註解定義的方法優先順序的問題:例如發生的是NullPointException,但是宣告的異常有RuntimeException和Exception,此時會根據異常的就近繼承關係找到深度最淺的那個@ExceptionHandler註解方法,也就是標記RuntimeException的方法。

ExceptionHandlerMethodResolver內部如果找不到@ExceptionHandler註解的話,會找@ControllerAdvice中的@ExceptionHandler註解的方法
注意:我們在使用@ExceptionHandler的時候,用此註解修飾的方法中可以寫入Exception型別得物件,此物件對應出現的異常,如果此時我們需要將異常物件儲存在屬性範圍中時,不能使用map物件儲存,而是使用ModelAndView儲存。

注意:我們現在編寫的處理異常的方式,只能處理Handler方法中出現的異常。那麼如果在Handler方法中沒有找到匹配的異常,SpringMVC會去使用@ControllerAdvice修飾的類中查詢異常。
例子:
(1)書寫一個簡單的數字計算的超連結

   <a href = "mathtest?mun=0">mathtest</a>

(2)在handler裡面寫入計算的處理方法

@RequestMapping("mathtest")
	public String mathtest(@RequestParam("mun") Integer mun){
		System.out.println("result"+(10/mun));
		return "success";
	}
	

(3)異常處理的程式碼:

@ExceptionHandler(value=ArithmeticException.class)
	public String handlerExceptiontest(){
		return "error";
	}

(4)我們可以通過ModelAndView物件將異常傳遞給跳轉頁面,程式碼如下:

@ExceptionHandler(value=ArithmeticException.class)
	public ModelAndView handlerExceptiontest(Exception ex){
		ModelAndView mv = new ModelAndView("error");
		mv.addObject("ex", ex);
		return mv;
	}

(5)如果在handler類裡面找不到異常處理MVC回去有@ControllerAdvice註解的類去尋找處理方法,程式碼如下:

package com.oracle.handler;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

@ControllerAdvice
public class exceptiontest {
	@ExceptionHandler(value=ArithmeticException.class)
	public ModelAndView handlerExceptiontest(Exception ex){
		ModelAndView mv = new ModelAndView("error");
		mv.addObject("ex", ex);
		return mv;
	}
}

ResponseStatusExceptionResolver:

在異常以及異常父類中找到@ResponseStatus註解,然後使用這個註解的屬性進行處理。

我們可以用註解來進行修飾產生的異常:
1.修飾異常類例子:
(1)自定義異常程式碼

package com.oracle.po;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(value=HttpStatus.NOT_EXTENDED,reason= "使用者名稱不正確")
public class MyException extends RuntimeException{
	public MyException(String name ){
		super(name);
	}
}

(2)跳轉的超連結

    <a href = "extest?mun=10">extest</a>

(3)處理的方法

@RequestMapping(value = "/extest")
	public String extest(@RequestParam("mun") Integer num){
		if(num==10){
			throw new MyException("自定義異常");
		}
		return "success";
	}

注:當用@ResponseStatus註釋修飾後,當產生異常的時候,就會丟擲與註釋相關的異常,value屬性設定異常的狀態碼,reason是產生異常的原因。
2.當修飾類中的方法的
當修飾方法時,方法正常執行之後也會丟擲異常:

	@RequestMapping(value = "/extest")
	@ResponseStatus(value=HttpStatus.NOT_EXTENDED,reason= "使用者名稱不正確")
	public String extest(@RequestParam("mun") Integer num){
		if(num==10){
			throw new MyException("自定義異常");
		}
		return "test";
	}