欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot的@RestControllerAdvice作用詳解

 更新時(shí)間:2024年01月17日 09:30:08   作者:java-zh  
這篇文章主要介紹了SpringBoot的@RestControllerAdvice作用詳解,@RestContrllerAdvice是一種組合注解,由@ControllerAdvice,@ResponseBody組成,本質(zhì)上就是@Component,需要的朋友可以參考下

一、@RestControllerAdvice是什么?

@RestContrllerAdvice是一種組合注解,由@ControllerAdvice,@ResponseBody組成

@ControllerAdvice繼承了@Component,反過(guò)來(lái),可以理解為@RestContrllerAdvice本質(zhì)上就是@Component

1.1 @Component是什么?

本質(zhì)上是一個(gè)類,泛指各種組件,就是說(shuō)當(dāng)我們的類不屬于各種歸類的時(shí)候(不屬于@Controller,@Service等的時(shí)候),我們就可以使用@Component

作用就是實(shí)現(xiàn)bean注入,利用這個(gè)注解可以取代spring的xml配置文件

1.2 @Component案例

1.2.1 準(zhǔn)備的jar

 <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.75</version>
</dependency>

1.2.2 controller

@RestController
public class TestController {
    @Autowired
    private TestService testService;
    @GetMapping("/test3")
    public String test3() {
        return testService.test();
    }
}

1.2.3 接口

public interface TestService {
    String test();
}

1.2.4組件

@Component
public class TestServiceImpl implements TestService {
    @Autowired
    private ObjectMapper objectMapper;
    @Override
    public String test() {
        String b = null;
        try {
            b =  objectMapper.writeValueAsString("a");
            System.out.println(b);
        } catch (Exception e) {
        }
        return b;
    }
}

二、@RestControllerAdvice有什么作用?

  • 自定義客戶端返回格式
  • 捕獲客戶端返回異常

三、@RestControllerAdvice案例和使用場(chǎng)景

捕獲客戶端返回異常案例(自定義返回異常)

3.1 未自定義捕獲異常之前

3.2 自定義捕獲異常以后

3.3代碼實(shí)現(xiàn)自定義捕獲異常

3.3.1 自定義異常枚舉

