0
点赞
收藏
分享

微信扫一扫

@ResponseStatus & @ControllerAdvice

我阿霆哥 2022-03-24 阅读 67
spring

一、@ResponseStatus注解作用

@ResponseStatus注解是spring-web包中提供的一个注解,从下图部分源码中可以看出@ResponseStatus注解具有value、code、reason 三个属性。
在这里插入图片描述

代码中的作用:

二、@ResponseStatus注解用法

@ResponseStatus注解有两种用法,一种是加载自定义异常类上,一种是加在目标方法中,当修饰一个类的时候,通常修饰的是一个异常类
Tips: 这里我们说一下加在目标方法上的这种情况,注解中有两个参数,value属性设置异常的状态码,reaseon是对于异常的描述,其实@ResponseStatus大部分情况下更适合于在自定义异常类或者目标方法上使用

  1. @ResponseStatus响应成功
  @RequestMapping(value = "/res")
    @ResponseStatus(value = HttpStatus.OK)
    //@RequestsMapping方法执行完成,Spring解析返回值之前,进行了该注解解析,最好配合HandleException使用,用于自定义异常处理
    //@ResponseStatus的reason不为空,就调用response.sendError  ; reason为空,就调用setStatus方法仅仅设置响应状态码
    @ResponseBody
    public String helloResponseStatus(@RequestParam(value = "name") String name) {
        System.out.println("into res");
        return "into res";
    }

在这里插入图片描述

  1. @ResponseStatus响应失败
    @RequestMapping(value = "/res")
    @ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "404-NotFound")
    //@RequestsMapping方法执行完成,Spring解析返回值之前,进行了该注解解析,最好配合HandleException使用,用于自定义异常处理
    //@ResponseStatus的reason不为空,就调用response.sendError  ; reason为空,就调用setStatus方法仅仅设置响应状态码
    @ResponseBody
    public String helloResponseStatus(@RequestParam(value = "name") String name) {
        System.out.println("into res");
        return "into res";
    }

在这里插入图片描述

  1. @ResponseStatus用在自定义异常类上
 @RequestMapping(value = "/resex")
    public void ResponseStatusException() throws BusinessException {
            throw new BusinessException();
    }
-------------------------------------------------------------
@ResponseStatus(reason="The system is exception!")
public class BusinessException extends Exception{
}

在这里插入图片描述

  1. @ResponseStatus与@ExceptionHandler组合使用

@ResponseStatus注解配合@ExceptionHandler注解使用会更好
在这里插入图片描述

  1. 小结

三、@ControllerAdvice用法

  1. 官方解释作用:
  1. 自定义ControllerAdvice
@ControllerAdvice
public class ExceptionAdvice {
    //配置一个全局异常
    //乍一眼看上去毫无问题,但这里有一个纰漏,由于Exception是异常的父类,
    //如果你的项目中出现过在自定义异常中使用@ResponseStatus的情况,
    //你的初衷是碰到那个自定义异常响应对应的状态码,而这个控制器增强处理类,会首先进入,并直接返回,
    //不会再有@ResponseStatus的事情了,这里为了解决这种纰漏,我提供了一种解决方式。
    @ExceptionHandler({Exception.class})
    @ResponseBody
    public String handException(HttpServletRequest request, Exception e) throws Exception {
        //如果异常用 @ResponseStatus 注释,则重新抛出它并让框架处理它
        //AnnotationUtils 是一个 Spring Framework 实用程序类。
        if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
            throw e;
        }
        //否则设置并将用户发送到默认错误视图
        return e.getMessage();
    }
    
     //用于捕捉全局的ArrayIndexOutOfBoundsException
    @ExceptionHandler({ ArrayIndexOutOfBoundsException.class })
    @ResponseBody
    public String handleArrayIndexOutOfBoundsException(Exception e) {
        e.printStackTrace();
        return "testArrayIndexOutOfBoundsException";}
}

@ExceptionHandler和@ResponseStatus我们提到,如果单使用@ExceptionHandler,只能在当前Controller中处理异常。但当配合@ControllerAdvice一起使用的时候,就可以摆脱那个限制了。

  1. Controller
    @GetMapping(value = "ex/{id}")
    @ResponseBody
    public String testExceptionHandle2(@PathVariable(value = "id") Integer id) {
        //抛出ArrayIndexOutOfBoundsException给ExceptionAdvice处理
        List<String> list = Arrays.asList(new String[]{"a","b","c","d"});
        return list.get(id-1);
    }

在这里插入图片描述

举报

相关推荐

0 条评论