最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于Spring統(tǒng)一異常處理及說明

 更新時(shí)間:2022年09月30日 10:47:42   作者:融極  
這篇文章主要介紹了關(guān)于Spring統(tǒng)一異常處理及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

相關(guān)注解概述

通過使用@RestControllerAdvice或@ControllerAdvice定義統(tǒng)一的異常處理類,而不是在每個(gè)Controller中逐個(gè)定義;

  • @RestControllerAdvice:返回Json格式數(shù)據(jù);
  • @ControllerAdvice:返回視圖類型數(shù)據(jù);
  • @ResponseBody:和Controller方法上的用法一樣,會(huì)將方法中返回值轉(zhuǎn)換成Json格式后返回給客戶端;
  • @ExceptionHandler:用來定義函數(shù)針對(duì)的異常類型,最后將Exception對(duì)象和請(qǐng)求URL映射到返回結(jié)果中;用于注釋異常處理類,value屬性指定需要攔截的異常類型。
  • spring應(yīng)用啟動(dòng)后,被@ExceptionHandler、@InitBinder、@ModelAttribute注解的方法,都會(huì)作用在被@RequestMapping注解的方法上。
  • 全局捕獲異常的原理:使用AOP切面技術(shù)。
  • 用@RequestBody,就解決了JSon自動(dòng)綁定。

全局異常依賴包

由于全局捕獲異常使用的是AOP切面技術(shù),需要直接或間接導(dǎo)入aop的jar包。

<dependency>
?? ? ?<groupId>org.springframework.boot</groupId>
?? ? ?<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

示例

import com.terse.develop.utils.exception.AdminException;
import com.terse.develop.utils.exception.MsgResultException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.io.IOException;
import java.net.ConnectException;
import java.util.List;
import java.util.Set;

/**
?* 全局異常處理
?*/
@RestControllerAdvice
@ResponseBody
public class ExceptionHandlerController {

? ? private static final Logger logger = LoggerFactory.getLogger(ExceptionHandlerController1.class);

? ? public static void print(Exception ex) {
? ? ? ? logger.error(ex.toString());
? ? ? ? ex.printStackTrace();
? ? }

? ? //Http請(qǐng)求方式不支持
? ? @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
? ? public Exception HttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
? ? ? ? print(e);
? ? ? ? return new Exception("Http請(qǐng)求方式不支持");
? ? }

?? ?/**
? ? ?* MsgResultException、AdminException 均為自定義異常類
? ? ?*/
? ? @ExceptionHandler(value = {MsgResultException.class, AdminException.class})
? ? public Exception exception(Exception e) {
? ? ? ? print(e);
? ? ? ? if (e instanceof MsgResultException)
? ? ? ? ? ? //捕獲什么異常信息就返回給前端什么信息
? ? ? ? ? ? return new MsgResultException(((MsgResultException) e).getMsg());
? ? ? ? else
? ? ? ? ? ? //只返回給后端"請(qǐng)重試"
? ? ? ? ? ? return new AdminException("請(qǐng)重試");
? ? }

? ? //request Body 讀取異常
? ? @ExceptionHandler(value = HttpMessageNotReadableException.class)
? ? public Exception httpMessageNotReadableException(HttpMessageNotReadableException e) {
? ? ? ? print(e);
? ? ? ? return new Exception("請(qǐng)檢查數(shù)據(jù)是否正確");
? ? }

? ? //參數(shù)類型轉(zhuǎn)換異常
? ? @ExceptionHandler(value = MethodArgumentTypeMismatchException.class)
? ? public Exception getNumberException(MethodArgumentTypeMismatchException e) {
? ? ? ? print(e);
? ? ? ? return new Exception("String類型不能轉(zhuǎn)換成數(shù)字類型");
? ? }

? ? /**
? ? ?* 校驗(yàn)基本類型
? ? ?*/
? ? @ExceptionHandler(value = ConstraintViolationException.class)
? ? public Exception ConstraintViolationExceptionHandler(ConstraintViolationException ex) {
? ? ? ? Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
? ? ? ? String msg = null;
? ? ? ? for (ConstraintViolation<?> cvl : constraintViolations) {
? ? ? ? ? ? msg = cvl.getMessageTemplate();
? ? ? ? }
? ? ? ? logger.error(msg);
? ? ? ? return new Exception(msg);
? ? }

? ? //缺少參數(shù)異常
? ? @ExceptionHandler(value = ServletRequestBindingException.class)
? ? public Exception ServletRequestBindingException(ServletRequestBindingException e) {
? ? ? ? print(e);
? ? ? ? return new Exception("缺少參數(shù)");
? ? }

? ? /**
? ? ?* 校驗(yàn)對(duì)象類型
? ? ?*/
? ? @ExceptionHandler(value = BindException.class)
? ? public Exception BindExceptionHandler(BindException bindException) {
? ? ? ? List<FieldError> fieldErrors = bindException.getFieldErrors();
? ? ? ? String msg = null;
? ? ? ? for (FieldError fieldError : fieldErrors) {
? ? ? ? ? ? msg = fieldError.getDefaultMessage();
? ? ? ? }
? ? ? ? return new Exception(msg);
? ? }