public interface BaseCodeMsg {
    String getCode();
    String getMsg();
}
public enum PlatformExceptionMsgEnum implements BaseCodeMsg {
    /**
     * base平臺(tái)返回的異常信息
     */
    SELECT_NULL("000000001", "查詢數(shù)據(jù)為空"),
    INVOKE_IS_REJECT("00000002", "請(qǐng)求被拒絕"),
    ILLEGAL_ARGUMENT_FORMAT("000000003", "非法參數(shù)格式"),
    ILLEGAL_ARGUMENT("000000004","數(shù)據(jù)非法"),
    SYSTEM_EXCEPTION("000000005", "系統(tǒng)異常");
    /**
     * 錯(cuò)誤碼
     */
    private final String code;
    /**
     * 錯(cuò)誤信息
     */
    private final String msg;
    PlatformExceptionMsgEnum(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    @Override
    public String getCode() {
        return code;
    }
    @Override
    public String getMsg() {
        return msg;
    }
}

3.3.2 自定義平臺(tái)異常

public abstract class AbstractApiException extends RuntimeException{
    public AbstractApiException() {
    }
    public abstract String getCode();
    public abstract String getMsg();
}
public class PlatformException extends AbstractApiException {
    private String code;
    private String msg;
    public PlatformException(BaseCodeMsg baseCodeMsg) {
        code = baseCodeMsg.getCode();
        msg = baseCodeMsg.getMsg();
    }
    public static void throwException(BaseCodeMsg baseCodeMsg) {
        throw new PlatformException(baseCodeMsg.getCode(), baseCodeMsg.getMsg());
    }
    public static void throwException(BaseCodeMsg baseCodeMsg, String msg) {
        throw new PlatformException(baseCodeMsg.getCode(), StringUtils.isEmpty(baseCodeMsg.getMsg()) ? msg : baseCodeMsg.getMsg());
    }
    public static void throwException(String code, String msg) {
        throw new PlatformException(code, msg);
    }
    public static void throwException(String msg) {
        throw new PlatformException(PlatformExceptionMsgEnum.SYSTEM_EXCEPTION.getCode(), msg);
    }
    public PlatformException(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    @Override
    public String getCode() {
        return code;
    }
    @Override
    public String getMsg() {
        return msg;
    }
}

3.3.3 自定義返回類

@Data
public class BaseResult<T> implements Serializable {
    private static final long serialVersionUID = 1L;
    private String code;
    private String msg;
    private String traceId;
    private T data;
    public boolean isSuccess() {
        return PlatformExceptionMsgEnum.SUCCESS.getCode().equals(this.code);
    }
    public static BaseResult ok() {
        return restBaseResult((Object)null, PlatformExceptionMsgEnum.SUCCESS);
    }
    public static <T> BaseResult<T> ok(T data) {
        return restBaseResult(data, PlatformExceptionMsgEnum.SUCCESS);
    }
    public static BaseResult fail() {
        return restBaseResult((Object)null, PlatformExceptionMsgEnum.SYSTEM_ERROR);
    }
    public static BaseResult fail(BaseCodeMsg baseCodeMsg) {
        return restBaseResult((Object)null, baseCodeMsg);
    }
    public static BaseResult fail(String code, String msg) {
        return restBaseResult((Object)null, code, msg);
    }
    private static <T> BaseResult<T> restBaseResult(T data, BaseCodeMsg baseCodeMsg) {
        return restBaseResult(data, baseCodeMsg.getCode(), baseCodeMsg.getMsg());
    }
    private static <T> BaseResult<T> restBaseResult(T data, String code, String msg) {
        BaseResult<T> apiBaseResult = new BaseResult();
        apiBaseResult.setCode(code);
        apiBaseResult.setData(data);
        apiBaseResult.setMsg(msg);
        apiBaseResult.setTraceId(MDC.get("traceId"));
        return apiBaseResult;
    }
    public BaseResult() {
    }
}

3.3.4 controller層

@RestController
public class TestController {
    @GetMapping("/test")
    public void test() {
        PlatformException.throwException(PlatformExceptionMsgEnum.SYSTEM_EXCEPTION);
    }
}

3.3.5 @RestControllerAdvice

@RestControllerAdvice
@Configuration
public class GlobalExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    private MessageSource messageSource;
    /**
     * 捕獲全局異常類
     *
     * @param e
     * @return
     */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public BaseResult handle(MethodArgumentNotValidException e) {
        if (e.getBindingResult().hasErrors()) {
            String msg = ((ObjectError) e.getBindingResult().getAllErrors().get(0)).getDefaultMessage();
            return BaseResult.fail(PlatformExceptionMsgEnum.ILLEGAL_ARGUMENT.getCode(), this.getI18nMsg(msg));
        } else {
            log.info(e.getMessage(), e);
            return BaseResult.fail(PlatformExceptionMsgEnum.ILLEGAL_ARGUMENT.getCode(), this.getI18nMsg(PlatformExceptionMsgEnum.ILLEGAL_ARGUMENT.getMsg()));
        }
    }
    /**
     * 捕獲API調(diào)用接口的異常類
     *
     * @param e
     * @return
     */
    @ExceptionHandler(AbstractApiException.class)
    public BaseResult abstractApiException(AbstractApiException e) {
        return BaseResult.fail(e.getCode(), e.getMsg());
    }
    /**
     * 前端傳入的參數(shù)和后端傳入的參數(shù)接收不匹配
     *
     * @param e
     * @return
     */
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public BaseResult handle(HttpMessageNotReadableException e) {
        log.warn(e.getMessage(), e);
        return BaseResult.fail(PlatformExceptionMsgEnum.ILLEGAL_ARGUMENT_FORMAT.getCode(), this.getI18nMsg(PlatformExceptionMsgEnum.ILLEGAL_ARGUMENT_FORMAT.getMsg()));
    }
    /**
     * 子類異常(相當(dāng)于子類不能拋出比父類更廣泛異常)
     *
     * @param e
     * @return
     */
    @ExceptionHandler({UndeclaredThrowableException.class})
    public BaseResult handle(UndeclaredThrowableException e) {
        log.warn(e.getMessage(), e);
        return BaseResult.fail(PlatformExceptionMsgEnum.INVOKE_IS_REJECT.getCode(), this.getI18nMsg(PlatformExceptionMsgEnum.INVOKE_IS_REJECT.getMsg()));
    }
    /**
     * 異常捕獲
     *
     * @param e 捕獲的異常,封裝返回的對(duì)象
     * @return
     */
    @ExceptionHandler(Exception.class)
    public BaseResult handleException(Exception e) {
        log.warn(e.getMessage(), e);
        StringJoiner joiner = new StringJoiner(":");
        joiner.add(this.getI18nMsg(PlatformExceptionMsgEnum.INVOKE_IS_REJECT.getMsg())).add(e.getMessage());
        return BaseResult.fail(PlatformExceptionMsgEnum.SYSTEM_EXCEPTION.getCode(), joiner.toString());
    }
    private String getI18nMsg(String msg) {
        try {
            return this.messageSource.getMessage(msg, (Object[]) null, LocaleContextHolder.getLocale());
        } catch (NoSuchMessageException var3) {
            return msg;
        }
    }
    public GlobalExceptionHandler(MessageSource messageSource) {
        this.messageSource = messageSource;
    }
}

3.4 代碼實(shí)現(xiàn)自定義返回結(jié)果

沒(méi)有自定義返回結(jié)果之前

自定義返回結(jié)果以后

3.4.1 controller

@RestController
public class TestController {
    @GetMapping("/test2")
    public String test2() {
        return "test2";
    }
}

3.4.2 返回結(jié)果來(lái)

BaseResult返回結(jié)果類在上面,對(duì)應(yīng)需要導(dǎo)入json的jar也在上面

3.4.3 @RestControllerAdvice

@RestControllerAdvice(
        annotations = {RestController.class}
)
@Configuration
public class BaseResultResponseAdvice implements ResponseBodyAdvice<Object> {
    @Autowired
    private ObjectMapper objectMapper;
    /**
     * @param methodParameter 利用這個(gè)參數(shù)判斷注解信息
     * @param aClass
     * @return
     */
    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }
    /**
     * @param body               原controller需要返回的內(nèi)容
     * @param methodParameter    利用這個(gè)參數(shù)判斷注解信息
     * @param mediaType
     * @param aClass
     * @param serverHttpRequest
     * @param serverHttpResponse
     * @return
     */
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        try {
            if (methodParameter.getParameterType() == ResponseEntity.class) {
                return body;
            } else if (methodParameter.getParameterType() == BaseResult.class) {
                return body;
            } else if (methodParameter.getParameterType() == String.class) {
                serverHttpResponse.getHeaders().setContentType(MediaType.APPLICATION_JSON);
                return this.objectMapper.writeValueAsString(BaseResult.ok(body));
            } else {
                return BaseResult.ok(body);
            }
        } catch (Throwable t) {
            return BaseResult.fail();
        }
    }
}

