Java/Spring中重复异常处理逻辑的重构与简化

Java/Spring中重复异常处理逻辑的重构与简化

本教程旨在解决Spring应用中@ExceptionHandler方法体重复的问题。通过将多个相似的异常处理逻辑抽象为一个通用的私有辅助方法,实现代码的有效重构,从而提高代码的可读性、可维护性,并遵循DRY(Don’t Repeat Yourself)原则,减少冗余代码。

在复杂的企业级应用中,异常处理是不可或缺的一部分。spring框架通过@exceptionhandler注解提供了强大的异常处理机制,允许开发者为特定的异常类型定义专门的处理逻辑。然而,随着应用规模的增长,我们可能会遇到多个异常处理方法具有相似甚至相同的代码结构,仅仅在少数参数(如http状态码、错误类型标识)上有所差异。这种代码重复不仅增加了维护成本,也降低了代码的可读性。

考虑以下三个典型的Spring异常处理方法:

@ExceptionHandler(value = {ProhibitedScimTypeException.class})public ResponseEntity policyConflict(final ProhibitedScimTypeException exception) {    final var errorDto = new ErrorDto();    errorDto.setDetail(exception.getMessage());    errorDto.setStatus(BAD_REQUEST.toString());    errorDto.setScimType("prohibited");    return new ResponseEntity(errorDto, HttpStatus.BAD_REQUEST);}@ExceptionHandler(value = {UserAlreadyExistsException.class})public ResponseEntity userNameExistsConflict(final UserAlreadyExistsException exception) {    final var errorDto = new ErrorDto();    errorDto.setDetail(exception.getMessage());    errorDto.setStatus(CONFLICT.toString());    errorDto.setScimType("uniqueness");    return new ResponseEntity(errorDto, HttpStatus.CONFLICT);}@ExceptionHandler(value = {UserNotFoundException.class})public ResponseEntity userNameNotFoundConflict(final UserNotFoundException exception) {    final var errorDto = new ErrorDto();    errorDto.setDetail(exception.getMessage());    errorDto.setStatus(NOT_FOUND.toString());    errorDto.setScimType("prohibited");    return new ResponseEntity(errorDto, HttpStatus.NOT_FOUND);}

仔细观察这些方法,可以发现它们的核心逻辑高度相似:创建一个ErrorDto对象,设置其detail为异常消息,设置status和scimType,最后构建并返回一个ResponseEntity。不同之处在于HttpStatus和scimType的值。

重构策略:提取通用辅助方法

为了消除这种重复,我们可以将公共的代码逻辑提取到一个独立的私有辅助方法中。这个辅助方法将接收那些在不同异常处理中变化的参数,例如异常对象本身、HTTP状态码和自定义的SCIM类型字符串。

步骤一:识别并参数化可变部分

立即学习“Java免费学习笔记(深入)”;

在上述示例中,exception对象、HttpStatus和scimType是变化的。因此,我们的辅助方法需要这些作为参数。

降重鸟 降重鸟

要想效果好,就用降重鸟。AI改写智能降低AIGC率和重复率。

降重鸟 113 查看详情 降重鸟

步骤二:创建私有辅助方法

定义一个私有方法,例如conflict,它接收Throwable类型的异常、HttpStatus以及一个表示SCIM类型的String。该方法将封装构建ErrorDto和ResponseEntity的通用逻辑。

private ResponseEntity conflict(final Throwable exception, HttpStatus status, String scimType) {    final var errorDto = new ErrorDto();    errorDto.setDetail(exception.getMessage());    errorDto.setStatus(status.toString());    errorDto.setScimType(scimType);    return new ResponseEntity(errorDto, status);}

步骤三:调用辅助方法简化原始处理方法

现在,每个@ExceptionHandler方法都可以变得非常简洁,只需调用新创建的conflict辅助方法,并传入其特有的参数。

@ExceptionHandler(value = {ProhibitedScimTypeException.class})public ResponseEntity policyConflict(final ProhibitedScimTypeException exception) {    return conflict(exception, HttpStatus.BAD_REQUEST, "prohibited");}@ExceptionHandler(value = {UserAlreadyExistsException.class})public ResponseEntity userNameExistsConflict(final UserAlreadyExistsException exception) {    return conflict(exception, HttpStatus.CONFLICT, "uniqueness");}@ExceptionHandler(value = {UserNotFoundException.class})public ResponseEntity userNameNotFoundConflict(final UserNotFoundException exception) {    return conflict(exception, HttpStatus.NOT_FOUND, "prohibited");}

优势与注意事项

