第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Spring MVC 異常處理

1. 前言

本章節(jié)將和大家一起聊聊 Spring MVC 是如何處理異常的。

Spring MVC 框架中,將異常處理從業(yè)務(wù)邏輯中解耦出來,既保證了業(yè)務(wù)邏輯高度內(nèi)聚性,又能實(shí)現(xiàn)了異常信息的統(tǒng)一處理和維護(hù)。很優(yōu)雅的解決了異常的問題。通過本章節(jié)內(nèi)容的學(xué)習(xí),你將了解到 Spring MVC 內(nèi)置的異常處理機(jī)制。

  • 將異常映射成 HTTP 狀態(tài)碼;
  • 全局異常處理器的使用。這個(gè)將是本章節(jié)的重點(diǎn);
  • 與異常有關(guān)的注解。

2. 異常處理原則

異常是程序運(yùn)行過程中不可避免的問題。異常出現(xiàn)的原因很多,但不管怎樣,都需要提前預(yù)知或者當(dāng)異常發(fā)生后采取相應(yīng)的處理措施。

異常的處理原則是:

  • 能預(yù)知的盡可能在邏輯層面提前制止。如用戶注冊(cè)時(shí),要求登錄名是唯一的,可先檢查數(shù)據(jù)庫是否存在同名用戶名后,再進(jìn)行添加操作;
  • 以一種友好的方式告知使用者出錯(cuò)的原因;
  • 采用多層體系結(jié)構(gòu)的項(xiàng)目中,建議異常由下逐層向上拋出,一直到達(dá)應(yīng)用層面;
  • 使用日志記錄功能把異常信息記錄在日志文件中,便于開發(fā)者分析。

如下面的控制器方法:

@Controller
public class ExceptionAction {
@RequestMapping("/exception01")
public String exception01(@RequestParam("userName") String userName) {	
	return "exception";
}
}

在瀏覽器中輸入:http://localhost:8888/sm-demo/exception01 ,頁面中會(huì)出現(xiàn)錯(cuò)誤提示。

圖片描述

這個(gè)原因是 @RequestParam(“userName”) 注解在默認(rèn)情況下,要求請(qǐng)求包中一定要有 userName 這個(gè)參數(shù)。

顯然,頁面中顯示出來的錯(cuò)誤信息是不友好的。所謂的異常處理,并不能完全阻止異常的發(fā)生。而是把異常信息對(duì)外、對(duì)內(nèi)做一個(gè)封裝,換一個(gè)淺白的、直接的、非專業(yè)的方式告訴使用者。

對(duì)于前面的異常解決方案,可以在 @RequestParam(value = “userName”,required = false) 中添加一個(gè) required = false 的設(shè)置。這是一種最理想的異常解決方案。

3. Spring MVC 的異常處理方案

3.1 將異常映射成狀態(tài)碼

Spring MVC 內(nèi)部提供了很多優(yōu)雅的異常處理機(jī)制。其中之一就是把不同的異常映射成 HTTP 狀態(tài)碼。

如下面實(shí)例:

  1. 首先定義一個(gè)異常類:
@ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "數(shù)字范圍不符合要求?。ú荒苁?20)")
public class NumberException extends RuntimeException {	
}
  1. 如果在方法中拋出的異常已經(jīng)被映射成了狀態(tài)嗎。則在瀏覽器中顯示出來的異常信息會(huì)明確很多。
@RequestMapping("/exception")
public String test(@RequestParam("num") int num) {
	if (num == 20) {
		throw new NumberException();
	}
		return "success";
}

在瀏覽器中輸入 http://localhost:8888/sm-demo/exception?num=13 ??梢钥吹剑?/p>

圖片描述

定制化的信息已經(jīng)有所改善,但是,還是不夠友好。

3.2 全局異常處理器

Spring MVC 提供了名為 SimpleMappingExceptionResolver 的異常處理組件,該組件實(shí)現(xiàn)了 HandlerExceptionResolver 接口,或者說實(shí)現(xiàn)了這個(gè)接口的對(duì)象都可稱其為全局異常處理器。