? ? //請(qǐng)求異常
? ? @ExceptionHandler(value = ConnectException.class)
? ? public Exception connectException(ConnectException e) {
? ? ? ? print(e);
? ? ? ? return new Exception("服務(wù)器異常,請(qǐng)聯(lián)系管理員");
? ? }

? ? //IO流異常
? ? @ExceptionHandler(value = IOException.class)
? ? public Exception ioException(IOException e) {
? ? ? ? e.printStackTrace();
? ? ? ? return new Exception("IO流處理異常,請(qǐng)聯(lián)系管理員");
? ? }

}

@ExceptionHandler注解使用方法

基本使用方法

Spring的@ExceptionHandler可以用來統(tǒng)一處理方法拋出的異常

比如這樣:

@ExceptionHandler()
public String handleExeption2(Exception ex) {
? ? System.out.println("拋異常了:" + ex);
? ? ex.printStackTrace();
? ? String resultStr = "異常:默認(rèn)";
? ? return resultStr;
}

當(dāng)我們使用這個(gè)@ExceptionHandler注解時(shí),我們需要定義一個(gè)異常的處理方法,比如上面的handlerException2()方法,給這個(gè)方法加上@ExceptionHandler注解,這個(gè)方法就好處理被@RequestMapping注解方法拋出的異常。

注解的參數(shù)

@ExceptionHandler注解中可以添加參數(shù),參數(shù)是某個(gè)異常類的class,代表這個(gè)方法專門處理該類異常

比如:

@ExceptionHandler(NumberFormatException.class)
public String handleExeption(Exception ex) {
? ? System.out.println("拋異常了:" + ex);
? ? ex.printStackTrace();
? ? String resultStr = "異常:NumberFormatException";
? ? return resultStr;
}

此時(shí)注解的參數(shù)是NumberFormatException.class,表示只有方法拋出NumberFormatException時(shí),才會(huì)調(diào)用該方法。

異常類型就近原則

當(dāng)異常發(fā)生時(shí),Spring會(huì)選擇最接近拋出異常類型的處理方法。

比如之前提到的NumberFormatException,這個(gè)異常有父類RuntimeException,RuntimeException還有父類Exception,如果我們分別定義異常處理方法,@ExceptionHandler分別使用這三個(gè)異常作為參數(shù)

比如:

@ExceptionHandler(NumberFormatException.class)
public String handleExeption(Exception ex) {
? ? System.out.println("拋異常了:" + ex);
? ? ex.printStackTrace();
? ? String resultStr = "異常:NumberFormatException";
? ? return resultStr;
}
?
@ExceptionHandler()
public String handleExeption2(Exception ex) {
? ? System.out.println("拋異常了:" + ex);
? ? ex.printStackTrace();
? ? String resultStr = "異常:默認(rèn)";
? ? return resultStr;
}
?
@ExceptionHandler(RuntimeException.class)
public String handleExeption3(Exception ex) {
? ? System.out.println("拋異常了:" + ex);
? ? ex.printStackTrace();
? ? String resultStr = "異常:RuntimeException";
? ? return resultStr;
}

那么,當(dāng)代碼拋出NumberFormatException時(shí),調(diào)用的方法將是注解參數(shù)NumberFormatException.class的方法,也就是handleExeption(),而當(dāng)代碼拋出IndexOutOfBoundsException時(shí),調(diào)用的方法將是注解參數(shù)RuntimeException的方法,也就是handleExeption3()。

注解方法的返回值

標(biāo)識(shí)了@ExceptionHandler注解的方法,返回值類型和標(biāo)識(shí)了@RequestMapping的方法是統(tǒng)一的,可參見@RequestMapping的說明,比如默認(rèn)返回Spring的ModelAndView對(duì)象,也可以返回String,這時(shí)的String是ModelAndView的路徑,而不是字符串本身。

有些情況下我們會(huì)給標(biāo)識(shí)了@RequestMapping的方法添加@ResponseBody,比如使用Ajax的場(chǎng)景,直接返回字符串,異常處理類也可以如此操作,添加@ResponseBody注解后,可以直接返回字符串

比如這樣:

@ExceptionHandler(NumberFormatException.class)
@ResponseBody
public String handleExeption(Exception ex) {
? ? System.out.println("拋異常了:" + ex);
? ? ex.printStackTrace();
? ? String resultStr = "異常:NumberFormatException";
? ? return resultStr;
}

這樣的操作可以在執(zhí)行完方法后直接返回字符串本身。

注解使用錯(cuò)誤舉例

使用@ExceptionHandler時(shí)盡量不要使用相同的注解參數(shù)。

如果我們定義兩個(gè)處理相同異常的處理方法:

