Spring中@RestControllerAdvice注解的使用詳解
一、@RestControllerAdvice是什么
@RestControllerAdvice是一個組合注解,由@ControllerAdvice、@ResponseBody組成,而@ControllerAdvice繼承了@Component,因此@RestControllerAdvice本質(zhì)上是個Component,用于定義@ExceptionHandler,@InitBinder和@ModelAttribute方法,適用于所有使用@RequestMapping方法。


二、@RestControllerAdvice的特點
1、注解了@RestControllerAdvice的類的方法可以使用@ExceptionHandler、@InitBinder、@ModelAttribute注解到方法上。
2、@RestControllerAdvice注解將作用在所有注解了@RequestMapping的控制器的方法上。
3、@ExceptionHandler:用于指定異常處理方法。當(dāng)與@RestControllerAdvice配合使用時,用于全局處理控制器里的異常。
4、@InitBinder:用來設(shè)置WebDataBinder,用于自動綁定前臺請求參數(shù)到Model中。
5、@ModelAttribute:本來作用是綁定鍵值對到Model中,當(dāng)與@RestControllerAdvice配合使用時,可以讓全局的@RequestMapping都能獲得在此處設(shè)置的鍵值對
@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,那么 " " 會被轉(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("請求地址'{}',權(quán)限碼校驗失敗'{}'", requestURI, e.getMessage());
return AjaxResult.error(HttpStatus.FORBIDDEN, "沒有訪問權(quán)限,請聯(lián)系管理員授權(quán)");
}
// 全局?jǐn)?shù)據(jù)綁定
// 應(yīng)用到所有@RequestMapping注解方法
// 此處將鍵值對添加到全局,注解了@RequestMapping的方法都可以獲得此鍵值對
@ModelAttribute
public void addUser(Model model) {
model.addAttribute("msg", "此處將鍵值對添加到全局,注解了@RequestMapping的方法都可以獲得此鍵值對");
}
}@ControllerAdvice可以指定 Controller 范圍
basePackages: 指定一個或多個包,這些包及其子包下的所有 Controller 都被該 @ControllerAdvice 管理
@RestControllerAdvice(basePackages={"com.alibaba"})
@Slf4j
public class ExceptionHandlerAdvice {
@ExceptionHandler(Exception.class)
public String handleException(Exception e) {
return "error";
}
} basePackageClasses: 是 basePackages 的一種變形,指定一個或多個 Controller 類,這些類所屬的包及其子包下的所有 Controller 都被該 @ControllerAdvice 管理
@RestControllerAdvice(basePackageClasses={TestController.class})
@Slf4j
public class ExceptionHandlerAdvice {
@ExceptionHandler(Exception.class)
public String handleException(Exception e) {
return "error";
}
} assignableTypes: 指定一個或多個 Controller 類,這些類被該 @ControllerAdvice 管理
@RestControllerAdvice(assignableTypes={TestController.class})
@Slf4j
public class ExceptionHandlerAdvice {
@ExceptionHandler(Exception.class)
public String handleException(Exception e) {
return "error";
}
} annotations: 指定一個或多個注解,被這些注解所標(biāo)記的 Controller 會被該 @ControllerAdvice 管理
@ControllerAdvice(annotations = {TestAnnotation.class})
@Slf4j
public class ExceptionHandlerAdvice {
@ExceptionHandler(Exception.class)
public String handleException(Exception e) {
return "error";
}
} 三、@ExceptionHandler
1、根據(jù)不同業(yè)務(wù)場景自定義返回碼
/**
* 返回狀態(tài)碼
*
* @author
*/
public class HttpStatus
{
/**
* 操作成功
*/
public static final int SUCCESS = 200;
/**
* 對象創(chuàng)建成功
*/
public static final int CREATED = 201;
/**
* 請求已經(jīng)被接受
*/
public static final int ACCEPTED = 202;
/**
* 操作已經(jīng)執(zhí)行成功,但是沒有返回數(shù)據(jù)
*/
public static final int NO_CONTENT = 204;
/**
* 資源已被移除
*/
public static final int MOVED_PERM = 301;
/**
* 重定向
*/
public static final int SEE_OTHER = 303;
/**
* 資源沒有被修改
*/
public static final int NOT_MODIFIED = 304;
/**
* 參數(shù)列表錯誤(缺少,格式不匹配)
*/
public static final int BAD_REQUEST = 400;
/**
* 未授權(quán)
*/
public static final int UNAUTHORIZED = 401;
/**
* 訪問受限,授權(quán)過期
*/
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)部錯誤
*/
public static final int ERROR = 500;
/**
* 接口未實現(xiàn)
*/
public static final int NOT_IMPLEMENTED = 501;
}2、根據(jù)不同的業(yè)務(wù)場景定制異常
/**
* 未能通過的權(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ù)流程中拋出定制異常
/**
* 驗證用戶是否具備某權(quán)限, 如果驗證未通過,則拋出異常: 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("請求地址'{}',權(quán)限碼校驗失敗'{}'", requestURI, e.getMessage());
return AjaxResult.error(HttpStatus.FORBIDDEN, "沒有訪問權(quán)限,請聯(lián)系管理員授權(quán)");
}
}四、@InitBinder
@InitBinder從字面意思可以看出這個的作用是給Binder做初始化的,@InitBinder主要用在@Controller中標(biāo)注于方法上(@RestController也算),表示初始化當(dāng)前控制器的數(shù)據(jù)綁定器(或者屬性綁定器),只對當(dāng)前的Controller有效。@InitBinder標(biāo)注的方法必須有一個參數(shù)WebDataBinder。所謂的屬性編輯器可以理解就是幫助我們完成參數(shù)綁定,然后是在請求到達(dá)controller要執(zhí)行方法前執(zhí)行!
用法如下:
@InitBinder
private void initBinder(WebDataBinder binder) {
// 可用于自定義參數(shù)校驗,然后通過addValidators來進(jìn)行綁定controller
binder.addValidators(userValidator);
// 可用于注冊 屬性編譯器
binder.registerCustomEditor(String.class,new StringTrimmerEditor(true));
}WebDataBinder到底是干嘛的?
在Servlet中,有一個方法:request.getParameter("paramName"),它會根據(jù)key返回一個String類型的數(shù)據(jù),從而獲取到前端傳遞過來的請求參數(shù)。但是如果我們這樣一個一個地去取出Web請求中的所有參數(shù),就會很麻煩。我們知道Java中有對象的概念,那有沒有辦法將request中的請求參數(shù)都自動封裝到一個Java對象中呢?為了解決這個問題,SpringMVC中就引入了WebDataBinder的概念。
WebDataBinder的作用是從Web 請求中,把請求里的參數(shù)都綁定到對應(yīng)的JavaBean上!在Controller方法中的參數(shù)類型可以是基本類型,也可以是封裝后的普通Java類型。若這個普通的Java類型沒有聲明任何注解,則意味著它的每一個屬性都需要到Request中去查找對應(yīng)的請求參數(shù),而WebDataBinder則可以幫助我們實現(xiàn)從Request中取出請求參數(shù)并綁定到JavaBean中。
到此這篇關(guān)于Spring中@RestControllerAdvice注解的使用詳解的文章就介紹到這了,更多相關(guān)@RestControllerAdvice注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Spring注解@RestControllerAdvice原理解析
- springboot @Controller和@RestController的區(qū)別及應(yīng)用詳解
- SpringBoot http請求注解@RestController原理解析
- SpringBoot的@RestControllerAdvice作用詳解
- SpringBoot常用注解@RestControllerAdvice詳解
- Spring中的@RestController注解詳細(xì)解析
- Spring @RestController注解組合實現(xiàn)方法解析
- springboot中@RestController注解實現(xiàn)
- Spring中@RestController注解的使用實現(xiàn)
相關(guān)文章
詳解五種方式讓你在java中讀取properties文件內(nèi)容不再是難題
這篇文章主要介紹了詳解五種方式讓你在java中讀取properties文件內(nèi)容不再是難題 ,非常具有實用價值,需要的朋友可以參考下。2016-12-12
SpringBoot遠(yuǎn)程訪問redis服務(wù)器問題剖析
使用了SpringBoot的項目,在遠(yuǎn)程連接Redis服務(wù)器時,會遇倒一些小問題,下面通過本文給大家全面解析SpringBoot遠(yuǎn)程訪問redis服務(wù)器問題,需要的朋友參考下吧2017-04-04
解決DataInputStream?read不等于-1,socket文件傳輸只能傳輸一個文件無法傳輸多個問題
這篇文章主要介紹了解決DataInputStream?read不等于-1,socket文件傳輸只能傳輸一個文件無法傳輸多個問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08

