一、@RestControllerAdvice是什么?
@RestContrllerAdvice是一種組合注解,由@ControllerAdvice,@ResponseBody組成
@ControllerAdvice繼承了@Component,反過來,可以理解為@RestContrllerAdvice本質(zhì)上就是@Component
1.1 @Component是什么?
本質(zhì)上是一個(gè)類,泛指各種組件,就是說當(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é)果
沒有自定義返回結(jié)果之前

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

3.4.1 controller
@RestController
public class TestController {
@GetMapping("/test2")
public String test2() {
return "test2";
}
}
3.4.2 返回結(jié)果來
BaseResult返回結(jié)果類在上面,對(duì)應(yīng)需要導(dǎo)入json的jar也在上面文章來源:http://www.zghlxwxcb.cn/news/detail-778237.html
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層使用,如果你要指定類和包也可以文章來源地址http://www.zghlxwxcb.cn/news/detail-778237.html
4.1 指定注解
@RestControllerAdvice(
annotations = {RestController.class}
)
4.2 指定類
@RestControllerAdvice(
basePackageClasses = TestController.class
)
4.3 指定包
@RestControllerAdvice(
basePackages = "com.common.base.controller"
)
到了這里,關(guān)于springboot的@RestControllerAdvice作用和捕獲自定義異常返回自定義結(jié)果案例的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!