Spring中@RestControllerAdvice注解的使用详解

 更新时间:2024年01月19日 10:22:45   作者:小七乀  
这篇文章主要介绍了Spring中@RestControllerAdvice注解的使用详解,@RestControllerAdvice是一个组合注解,由@ControllerAdvice、@ResponseBody组成,而@ControllerAdvice继承了@Component,需要的朋友可以参考下

一、@RestControllerAdvice是什么

@RestControllerAdvice是一个组合注解,由@ControllerAdvice、@ResponseBody组成,而@ControllerAdvice继承了@Component,因此@RestControllerAdvice本质上是个Component,用于定义@ExceptionHandler,@InitBinder和@ModelAttribute方法,适用于所有使用@RequestMapping方法。

二、@RestControllerAdvice的特点

1、注解了@RestControllerAdvice的类的方法可以使用@ExceptionHandler、@InitBinder、@ModelAttribute注解到方法上。

2、@RestControllerAdvice注解将作用在所有注解了@RequestMapping的控制器的方法上。

3、@ExceptionHandler:用于指定异常处理方法。当与@RestControllerAdvice配合使用时,用于全局处理控制器里的异常。

4、@InitBinder:用来设置WebDataBinder,用于自动绑定前台请求参数到Model中。

5、@ModelAttribute:本来作用是绑定键值对到Model中,当与@RestControllerAdvice配合使用时,可以让全局的@RequestMapping都能获得在此处设置的键值对

@RestControllerAdvice
public class GlobalControllerAdivice {
    private static final Logger log = LoggerFactory.getLogger(GlobalControllerAdivice.class);
    @InitBinder
    public void dataBind(WebDataBinder binder) {
        // 构造方法中 boolean 参数含义为如果是空白字符串,是否转换为 null
        // 即如果为 true,那么 " " 会被转换为 null,否者为""
        binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
    }
    /**
     * 权限码异常
     */
    @ExceptionHandler(NotPermissionException.class)
    public AjaxResult handleNotPermissionException(NotPermissionException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',权限码校验失败'{}'", requestURI, e.getMessage());
        return AjaxResult.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权");
    }
    // 全局数据绑定
    // 应用到所有@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: 指定一个或多个注解,被这些注解所标记的 Controller 会被该 @ControllerAdvice 管理

@ControllerAdvice(annotations = {TestAnnotation.class})
@Slf4j
public class ExceptionHandlerAdvice {
    @ExceptionHandler(Exception.class)    
    public String handleException(Exception e) {    
        return "error";
    } 
} 

三、@ExceptionHandler

1、根据不同业务场景自定义返回码

/**
 * 返回状态码
 * 
 * @author
 */
public class HttpStatus
{
    /**
     * 操作成功
     */
    public static final int SUCCESS = 200;
    /**
     * 对象创建成功
     */
    public static final int CREATED = 201;
    /**
     * 请求已经被接受
     */
    public static final int ACCEPTED = 202;
    /**
     * 操作已经执行成功,但是没有返回数据
     */
    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;
    /**
     * 参数列表错误(缺少,格式不匹配)
     */
    public static final int BAD_REQUEST = 400;
    /**
     * 未授权
     */
    public static final int UNAUTHORIZED = 401;
    /**
     * 访问受限,授权过期
     */
    public static final int FORBIDDEN = 403;
    /**
     * 资源,服务未找到
     */
    public static final int NOT_FOUND = 404;
    /**
     * 不允许的http方法
     */
    public static final int BAD_METHOD = 405;
    /**
     * 资源冲突,或者资源被锁
     */
    public static final int CONFLICT = 409;
    /**
     * 不支持的数据,媒体类型
     */
    public static final int UNSUPPORTED_TYPE = 415;
    /**
     * 系统内部错误
     */
    public static final int ERROR = 500;
    /**
     * 接口未实现
     */
    public static final int NOT_IMPLEMENTED = 501;
}

2、根据不同的业务场景定制异常

/**
 * 未能通过的权限认证异常
 * 
 * @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、业务流程中抛出定制异常

/**
	 * 验证用户是否具备某权限, 如果验证未通过,则抛出异常: NotPermissionException
	 * 
	 * @param permission 权限字符串
	 * @return 用户是否具备某权限
	 */
	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);
	/**
	 * 权限码异常
	 */
	@ExceptionHandler(NotPermissionException.class)
	public AjaxResult handleNotPermissionException(NotPermissionException e, HttpServletRequest request) {
		String requestURI = request.getRequestURI();
		log.error("请求地址'{}',权限码校验失败'{}'", requestURI, e.getMessage());
		return AjaxResult.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权");
	}
}

四、@InitBinder

