@ResponseStatus注解

0. 前言

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

@ResponseStatus注释可指定下表所示属性:

1. @ResponseStatus注解用法

@ResponseStatus注解有两种用法,一种是加载自定义异常类上,一种是加在目标方法中,当修饰一个类的时候,通常修饰的是一个异常类。

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

1.1 标注在@ControllerAdvice中

controller
@GetMapping("/err")
public Response errorTest(){
    int i = 1 / 0;
    return new Response(401, "1/0", null);
}
ExceptionController
@RestControllerAdvice
public class ExceptionController {
    // 捕捉其他所有异常
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Response globalException(HttpServletRequest request, Throwable ex) {
        return new Response(400,"1 / 0",null);
    }
}

由于1 / 0 出现异常被我们捕获之后返回我们自定义的状态码400,和自定义的结果。ResponseStatus就是设置了状态码400.

1.2 标注在controller方法上

使用的是@RestController返回json内容

1.2.1 修改状态码

@RequestMapping(path = "/401")
@ResponseStatus(value = HttpStatus.CREATED)
public Response unauthorized() {
    return new Response(401, "Unauthorized", null);
}

HttpStatus.CREATED 状态码为201,将原来请求状态码200改为201

1.2.2 使用reason

@RequestMapping(path = "/401")
@ResponseStatus(value = HttpStatus.UNAUTHORIZED,reason = "no no no")
public Response unauthorized() {
    return new Response(401, "Unauthorized", null);
}

如果@ResponseStatus有reason属性,@RequestMapping方法返回值都不处理了,直接返回。如下:

建议不要使用

1.3 标注在自定义的异常类上

使用时,先声明一个自定义异常类,在自定义异常类上面加上@ResponseStatus注释表示系统运行期间,当抛出自定义异常的时候,使用@ResponseStatus注解中声明的属性和reason属性将异常信息返回给客户端,提高可读性。

MyException
@ResponseStatus(code = HttpStatus.PAYMENT_REQUIRED,reason = "this is MyException")
public class MyException extends RuntimeException {
    public MyException() {
    }
}
controller
@GetMapping("/err2")
public Response errorTest2(){
    throw new MyException();
}

结果:

2. 底层原理

注解底层还是通过设置 response.setStatus来实现.

在@RequestMapping方法执行完成,Spring解析返回值之前,进行了responseStatus设置.

代码片段位于:org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#setResponseStatus

this对象指当前的ServletInvocableHandlerMethod,看到 @ResponseStatus的reason不为空,就调用response.sendError ; reason为空,就调用setStatus方法仅仅设置响应状态码.

代码片段位于:org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle

发现如果ServletInvocableHandlerMethod的responseReason有值,也就是@ResponseStatus有reason属性,@RequestMapping方法返回值都不处理了,直接返回;

也就是说只要有@ResponseStatus的 reason属性标注在 处理器Controller类或者方法上,比如响应状态码code设置为 404,reason设置为页面没找到 ,那 tomcat 展示界面是这样大概,展示信息就是我们写的reason属性.

@ResponseStatus(code=A,reason=B)标注在 @RequestMapping方法上,作用效果与 response.sendError(A,B)是一样的.

3.参考

https://www.cnblogs.com/lvbinbin2yujie/p/10575101.html

https://blog.csdn.net/Thinkingcao/article/details/110875494

  • 19
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jumper17

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值