SpringBoot 如何使用 @ResponseStatus 注解处理异常状态码

SpringBoot 如何使用 @ResponseStatus 注解处理异常状态码

SpringBoot 是一款非常流行的 Java Web 开发框架,它提供了很多便捷的功能来简化开发工作。其中,异常处理是非常重要的一部分。在实际开发中,我们经常需要处理各种异常情况,并返回适当的 HTTP 状态码给客户端。在本文中,我们将介绍如何使用 SpringBoot 中的 @ResponseStatus 注解来处理异常状态码。

在这里插入图片描述

@ResponseStatus 注解的概念和用法

@ResponseStatus 是 Spring Framework 提供的一个注解,用于指定控制器方法抛出异常时的 HTTP 状态码。我们可以在控制器方法或自定义异常类上使用 @ResponseStatus 注解,以指定异常情况下的 HTTP 状态码。

下面是一个例子,演示如何使用 @ResponseStatus 注解来指定 HTTP 状态码。

@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
    // ...
}

在上面的例子中,我们声明了一个 ResourceNotFoundException 异常类,并使用 @ResponseStatus 注解指定了 HTTP 状态码为 HttpStatus.NOT_FOUND(404)。

使用 @ResponseStatus 注解处理异常状态码

在 SpringBoot 应用程序中,我们可以使用 @ResponseStatus 注解来处理异常状态码。具体来说,我们可以在控制器方法或自定义异常类上使用 @ResponseStatus 注解,以指定异常情况下的 HTTP 状态码。

1. 在控制器方法上使用 @ResponseStatus 注解

在控制器方法中,如果出现异常情况,我们可以使用 @ResponseStatus 注解来指定 HTTP 状态码。下面是一个例子,演示如何在控制器方法中使用 @ResponseStatus 注解。

@RestController
public class UserController {

    @GetMapping("/users/{id}")
    public User getUserById(@PathVariable Long id) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("User not found with id " + id));
        return user;
    }

    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler({ResourceNotFoundException.class})
    public void handleNotFoundException() {
        // Handle ResourceNotFoundException
    }
}

在上面的例子中,我们定义了一个 UserController 控制器类,并在 getUserById 方法中使用了 @ResponseStatus 注解来指定 ResourceNotFoundException 异常情况下的 HTTP 状态码为 HttpStatus.NOT_FOUND(404)。同时,我们还定义了一个 handleNotFoundException 方法,用于处理 ResourceNotFoundException 异常情况。当出现该异常时,控制器会自动调用该方法,并返回指定的 HTTP 状态码。

2. 在自定义异常类上使用 @ResponseStatus 注解

除了在控制器方法中使用 @ResponseStatus 注解,我们还可以在自定义异常类上使用该注解来指定异常情况下的 HTTP 状态码。下面是一个例子,演示如何在自定义异常类上使用 @ResponseStatus 注解。

@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
    // ...
}

在上面的例子中,我们定义了一个 ResourceNotFoundException 异常类,并使用 @ResponseStatus 注解指定了 HTTP 状态码为 HttpStatus.NOT_FOUND(404)。当抛出该异常时,SpringBoot 会自动返回指定的 HTTP 状态码,并将异常信息返回给客户端。

原理解析

在 SpringBoot 应用程序中,当控制器方法或自定义异常类上使用 @ResponseStatus 注解时,SpringBoot 会自动处理异常情况,并返回指定的 HTTP 状态码给客户端。具体来说,SpringBoot 会使用 ResponseStatusExceptionResolver 类来处理异常状态码。

ResponseStatusExceptionResolver 是 Spring Framework 提供的一个异常解析器,用于处理使用 @ResponseStatus 注解指定的异常情况。当控制器方法抛出异常时,ResponseStatusExceptionResolver 会检查异常类上是否有 @ResponseStatus 注解,并将指定的 HTTP 状态码返回给客户端。如果控制器方法没有指定 @ResponseStatus 注解,ResponseStatusExceptionResolver 会继续查找全局异常处理器,并使用其中的异常处理器来处理异常情况。

ResponseStatusExceptionResolver 中,使用了 ResponseStatus 注解中定义的 value() 属性来获取异常对应的 HTTP 状态码,并将其返回给客户端。同时,如果 @ResponseStatus 注解中定义了 reason() 属性,ResponseStatusExceptionResolver 会将其作为响应消息的正文内容返回给客户端。

下面是 ResponseStatusExceptionResolver 的部分源代码,展示了其如何处理异常状态码。