四、拓展

@RestControllerAdvice的使用還可以指定對(duì)應(yīng)的注解、包,類。比如你需要返回自定義結(jié)果格式,可以指定@RestController層使用,如果你要指定類和包也可以

4.1 指定注解

@RestControllerAdvice(
        annotations = {RestController.class}
)

4.2 指定類

@RestControllerAdvice(
        basePackageClasses = TestController.class
)

4.3 指定包

@RestControllerAdvice(
        basePackages = "com.common.base.controller"
)

到此這篇關(guān)于SpringBoot的@RestControllerAdvice作用詳解的文章就介紹到這了,更多相關(guān)@RestControllerAdvice作用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Boot如何移除內(nèi)嵌Tomcat,使用非web方式啟動(dòng)

    Spring Boot如何移除內(nèi)嵌Tomcat,使用非web方式啟動(dòng)

    這篇文章主要介紹了Spring Boot如何移除內(nèi)嵌Tomcat,使用非web方式啟動(dòng),幫助大家更好的理解和學(xué)習(xí)使用spring boot框架,感興趣的朋友可以了解下
    2021-02-02
  • java工具類static靜態(tài)方法讀取yml配置過(guò)程

    java工具類static靜態(tài)方法讀取yml配置過(guò)程

    文章介紹了在工具類中獲取YAML配置時(shí)遇到的問(wèn)題,由于變量是靜態(tài)的,而Spring加載靜態(tài)方法比IOC容器早,導(dǎo)致無(wú)法直接使用@Value注解讀取YAML配置,從而讀取結(jié)果為null
    2024-11-11
  • SpringBoot中的Lombok庫(kù)及使用舉例詳解

    SpringBoot中的Lombok庫(kù)及使用舉例詳解

    Lombok是一個(gè)Java庫(kù),通過(guò)注解的方式簡(jiǎn)化代碼編寫(xiě),減少樣板代碼,它能夠自動(dòng)生成getter、setter、構(gòu)造函數(shù)、toString等方法,提升開(kāi)發(fā)效率,這篇文章主要介紹了SpringBoot中的Lombok庫(kù),需要的朋友可以參考下
    2025-05-05
  • java音頻播放示例分享(java如何播放音頻)

    java音頻播放示例分享(java如何播放音頻)

    java如何播放音頻?下面的代碼就介紹了java音頻播放示例,需要的朋友可以參考下
    2014-04-04
  • Java 普通代碼塊靜態(tài)代碼塊執(zhí)行順序(實(shí)例講解)

    Java 普通代碼塊靜態(tài)代碼塊執(zhí)行順序(實(shí)例講解)

    下面小編就為大家?guī)?lái)一篇Java 普通代碼塊靜態(tài)代碼塊執(zhí)行順序(實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • SpringBoot項(xiàng)目使用mybatis-plus代碼生成的實(shí)例詳解

    SpringBoot項(xiàng)目使用mybatis-plus代碼生成的實(shí)例詳解

    mybatis-plus是mybatis的增強(qiáng),不對(duì)mybatis做任何改變,涵蓋了代碼生成,自定義ID生成器,快速實(shí)現(xiàn)CRUD,自動(dòng)分頁(yè),邏輯刪除等功能。本文就來(lái)講講SpringBoot項(xiàng)目如何使用mybatis-plus實(shí)現(xiàn)代碼生成,需要的可以了解一下
    2022-10-10
  • SpringBoot 分布式驗(yàn)證碼登錄方案示例詳解

    SpringBoot 分布式驗(yàn)證碼登錄方案示例詳解

    為了防止驗(yàn)證系統(tǒng)被暴力破解,很多系統(tǒng)都增加了驗(yàn)證碼效驗(yàn),比較常見(jiàn)的就是圖片二維碼,業(yè)內(nèi)比較安全的是短信驗(yàn)證碼,當(dāng)然還有一些拼圖驗(yàn)證碼,加入人工智能的二維碼等等,我們今天的主題就是前后端分離的圖片二維碼登錄方案,感興趣的朋友一起看看吧
    2023-10-10
  • java IO實(shí)現(xiàn)電腦搜索、刪除功能的實(shí)例

    java IO實(shí)現(xiàn)電腦搜索、刪除功能的實(shí)例

    下面小編就為大家?guī)?lái)一篇java IO實(shí)現(xiàn)電腦搜索、刪除功能的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12
  • SpringBoot3.3.0升級(jí)方案

    SpringBoot3.3.0升級(jí)方案

    本文介紹了由SpringBoot2升級(jí)到SpringBoot3.3.0升級(jí)方案,新版本的升級(jí)可以解決舊版本存在的部分漏洞問(wèn)題,感興趣的可以了解一下
    2024-08-08
  • java異常處理throws完成異常拋出詳解

    java異常處理throws完成異常拋出詳解

    這篇文章主要介紹了java異常處理中throws完成異常拋出示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家學(xué)有所得多多進(jìn)步
    2021-10-10

最新評(píng)論