@ExceptionHandler(NumberFormatException.class)
@ResponseBody
public String handleExeption(Exception ex) {
? ? System.out.println("拋異常了:" + ex);
? ? ex.printStackTrace();
? ? String resultStr = "異常:NumberFormatException";
? ? return resultStr;
}
?
@ExceptionHandler(NumberFormatException.class)
@ResponseBody
public String handleExeption2(Exception ex) {
? ? System.out.println("拋異常了:" + ex);
? ? ex.printStackTrace();
? ? String resultStr = "異常:默認(rèn)";
? ? return resultStr;
}

兩個(gè)方法都處理NumberFormatException,這種定義方式編譯可以通過,而當(dāng)NumberFormatException真正被拋出時(shí)

Spring會(huì)給我們報(bào)錯(cuò):

java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class java.lang.NumberFormatException]: {public java.lang.String TestController.handleExeption(java.lang.Exception), public java.lang.String TestController.handleExeption2(java.lang.Exception)}
    at org.springframework.web.method.annotation.ExceptionHandlerMethodResolver.addExceptionMapping(ExceptionHandlerMethodResolver.java:102) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
...

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 解決java數(shù)值范圍以及float與double精度丟失的問題

    解決java數(shù)值范圍以及float與double精度丟失的問題

    下面小編就為大家?guī)硪黄鉀Qjava數(shù)值范圍以及float與double精度丟失的問題。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • Jar包反編譯修改代碼后重新打jar包圖文詳解

    Jar包反編譯修改代碼后重新打jar包圖文詳解

    這篇文章主要給大家介紹了關(guān)于Jar包反編譯修改代碼后重新打jar包的相關(guān)資料,JAR文件就是Java Archive(Java檔案文件),它是 Java的一種文檔格式,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • JVM Tomcat性能實(shí)戰(zhàn)(推薦)

    JVM Tomcat性能實(shí)戰(zhàn)(推薦)

    下面小編就為大家?guī)硪黄狫VM Tomcat性能實(shí)戰(zhàn)(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-05-05
  • java中struts 框架的實(shí)現(xiàn)

    java中struts 框架的實(shí)現(xiàn)

    本文給大家介紹的是java中struts 框架的實(shí)現(xiàn),有需要的小伙伴可以參考下。
    2015-06-06
  • MyBatis?Xml映射文件之字符串替換方式

    MyBatis?Xml映射文件之字符串替換方式

    這篇文章主要介紹了MyBatis?Xml映射文件之字符串替換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • springboot項(xiàng)目中統(tǒng)一時(shí)間格式處理方法

    springboot項(xiàng)目中統(tǒng)一時(shí)間格式處理方法

    JacksonConfiguration主要用于配置JSON的序列化和反序列化,而LocalDateTimeFormatter則用于處理請(qǐng)求和響應(yīng)中的LocalDateTime格式,這兩個(gè)配置項(xiàng)在SpringBoot項(xiàng)目中至關(guān)重要,確保數(shù)據(jù)格式的正確處理和傳輸
    2024-10-10
  • Java設(shè)計(jì)模式之單例設(shè)計(jì)模式解析

    Java設(shè)計(jì)模式之單例設(shè)計(jì)模式解析

    這篇文章主要介紹了Java設(shè)計(jì)模式之單例設(shè)計(jì)模式解析,設(shè)計(jì)模式是在大量的實(shí)踐中總結(jié)和理論化之后優(yōu)選的代碼結(jié)構(gòu)、編程風(fēng)格、以及解決問題的思考方式,設(shè)計(jì)模式免去我們自己再思考和摸索,需要的朋友可以參考下
    2023-11-11
  • Java 定時(shí)器的多種實(shí)現(xiàn)方式

    Java 定時(shí)器的多種實(shí)現(xiàn)方式

    本文介紹了Java中定時(shí)器的多種實(shí)現(xiàn)方式,有此需求的朋友可以根據(jù)實(shí)際選擇適合自己的方式
    2021-06-06
  • 對(duì)Netty組件的基本介紹

    對(duì)Netty組件的基本介紹

    這篇文章主要介紹了對(duì)Netty組件的基本介紹,Netty是基于Java NIO client-server的網(wǎng)絡(luò)應(yīng)用框架,使用Netty可以快速開發(fā)網(wǎng)絡(luò)應(yīng)用,本文涵蓋了netty開發(fā)中主要的組件的介紹,需要的朋友可以參考下
    2021-06-06
  • springboot接入微信app支付的方法

    springboot接入微信app支付的方法

    本文使用springboot集成微信支付服務(wù),包含微信統(tǒng)一支付訂單接口,以及支付回調(diào)接口等,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05

最新評(píng)論

胶南市| 青田县| 铜川市| 金昌市| 晋江市| 称多县| 洪湖市| 托克逊县| 东至县| 揭东县| 通许县| 武强县| 宁陕县| 新巴尔虎左旗| 洛川县| 舞阳县| 大埔区| 江北区| 黄冈市| 尼勒克县| 石屏县| 上栗县| 子长县| 桃园县| 哈尔滨市| 蓝田县| 阳城县| 淮北市| 荆州市| 修水县| 海门市| 卫辉市| 太白县| 阳谷县| 苏州市| 临夏县| 平安县| 北流市| 大新县| 阿勒泰市| 来安县|