提高代码可读性与简洁性:重构后的异常处理方法体变得非常短小,一目了然,清晰地表达了其核心意图——将特定异常映射到通用错误响应。增强可维护性:当需要修改ErrorDto的构建逻辑或ResponseEntity的返回方式时,只需修改conflict这一个辅助方法,而无需遍历所有相关的异常处理方法。这大大降低了维护成本和引入错误的风险。遵循DRY原则:消除了代码重复,使得代码库更加精炼和高效。易于扩展:如果未来需要添加新的异常类型,只要它们符合这种通用响应模式,就可以轻松地通过调用conflict方法来集成。适用性:这种重构模式不仅适用于@ExceptionHandler方法,也适用于任何存在重复逻辑的代码块。关键在于识别出哪些部分是固定不变的,哪些部分是需要参数化的。异常类型参数:在辅助方法中,异常参数类型使用了Throwable,这使得它可以接收任何类型的异常。在实际应用中,如果所有相关异常都继承自某个特定的基类(例如RuntimeException或自定义的BaseAppException),则可以将参数类型限定为该基类,以提供更强的类型安全。错误码管理:对于scimType这样的字符串常量,建议将其定义为枚举或公共常量,以避免魔法字符串,进一步提高代码质量。

总结

通过将重复的异常处理逻辑抽象为一个参数化的私有辅助方法,我们成功地简化了Spring应用中的@ExceptionHandler代码。这种重构实践不仅提升了代码的可读性和可维护性,还有效地减少了冗余,使得代码库更加健壮和易于管理。在日常开发中,积极识别并消除重复代码是提升软件质量的关键一环。

以上就是Java/Spring中重复异常处理逻辑的重构与简化的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/232070.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月3日 21:27:50
下一篇 2025年11月3日 21:33:00