public class ResponseStatusExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        // Check if the exception class is annotated with @ResponseStatus
        ResponseStatus responseStatus = AnnotationUtils.findAnnotation(ex.getClass(), ResponseStatus.class);
        if (responseStatus != null) {
            // Set the response status code
            response.setStatus(responseStatus.value().value());
            // Set the response body
            String reason = responseStatus.reason();
            if (!StringUtils.isEmpty(reason)) {
                response.setContentType("text/plain;charset=UTF-8");
                try {
                    response.getWriter().write(reason);
                } catch (IOException e) {
                    // ...
                }
                return new ModelAndView();
            }
        }
        // ...
    }
}

在上面的代码中,resolveException() 方法首先检查抛出异常的类是否有 @ResponseStatus 注解,如果有,则使用注解中指定的 HTTP 状态码来设置响应状态码,并将注解中指定的响应消息作为响应正文返回给客户端。如果没有找到 @ResponseStatus 注解,则继续查找全局异常处理器,直到找到可以处理该异常的处理器为止。

总结

在本文中,我们介绍了如何使用 SpringBoot 中的 @ResponseStatus 注解来处理异常状态码。具体来说,我们可以在控制器方法或自定义异常类上使用 @ResponseStatus 注解,以指定异常情况下的 HTTP 状态码。同时,我们还分析了 ResponseStatusExceptionResolver 类的实现原理,以更好地理解 SpringBoot 如何处理异常状态码。

使用 @ResponseStatus 注解可以使异常处理更加方便和简洁,并且可以使代码更具可读性。在实际开发中,我们应该根据具体的业务需求,合理地使用 @ResponseStatus 注解来处理异常状态码,以提高应用程序的可维护性和可扩展性。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
# 基于springBoot编写的RESTFul API 本项目可用于快速搭建基于springBoot的RESTFul API服务,同时集成了swagger作为接口的在线文档与调试工具,数据交互格式建议是JSON格式。 ## 增强理解 [Spring Boot集成swagger2生成接口文档](https://www.jianshu.com/p/a115c9367a59) [自定义RESTful API服务规范](https://www.jianshu.com/p/bdea0385a77e) ## RESTFul API 首先本项目是一个RESTFul API服务的demo,与此同时再集成了一些做API常用的工具。 对于RESTFul API服务各有各的见解,网上大多是自己封装了controller层统一格式返回,通常情况下,不管你怎么请求,它总是响应你的http状态码为200。 而本项目中充分结合了HTTP状态码规范,使用ResponseEntity + HttpStatus的方式完成我们的API。当然,你想做一个完全具有RESTFul风格的API,你需要具有良好的RESTFul风格的资源设计能力。 ## 全局异常处理 采用@RestControllerAdvice + @ExceptionHandler的方式对全局异常进行处理,同时加入了常见的一些自定义异常类。 ## 参数验证器 采用spring提供的@Validated注解结合hibernate的validator进行验证,你只需要在你的验证实体对象中使用验证注解,如@NotNull、@NotBlank等,同时在你的controller方法中加入@Validated注解即可,验证结果信息已经由全局异常处理器帮你做好了。 ## TOKEN验证 当我们的API需要登录后才能访问时,简单做法是登录验证成功后给客户端生成一个token,客户端后续的请求都需要带上这个token参数,服务端对这个token进行验证,验证通过即可访问API。本项目中也集成了token的生成,同时通过拦截器统一验证了token的有效性,这依赖于redis来存储token,但这也是比较流行的做法。 你只需要在controller中需要的地方加入@AccessToken注解即可,同时如果你需要当前登录的用户信息,只需要在方法参数中加入@UserPrincipal注解修饰参数UserPrincipalVO即可。 代码示例: ``` // 在登录业务类中注入用户TOKEN组件 @Autowired private UserTokenComponent userTokenComponent; // 登录 public UserPrincipalVO login(String account, String pwd) { // 登录逻辑验证 ~~~~~ // 验证成功后,可得到用户信息 // 根据用户信息创建token, 可以把用户其它信息填充进UserPrincipalVO中,提供了全参的构造方法 UserPrincipalVO userPrincipalVO = new UserPrincipalVO(account); return userTokenComponent.createToken(userPrincipalVO); } ``` ``` @ApiOperation(value = "需要登录后才能访问的API") @GetMapping("/token") @AccessToken public ResponseEntity<UserPrincipalVO> testToken(@ApiIgnore @UserPrincipal UserPrincipalVO user) { return ResponseEntity.ok(user); } ``` ## 参数签名验证 当我们的API需要作为开放接口时,一般会为接入方分配对应的accessKey和secret,接入方每次请求我们的API时,需要把accessKey和secret与其他参数进行统一的方式签名得到签名串sign,同时把sign作 ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

stormjun

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

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

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

打赏作者

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

抵扣说明:

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

余额充值