何謂全局異常處理器?

通俗講,有點(diǎn)類似于前端控制器的設(shè)計(jì)思路。Spring MVC 把所有異常分離出來后通通交給全局異常處理器做集中處理。

使用流程:

  1. 打開項(xiàng)目中的 WebConfig 配置類,添加組件;
@Bean
public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
	SimpleMappingExceptionResolver simResolver=new SimpleMappingExceptionResolver();
	//異常處理頁面
	simResolver.setDefaultErrorView("error");
	//封裝異常信息的屬性名,默認(rèn)是 exception
	simResolver.setExceptionAttribute("exception");
    //添加自定義異常信息
	Properties mappings=new Properties();
	mappings.put("com.mk.web.exception.MyException", "/WEB-INF/jsp/exception.jsp");
	simResolver.setExceptionMappings(mappings);
	return simResolver;
}

代碼中有注解,不再多言。

  1. 自定義異常類。自定義異常類并不是必須的,項(xiàng)目中自定義異常的目的可以讓異常的語義更具體;
public class MyException extends Exception {
   public MyException() {	
   }
   public MyException(String msg) {
   	super(msg);
   }
}
  1. 編寫控制器。控制器中的方法會(huì)根據(jù) userName 的值決定是否拋出異常。
   @RequestMapping("/exception03")
   public String exception03(String userName) throws MyException {
   	if (StringUtils.isEmpty(userName)) {
   		throw new MyException("用戶名不能為空");
   	}
   	return "index";
   }
  1. 測(cè)試。打開瀏覽器,輸入 http://localhost:8888/sm-demo/exception03 ;
  2. 瀏覽器會(huì)顯示把錯(cuò)誤導(dǎo)向到 “WEB-INF/exception.jsp” 頁面。此頁面,可添加下面的代碼。
   <body>
   出錯(cuò)啦!${exception.message}
   </body> 

解析出錯(cuò)誤的具體信息,最后可以在瀏覽器中看到:

圖片描述

開發(fā)者可以根據(jù)需要編寫自己的全局異常處理器組件。

3.3 與異常有關(guān)的注解

Spring MVC 還可以使用注解的方式集中處理異常。

@ExceptionHandler 注解:

此注解所標(biāo)注的方法能夠處理同一個(gè)控制器中所有方法所拋出的異常。

如下面實(shí)例:

@ExceptionHandler(Exception.class)
public String exception() {
	return "exception";
}
@RequestMapping("/exception04")
public String exception04(String userName) throws Exception {
	if (StringUtils.isEmpty(userName)) {
		throw new Exception("用戶名不能為空");
	}
	return "index";
}

當(dāng)控制器中的方法拋出異常后,會(huì)由 exception() 方法統(tǒng)一捕獲,然后跳到指定頁面。

@ControllerAdvice 注解:

此注解放在類的前面,且類中可以包含一個(gè)或多個(gè)如下類型的方法。

Tips: 由 @ControllerAdvice 注解標(biāo)注的類本質(zhì)上就是一個(gè)基于 AOP 思想的攔截器。

  • @ExceptionHandler 注解標(biāo)注的方法;
  • @InitBinder 注解標(biāo)注的方法;
  • @ModelAttribute 注解標(biāo)注的方法。

@ControllerAdvice 實(shí)現(xiàn)案例如下:

@ControllerAdvice
public class ExceptionAdviceAction {
	@ExceptionHandler(Exception.class)
	public String exception() {
		return "exception";
	}
}

無論哪一個(gè)控制器中拋出異常,都會(huì)由 ExceptionAdviceAction 類中的 exception() 方法統(tǒng)一響應(yīng)處理。

4. 小結(jié)

本章節(jié)和大家講解了 Spring MVC 中如何優(yōu)雅的處理異常。主要有 3 種方案:

  • 將異常映射成為 HTTP 狀態(tài)碼;
  • 使用全局異常處理組件。建議大家使用這種方式,具有很多的隔離性、統(tǒng)一性;
  • 使用注解的方式處理異常。