基于@RestControllerAdvice与@ControllerAdvice的区别说明

网友投稿 245 2022-12-05

基于@RestControllerAdvice与@ControllerAdvice的区别说明

目录@RestControllerAdvice与@ControllerAdvice的区别@ControllerAdvice注解的源码为@RestControllerAdvice注解的源码为@RestControllerAdvice @ControllerAdvice注解无效 通用异常处理启动类错误处理类

@RestControllerAdvice与@ControllerAdvice的区别

@RestControllerAdvice注解与@ControllerAdvice注解位于同一个依赖包下面,其pom依赖为:

org.springframework

spring-web

5.3.3

有时会发现在不同的项目中,全局异常处理部分,有的自定义类添加@RestControllerAdvice注解,有的自定义类添加@ControllerAdvice注解。

其实这两个注解的作用基本上是一致的,都是为了实现自定义全局异常处理,

唯一的区别是:@RestControllerAdvice注解包含了@ControllerAdvice注解和@ResponseBody注解。

@ControllerAdvice注解的源码为

@Target({ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Component

public @interface ControllerAdvice {

}

@RestControllerAdvice注解的源码为

@Target({ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@ControllerAdvice

@ResponseBody

public @interface RestControllerAdvice {

}

当自定义类加@ControllerAdvice注解时,方法需要返回json数据时,每个方法还需要添加@ResponseBody注解

当自定义类加@RestControllerAdvice注解时,方法自动返回json数据,每个方法无需再添加@ResponseBody注解

/**

* 全局异常处理类

*/

@RestControllerAdvice

@Slf4j

public class GlobalExceptionHandler {

@ExceptionHandler(Exception.class)

public Result ExceptionHandler(Exception e) {

log.error("出现异常:", e);

return Result.failed(e.getMessage());

}

}

@RestControllerAdvice @ControllerAdvice注解无效 通用异常处理

简单记录下,今天打算写一个公共异常处理切面,主要是将所有抛出的异常拦截,然后返回给前端的时候,统一是错误码,错误原因等。防止直接在前端抛出错误。

@RestControllerAdvice 或者 @ControllerAdvice 可以直接作为错误处理的切面对待。但是使用过程中发现这两个注解无效,原因是我将GlobalExceptionHandler定义在另一个包里面,@SpringBootApplication无法自动加载到该注解(springboot启动类的默认扫描路径是该类所在的包下面的所有java类。

如:启动类在“com.galen.cloud.portal”包下,那么只有com.galen.cloud.portal包下的类会被扫描加载)。所以添加上对应的scanBasePackages 即可(我这边改为扫描所有http://匹配com.galen.*的包):

启动类

package com.galen.cloud.portal;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(scanBasePackages = "com.galen.*")

public class galenPortalApplication {

public static void main(String[] args) {

SpringApplication.run(galenPortalApplication.class, args);

}

}

错误处理类

package com.galen.common.exception;

import com.galen.common.core.domain.R;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.core.annotation.AnnotationUtils;

import org.springframework.dao.DuplicateKeyException;

import org.springframework.http.HttpStatus;

import org.springframework.web.HttpRequestMethodNotSupportedException;

import org.springframework.web.bind.annotation.ExceptionHandler;

import org.springframework.web.bind.annotation.ResponseStatus;

import org.springframework.web.bind.annotation.RestControllerAdvice;

/**

* 异常处理器

* @author galen

*/

@RestControllerAdvice

public class GlobalExceptionHandler

{

private Logger logger = LoggerFactory.getLogger(getClass());

/**

* 请求方式不支持

*/

@ExceptionHandler({HttpRequestMethodNotSupportedException.class})

@ResponseStatus(code = HttpStatus.METHOD_NOT_ALLOWED)

public R handleException(HttpRequestMethodNotSupportedException e)

{

logger.error(e.getMessage(), e);

return R.error("不支持' " + e.getMethod() + "'请求");

}

/**

* 拦截未知的运行时异常

*/

@ExceptionHandler(RuntimeException.class)

public R notFount(RuntimeException e)

{

if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null)

{

throw e;

}

logger.error("运行时异常:", e);

return R.error("运行时异常:" + e.getMessage());

}

/**

* 处理自定义异常

*/

@ExceptionHandler(galenException.class)

public R handleWindException(galenException e)

{

return R.error(e.getCode(), e.getMessage());

}

@ExceptionHandler(DuplicateKeyException.class)

public R handleDuplicateKeyException(DuplicateKeyException e)

{

logger.error(e.getMessage(), e);

return R.error("数据库中已存在该记录");

}

@ExceptionHandler(Exception.class)

public R handleException(Exception e) throws Exception

{

logger.error(e.getMessage(), e);

return R.error("服务器错误,请联系管理员");

}

/**

* 捕获并处理未授权异常

*

* @param e 授权异常

* @return 统一封装的结果类, 含有代码code和提示信息msg

*/

@ExceptionHandler(UnauthorizedException.class)

public R handle401(UnauthorizedException e)

{

return R.error(401, e.getMessage());

}

// 验证码错误

@ExceptionHandler(ValidateCodeException.class)

public R handleCaptcha(ValidateCodeException e)

{

return R.error(e.getMessage());

}

}

最后拦截效果图如下:

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:使用RestTemplate 调用远程接口上传文件方式
下一篇:Java中的ThreadLocal详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~