相关推荐

  • 使用 Laravel Blade 组件简化表格元素插入

    本文旨在介绍如何利用 Laravel Blade 组件来简化表格元素的插入,提高代码的可维护性和可读性。虽然组件的使用可能不会显著减少代码量,但它能够将重复使用的 HTML 片段封装起来,从而提高代码的组织性和可重用性。通过创建表格行组件,我们可以将表格行的 HTML 结构和逻辑封装在一个单独的文件…

    2025年12月10日
    000
  • Laravel Blade:利用组件高效构建可复用表格结构

    本文探讨如何在Laravel Blade中简化表格元素的插入与管理。针对重复性表格行代码的问题,我们将介绍如何利用Laravel Blade组件(Components)来封装可复用的HTML结构,实现代码的模块化、清晰化和高效维护。通过实例演示,读者将掌握创建和使用Blade组件的方法,从而优化前端…

    2025年12月10日
    000
  • Laravel Blade 中高效复用表格元素:组件化实践

    本文探讨如何在 Laravel Blade 中高效、简洁地复用表格元素,解决传统 @include 结合 @section 导致重复内容的问题。我们将详细介绍如何利用 Laravel 强大的 Blade 组件功能,创建可参数化的表格行组件,从而实现代码的高度模块化和可维护性,提升开发效率。 理解原问…

    2025年12月10日
    000
  • PHP命令怎样在执行时自动记录脚本的运行状态 PHP命令运行状态记录的操作指南

    最直接的方式是使用Monolog库记录PHP CLI脚本的运行状态,通过配置文件处理器和格式化器,捕获脚本生命周期中的关键事件、错误及性能数据,并结合try-catch、全局异常处理和关闭函数实现全面的日志记录与错误监控。 要在PHP命令执行时自动记录脚本运行状态,最直接的方式是利用PHP内置的错误…

    2025年12月10日
    000
  • 如何在WordPress页面模板中实现全宽布局

    本教程旨在帮助您在WordPress中创建一个全宽页面模板,解决侧边栏意外显示的问题。我们将检查模板代码,确认侧边栏调用方式,并提供避免重复侧边栏显示的解决方案,确保您的页面呈现出预期的全宽效果。 在WordPress中创建全宽页面模板,通常意味着你希望移除页面上的侧边栏,让内容占据整个页面宽度。然…

    2025年12月10日
    000
  • 如何在 WordPress 页面模板中实现全宽布局

    本文将指导你如何在 WordPress 中创建一个全宽页面模板,解决侧边栏意外显示的问题。通过检查模板文件和理解 get_sidebar() 函数的工作方式,你可以轻松实现自定义的全宽页面布局,从而更好地控制页面的外观和内容呈现。 创建全宽页面模板 要创建一个全宽页面模板,你需要创建一个新的 PHP…

    2025年12月10日
    000
  • 使用 Laravel 调度器和 HTTP 客户端控制 PDU 设备

    本文将介绍如何使用 Laravel 调度器和 HTTP 客户端来远程控制电源分配单元 (PDU) 设备。重定向方法在调度器环境中不起作用,因此我们将使用 HTTP 客户端直接与 PDU 设备的 Web 接口进行通信。 问题分析 原方案尝试使用 Laravel 的 redirect() 或 Redir…

    2025年12月10日
    000
  • WordPress全宽页面模板创建指南:避免侧边栏冲突

    本文将指导您如何在WordPress中创建一个全宽页面模板,并解决可能出现的侧边栏冲突问题。通过修改页面模板代码,确保页面内容占据整个浏览器宽度,从而实现真正的全宽布局。重点在于检查并移除模板文件中不必要的侧边栏调用,确保页面布局的纯粹性。 创建WordPress全宽页面模板 在WordPress中…

    2025年12月10日
    000
  • Symfony 如何将设备信息转为数组

    将设备信息转换为数组的推荐做法是使用jenssegers/agent库,通过composer安装后,在symfony控制器中获取请求头的user-agent字符串并解析为包含设备、操作系统、浏览器等信息的关联数组;2. 实际应用场景包括用户体验优化、数据分析、日志记录、安全反欺诈和a/b测试;3. …

    2025年12月10日
    000
  • FCM Cloud Messaging:有效验证和管理设备Token

    本文旨在解决在使用Firebase Cloud Messaging (FCM)进行推送通知时,如何有效验证和管理设备Token的问题。当用户通过非应用内的方式取消订阅通知时,服务器无法立即得知,导致数据库中残留无效Token。本文将介绍如何使用Firebase Admin SDK提供的validat…

    2025年12月10日
    000
  • PHP Walk Score API 集成:解决数组循环中的非对象属性访问错误

    正如摘要所述,本文将深入探讨在使用 PHP 集成 Walk Score API 时,如何处理包含坐标对的文本输入,并解决可能出现的“Trying to get property ‘walkscore’ of non-object”错误。我们将分析导致该问题的代码,找出根本原因…

    2025年12月10日
    000
  • FCM Token 验证与失效清理:保障推送消息有效性

    本文旨在解决在使用 Firebase Cloud Messaging (FCM) 推送通知时,如何有效验证和清理失效的 FCM Token。通过批量验证 Token 的有效性,并结合数据库管理,确保推送消息能够准确送达目标用户,避免资源浪费,提高推送效率。 在使用 FCM 推送通知时,一个常见的挑战…

    2025年12月10日
    000
  • FCM 设备 Token 验证:确保推送通知的有效性

    在使用 Firebase Cloud Messaging (FCM) 进行推送通知时,一个常见的挑战是如何处理无效的设备 Token。例如,当用户在客户端(如 Chrome 或 Firefox)取消订阅通知,但服务器端数据库仍然保存着该设备的 Token 时,就会出现这种情况。这会导致向无效 Tok…

    2025年12月10日
    000
  • FCM Token 验证与失效处理:构建可靠的推送通知系统

    本文旨在解决在使用 Firebase Cloud Messaging (FCM) 构建 Web 应用时,如何有效验证和管理设备 Token 的问题。当用户在客户端自行取消订阅推送通知,而服务端未能及时同步状态时,会导致数据库中存在无效 Token。本文将介绍如何使用 Firebase Admin S…

    2025年12月10日
    000
  • PHP数组元素条件分类与重组实践

    本教程详细阐述了如何在PHP中高效地根据特定条件(例如字符串中是否包含某个特定字符)对数组元素进行分类和重组。通过首先合并所有待处理的数组,然后遍历合并后的数据,并利用字符串查找函数(如strpos)进行条件判断,最终将符合条件的元素分配到指定的新数组中,从而实现数据的精准分类和结构化重组,避免了复…

    2025年12月10日
    000
  • PHP框架怎样实现数据的软删除功能 PHP框架软删除的实用技巧教程

    软删除通过添加deleted_at字段标记删除时间而非物理删除数据。1. 在php中可通过重写模型newquery方法并结合global scope自动过滤未删除数据;2. 使用trait实现delete、restore、trashed等软删除逻辑;3. 为deleted_at字段建立索引以提升查询…

    2025年12月10日
    000
  • 创建 WordPress 全宽页面模板

    本文旨在指导您如何在 WordPress 中创建一个全宽页面模板,解决侧边栏意外显示的问题。通过检查模板文件,确保没有重复调用侧边栏函数,您可以轻松实现全宽页面的布局,从而更好地展示您的内容。 创建全宽页面模板 在 WordPress 中创建全宽页面模板,通常涉及创建一个自定义的页面模板文件,并将其…

    2025年12月10日
    000
  • PHP常用框架怎样优化数据库查询性能 PHP常用框架查询优化的技巧

    n+1查询问题由orm的懒加载机制导致,当查询主表数据后,在循环中逐条访问关联数据时会触发大量额外查询,例如获取100个用户及其文章时产生101次查询;有效规避方法是使用预加载(eager loading),如laravel的with()或yii的joinwith(),在初始查询时通过join或in…

    2025年12月10日
    000
  • WordPress 全宽页面模板创建指南

    本教程旨在指导您如何在 WordPress 中创建一个全宽页面模板。我们将分析常见问题,例如意外显示多个侧边栏的情况,并提供解决方案,确保您的页面真正实现全宽布局,摆脱侧边栏的干扰,专注于内容展示。 创建全宽页面模板 在 WordPress 中创建全宽页面模板,首先需要创建一个新的 PHP 文件,并…

    2025年12月10日
    000
  • PHP函数如何使用箭头函数简化匿名函数 PHP函数箭头函数应用的基础方法

    php的箭头函数(fn语法)与传统匿名函数的核心区别在于:它自动从父作用域按值捕获变量,无需use关键字,且隐式返回单一表达式的结果;这使得在数组操作、简单数据转换等场景下代码更简洁;但其限制包括只能包含一个表达式、无法处理复杂逻辑、不能使用return语句,且捕获的外部变量为按值传递,后续修改不影…

    2025年12月10日
    000

发表回复

登录后才能评论
关注微信