Spring中@RestControllerAdvice注解的使用詳解
一、@RestControllerAdvice是什么
@RestControllerAdvice是一個(gè)組合注解,由@ControllerAdvice、@ResponseBody組成,而@ControllerAdvice繼承了@Component,因此@RestControllerAdvice本質(zhì)上是個(gè)Component,用于定義@ExceptionHandler,@InitBinder和@ModelAttribute方法,適用于所有使用@RequestMapping方法。
二、@RestControllerAdvice的特點(diǎn)
1、注解了@RestControllerAdvice的類的方法可以使用@ExceptionHandler、@InitBinder、@ModelAttribute注解到方法上。
2、@RestControllerAdvice注解將作用在所有注解了@RequestMapping的控制器的方法上。
3、@ExceptionHandler:用于指定異常處理方法。當(dāng)與@RestControllerAdvice配合使用時(shí),用于全局處理控制器里的異常。
4、@InitBinder:用來(lái)設(shè)置WebDataBinder,用于自動(dòng)綁定前臺(tái)請(qǐng)求參數(shù)到Model中。
5、@ModelAttribute:本來(lái)作用是綁定鍵值對(duì)到Model中,當(dāng)與@RestControllerAdvice配合使用時(shí),可以讓全局的@RequestMapping都能獲得在此處設(shè)置的鍵值對(duì)
@RestControllerAdvice public class GlobalControllerAdivice { private static final Logger log = LoggerFactory.getLogger(GlobalControllerAdivice.class); @InitBinder public void dataBind(WebDataBinder binder) { // 構(gòu)造方法中 boolean 參數(shù)含義為如果是空白字符串,是否轉(zhuǎn)換為 null // 即如果為 true,那么 " " 會(huì)被轉(zhuǎn)換為 null,否者為"" binder.registerCustomEditor(String.class, new StringTrimmerEditor(true)); } /** * 權(quán)限碼異常 */ @ExceptionHandler(NotPermissionException.class) public AjaxResult handleNotPermissionException(NotPermissionException e, HttpServletRequest request) { String requestURI = request.getRequestURI(); log.error("請(qǐng)求地址'{}',權(quán)限碼校驗(yàn)失敗'{}'", requestURI, e.getMessage()); return AjaxResult.error(HttpStatus.FORBIDDEN, "沒(méi)有訪問(wèn)權(quán)限,請(qǐng)聯(lián)系管理員授權(quán)"); } // 全局?jǐn)?shù)據(jù)綁定 // 應(yīng)用到所有@RequestMapping注解方法 // 此處將鍵值對(duì)添加到全局,注解了@RequestMapping的方法都可以獲得此鍵值對(duì) @ModelAttribute public void addUser(Model model) { model.addAttribute("msg", "此處將鍵值對(duì)添加到全局,注解了@RequestMapping的方法都可以獲得此鍵值對(duì)"); } }
@ControllerAdvice可以指定 Controller 范圍
basePackages: 指定一個(gè)或多個(gè)包,這些包及其子包下的所有 Controller 都被該 @ControllerAdvice 管理
@RestControllerAdvice(basePackages={"com.alibaba"}) @Slf4j public class ExceptionHandlerAdvice { @ExceptionHandler(Exception.class) public String handleException(Exception e) { return "error"; } }
basePackageClasses: 是 basePackages 的一種變形,指定一個(gè)或多個(gè) Controller 類,這些類所屬的包及其子包下的所有 Controller 都被該 @ControllerAdvice 管理
@RestControllerAdvice(basePackageClasses={TestController.class}) @Slf4j public class ExceptionHandlerAdvice { @ExceptionHandler(Exception.class) public String handleException(Exception e) { return "error"; } }
assignableTypes: 指定一個(gè)或多個(gè) Controller 類,這些類被該 @ControllerAdvice 管理
@RestControllerAdvice(assignableTypes={TestController.class}) @Slf4j public class ExceptionHandlerAdvice { @ExceptionHandler(Exception.class) public String handleException(Exception e) { return "error"; } }
annotations: 指定一個(gè)或多個(gè)注解,被這些注解所標(biāo)記的 Controller 會(huì)被該 @ControllerAdvice 管理
@ControllerAdvice(annotations = {TestAnnotation.class}) @Slf4j public class ExceptionHandlerAdvice { @ExceptionHandler(Exception.class) public String handleException(Exception e) { return "error"; } }
三、@ExceptionHandler
1、根據(jù)不同業(yè)務(wù)場(chǎng)景自定義返回碼
/** * 返回狀態(tài)碼 * * @author */ public class HttpStatus { /** * 操作成功 */ public static final int SUCCESS = 200; /** * 對(duì)象創(chuàng)建成功 */ public static final int CREATED = 201; /** * 請(qǐng)求已經(jīng)被接受 */ public static final int ACCEPTED = 202; /** * 操作已經(jīng)執(zhí)行成功,但是沒(méi)有返回?cái)?shù)據(jù) */ public static final int NO_CONTENT = 204; /** * 資源已被移除 */ public static final int MOVED_PERM = 301; /** * 重定向 */ public static final int SEE_OTHER = 303; /** * 資源沒(méi)有被修改 */ public static final int NOT_MODIFIED = 304; /** * 參數(shù)列表錯(cuò)誤(缺少,格式不匹配) */ public static final int BAD_REQUEST = 400; /** * 未授權(quán) */ public static final int UNAUTHORIZED = 401; /** * 訪問(wèn)受限,授權(quán)過(guò)期 */ public static final int FORBIDDEN = 403; /** * 資源,服務(wù)未找到 */ public static final int NOT_FOUND = 404; /** * 不允許的http方法 */ public static final int BAD_METHOD = 405; /** * 資源沖突,或者資源被鎖 */ public static final int CONFLICT = 409; /** * 不支持的數(shù)據(jù),媒體類型 */ public static final int UNSUPPORTED_TYPE = 415; /** * 系統(tǒng)內(nèi)部錯(cuò)誤 */ public static final int ERROR = 500; /** * 接口未實(shí)現(xiàn) */ public static final int NOT_IMPLEMENTED = 501; }
2、根據(jù)不同的業(yè)務(wù)場(chǎng)景定制異常
/** * 未能通過(guò)的權(quán)限認(rèn)證異常 * * @author */ public class NotPermissionException extends RuntimeException { private static final long serialVersionUID = 1L; public NotPermissionException(String permission) { super(permission); } public NotPermissionException(String[] permissions) { super(StringUtils.join(permissions, ",")); } }
3、業(yè)務(wù)流程中拋出定制異常
/** * 驗(yàn)證用戶是否具備某權(quán)限, 如果驗(yàn)證未通過(guò),則拋出異常: NotPermissionException * * @param permission 權(quán)限字符串 * @return 用戶是否具備某權(quán)限 */ public void checkPermi(String permission) { if (!hasPermi(getPermiList(), permission)) { throw new NotPermissionException(permission); } }
4、定制全局異常處理器處理各種異常
/** * 全局異常處理器 * * @author */ @RestControllerAdvice public class GlobalExceptionHandler { private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); /** * 權(quán)限碼異常 */ @ExceptionHandler(NotPermissionException.class) public AjaxResult handleNotPermissionException(NotPermissionException e, HttpServletRequest request) { String requestURI = request.getRequestURI(); log.error("請(qǐng)求地址'{}',權(quán)限碼校驗(yàn)失敗'{}'", requestURI, e.getMessage()); return AjaxResult.error(HttpStatus.FORBIDDEN, "沒(méi)有訪問(wèn)權(quán)限,請(qǐng)聯(lián)系管理員授權(quán)"); } }
四、@InitBinder
@InitBinder從字面意思可以看出這個(gè)的作用是給Binder做初始化的,@InitBinder主要用在@Controller中標(biāo)注于方法上(@RestController也算),表示初始化當(dāng)前控制器的數(shù)據(jù)綁定器(或者屬性綁定器),只對(duì)當(dāng)前的Controller有效。@InitBinder標(biāo)注的方法必須有一個(gè)參數(shù)WebDataBinder。所謂的屬性編輯器可以理解就是幫助我們完成參數(shù)綁定,然后是在請(qǐng)求到達(dá)controller要執(zhí)行方法前執(zhí)行!
用法如下:
@InitBinder private void initBinder(WebDataBinder binder) { // 可用于自定義參數(shù)校驗(yàn),然后通過(guò)addValidators來(lái)進(jìn)行綁定controller binder.addValidators(userValidator); // 可用于注冊(cè) 屬性編譯器 binder.registerCustomEditor(String.class,new StringTrimmerEditor(true)); }
WebDataBinder到底是干嘛的?
在Servlet中,有一個(gè)方法:request.getParameter("paramName"),它會(huì)根據(jù)key返回一個(gè)String類型的數(shù)據(jù),從而獲取到前端傳遞過(guò)來(lái)的請(qǐng)求參數(shù)。但是如果我們這樣一個(gè)一個(gè)地去取出Web請(qǐng)求中的所有參數(shù),就會(huì)很麻煩。我們知道Java中有對(duì)象的概念,那有沒(méi)有辦法將request中的請(qǐng)求參數(shù)都自動(dòng)封裝到一個(gè)Java對(duì)象中呢?為了解決這個(gè)問(wèn)題,SpringMVC中就引入了WebDataBinder的概念。
WebDataBinder的作用是從Web 請(qǐng)求中,把請(qǐng)求里的參數(shù)都綁定到對(duì)應(yīng)的JavaBean上!在Controller方法中的參數(shù)類型可以是基本類型,也可以是封裝后的普通Java類型。若這個(gè)普通的Java類型沒(méi)有聲明任何注解,則意味著它的每一個(gè)屬性都需要到Request中去查找對(duì)應(yīng)的請(qǐng)求參數(shù),而WebDataBinder則可以幫助我們實(shí)現(xiàn)從Request中取出請(qǐng)求參數(shù)并綁定到JavaBean中。
到此這篇關(guān)于Spring中@RestControllerAdvice注解的使用詳解的文章就介紹到這了,更多相關(guān)@RestControllerAdvice注解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決java.util.NoSuchElementException異常正確方法
java.util.NoSuchElementException是Java中的一種異常,表示在迭代器或枚舉中找不到元素,這篇文章主要給大家介紹了關(guān)于解決java.util.NoSuchElementException異常的相關(guān)資料,需要的朋友可以參考下2023-11-11springboot寶塔簡(jiǎn)單部署的實(shí)現(xiàn)示例
通過(guò)使用Spring Boot,可以快速構(gòu)建出高效、可擴(kuò)展的應(yīng)用程序,而寶塔面板則提供了簡(jiǎn)單易用的網(wǎng)站管理和維護(hù)工具,本文將詳細(xì)介紹如何將Spring Boot應(yīng)用程序與寶塔面板進(jìn)行集成,實(shí)現(xiàn)自動(dòng)化部署、配置管理等操作2023-11-11關(guān)于使用Lambda表達(dá)式簡(jiǎn)化Comparator的使用問(wèn)題
這篇文章主要介紹了關(guān)于使用Lambda表達(dá)式簡(jiǎn)化Comparator的使用問(wèn)題,文中圖文講解了Comparator對(duì)象的方法,需要的朋友可以參考下2023-04-04Java TimeoutException:服務(wù)調(diào)用超時(shí)異常的正確解決方案
在現(xiàn)代軟件開(kāi)發(fā)中,服務(wù)間通信是構(gòu)建分布式系統(tǒng)的基礎(chǔ),然而,網(wǎng)絡(luò)延遲、服務(wù)負(fù)載、資源競(jìng)爭(zhēng)等因素都可能導(dǎo)致服務(wù)調(diào)用超時(shí),TimeoutException是Java中表示服務(wù)調(diào)用超時(shí)的常見(jiàn)異常之一,本文將探討TimeoutException的成因及解決方案,需要的朋友可以參考下2024-12-12Java后端服務(wù)間歇性響應(yīng)慢的問(wèn)題排查與解決
之前在公司內(nèi)其它團(tuán)隊(duì)找到幫忙排查的一個(gè)后端服務(wù)連接超時(shí)問(wèn)題,問(wèn)題的表現(xiàn)是服務(wù)部署到線上后出現(xiàn)間歇性請(qǐng)求響應(yīng)非常慢(大于10s),但是后端業(yè)務(wù)分析業(yè)務(wù)日志時(shí)卻沒(méi)有發(fā)現(xiàn)慢請(qǐng)求,所以本文給大家介紹了Java后端服務(wù)間歇性響應(yīng)慢的問(wèn)題排查與解決,需要的朋友可以參考下2025-03-03MyEclipse去除網(wǎng)上復(fù)制下來(lái)的代碼帶有的行號(hào)(正則去除行號(hào))
這篇文章主要介紹了MyEclipse去除網(wǎng)上復(fù)制下來(lái)的代碼帶有的行號(hào)(正則去除行號(hào))的相關(guān)資料,需要的朋友可以參考下2017-10-10java出現(xiàn)no XXX in java.library.path的解決及eclipse配
這篇文章主要介紹了java出現(xiàn)no XXX in java.library.path的解決及eclipse配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12