@InitBinder从字面意思可以看出这个的作用是给Binder做初始化的,@InitBinder主要用在@Controller中标注于方法上(@RestController也算),表示初始化当前控制器的数据绑定器(或者属性绑定器),只对当前的Controller有效。@InitBinder标注的方法必须有一个参数WebDataBinder。所谓的属性编辑器可以理解就是帮助我们完成参数绑定,然后是在请求到达controller要执行方法前执行!

 用法如下:

@InitBinder
private void initBinder(WebDataBinder binder) {
	// 可用于自定义参数校验,然后通过addValidators来进行绑定controller
    binder.addValidators(userValidator);
    // 可用于注册 属性编译器
    binder.registerCustomEditor(String.class,new StringTrimmerEditor(true));
}

WebDataBinder到底是干嘛的?

 在Servlet中,有一个方法:request.getParameter("paramName"),它会根据key返回一个String类型的数据,从而获取到前端传递过来的请求参数。但是如果我们这样一个一个地去取出Web请求中的所有参数,就会很麻烦。我们知道Java中有对象的概念,那有没有办法将request中的请求参数都自动封装到一个Java对象中呢?为了解决这个问题,SpringMVC中就引入了WebDataBinder的概念。

 WebDataBinder的作用是从Web 请求中,把请求里的参数都绑定到对应的JavaBean上!在Controller方法中的参数类型可以是基本类型,也可以是封装后的普通Java类型。若这个普通的Java类型没有声明任何注解,则意味着它的每一个属性都需要到Request中去查找对应的请求参数,而WebDataBinder则可以帮助我们实现从Request中取出请求参数并绑定到JavaBean中。

到此这篇关于Spring中@RestControllerAdvice注解的使用详解的文章就介绍到这了,更多相关@RestControllerAdvice注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • springboot+zookeeper实现分布式锁的示例代码

    springboot+zookeeper实现分布式锁的示例代码

    本文主要介绍了springboot+zookeeper实现分布式锁的示例代码,文中根据实例编码详细介绍的十分详尽,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • java使用EasyExcel实现合并单元格

    java使用EasyExcel实现合并单元格

    这篇文章主要为大家详细介绍了java使用EasyExcel实现合并单元格的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-12-12
  • Java通过绑定实现快速将数据导出至Excel

    Java通过绑定实现快速将数据导出至Excel

    把数据导出至 Excel 是很常见的需求,而数据的持久化,往往又放在数据库中,因此把数据库中的数据导出到 Excel中,成了非常普遍的一个需求,下面我们就来看看Java如何通过绑定实现快速将数据导出至Excel吧
    2023-10-10
  • SpringBoot中的PUT和Delete请求使用

    SpringBoot中的PUT和Delete请求使用

    这篇文章主要介绍了SpringBoot中的PUT和Delete请求使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • Java concurrency线程池之线程池原理(四)_动力节点Java学院整理

    Java concurrency线程池之线程池原理(四)_动力节点Java学院整理

    这篇文章主要为大家详细介绍了Java concurrency线程池之线程池原理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • Spring中常见的7种BeanDefinition详解

    Spring中常见的7种BeanDefinition详解

    在 Spring 容器中,我们广泛使用的是一个一个的 Bean,BeanDefinition 从名字上就可以看出是关于 Bean 的定义,下面就跟随小编一起深入了解一下常见的7中BeanDefinition吧
    2023-09-09
  • JavaCV调用百度AI实现人脸检测方法详解

    JavaCV调用百度AI实现人脸检测方法详解

    在检测人脸数量、位置、性别、口罩等场景时,可以考虑使用百度开放平台提供的web接口,一个web请求就能完成检测得到结果。本文就为大家介绍JavaCV如何调用百度AI实现最简单的人脸检测,需要的可以参考一下
    2022-01-01
  • 使用Spring源码报错java:找不到类 InstrumentationSavingAgent的问题

    使用Spring源码报错java:找不到类 InstrumentationSavingAgent的问题

    这篇文章主要介绍了使用Spring源码报错java:找不到类 InstrumentationSavingAgent的问题,本文给大家分享解决方法,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • Java -jar参数详解之掌握Java可执行JAR文件的运行技巧

    Java -jar参数详解之掌握Java可执行JAR文件的运行技巧

    做项目的时候我们肯定接触过很多jar包,下面这篇文章主要给大家介绍了关于Java -jar参数详解之掌握Java可执行JAR文件的运行技巧,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • Java Ehcache缓存框架入门级使用实例

    Java Ehcache缓存框架入门级使用实例

    这篇文章主要介绍了Java Ehcache缓存框架入门级使用实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-08-08

最新评论