程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 若依框架
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 若依框架
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • 快速入门

  • 后端手册

    • 分页实现
    • 导入导出功能
    • 文件上传与下载
    • 权限注解实现
    • 事务管理详解
    • 全局异常处理
      • 一、统一返回实体定义
      • 二、自定义异常定义
      • 三、全局异常处理器的实现
      • 四、异常处理示例
      • 五、针对不同请求类型的异常处理
      • 六、注意事项与扩展
        • 1. 使用 @RestControllerAdvice 注解
        • 2. 无法捕获异常的原因
        • 3. 扩展异常处理器
      • 七、总结
    • 参数验证详解
    • 数据脱敏详解
    • 系统日志功能实现
    • 数据权限控制
    • 多数据源实现
    • 代码生成功能
    • 定时任务实现
    • 系统接口文档生成
    • 防重复提交实现
    • 国际化支持
    • 新建子模块
  • 前端手册

  • 组件文档

  • 数据库分析

  • 若依框架
  • 后端手册
scholar
2024-08-31
目录

全局异常处理

# 全局异常处理

在Web开发中,异常处理是保证系统稳定性和用户体验的重要部分。若依框架通过全局异常处理器来统一管理各种异常,从而避免了在每个业务模块中重复编写异常处理代码。本文将详细介绍如何在若依框架中实现全局异常处理,并涵盖常见的异常场景、注意事项和扩展方法。

# 一、统一返回实体定义

为了统一处理异常和返回结果,若依框架定义了一个 AjaxResult 类,用于封装操作结果。该类继承自 HashMap,可以灵活地添加自定义字段。

package com.ruoyi.common.core.domain;

import java.util.HashMap;

/**
 * 操作消息提醒
 * 
 * @author ruoyi
 */
public class AjaxResult extends HashMap<String, Object>
{
    private static final long serialVersionUID = 1L;

    /**
     * 返回错误消息
     * 
     * @param msg 错误消息内容
     * @return 错误消息封装对象
     */
    public static AjaxResult error(String msg)
    {
        AjaxResult json = new AjaxResult();
        json.put("msg", msg);
        json.put("code", 500);  // 错误状态码
        return json;
    }

    /**
     * 返回成功消息
     * 
     * @param msg 成功消息内容
     * @return 成功消息封装对象
     */
    public static AjaxResult success(String msg)
    {
        AjaxResult json = new AjaxResult();
        json.put("msg", msg);
        json.put("code", 0);  // 成功状态码
        return json;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

# 二、自定义异常定义

在实际业务中,可能会需要定义一些自定义异常来处理特定的业务逻辑。例如,用户未登录时抛出登录异常 LoginException。

package com.ruoyi.common.exception;

/**
 * 登录异常
 * 
 * @author ruoyi
 */
public class LoginException extends RuntimeException
{
    private static final long serialVersionUID = 1L;

    protected final String message;

    public LoginException(String message)
    {
        this.message = message;
    }

    @Override
    public String getMessage()
    {
        return message;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 三、全局异常处理器的实现

通过使用 @ControllerAdvice 和 @ExceptionHandler 注解,可以捕获全局范围内的异常,并进行统一处理。若依框架的全局异常处理器 GlobalExceptionHandler 是一个很好的示例。

package com.ruoyi.framework.web.exception;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.LoginException;

/**
 * 全局异常处理器
 * 
 * @author ruoyi
 */
@RestControllerAdvice  // 自动将返回的数据封装为JSON格式
public class GlobalExceptionHandler
{
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 处理登录异常
     * 
     * @param e 登录异常对象
     * @return 处理后的AjaxResult封装对象
     */
    @ExceptionHandler(LoginException.class)
    public AjaxResult loginException(LoginException e)
    {
        log.error(e.getMessage(), e);  // 记录错误日志
        return AjaxResult.error(e.getMessage());  // 返回错误信息
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

注意:

  • 使用 @RestControllerAdvice 注解可以确保所有异常处理方法返回的结果都是 JSON 格式。
  • 通过 @ExceptionHandler 注解,可以定义具体的异常处理逻辑。

# 四、异常处理示例

为了演示全局异常处理器的工作流程,我们可以在一个控制器中模拟抛出异常。

@Controller
public class SysIndexController 
{
    /**
     * 首页方法
     */
    @GetMapping("/index")
    public String index(ModelMap mmap)
    {
        // 模拟用户未登录,抛出业务逻辑异常
        SysUser user = ShiroUtils.getSysUser();
        if (StringUtils.isNull(user))
        {
            throw new LoginException("用户未登录,无法访问请求。");  // 抛出自定义登录异常
        }
        mmap.put("user", user);
        return "index";
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

当用户未登录时,访问 /index 会抛出 LoginException 异常,根据全局异常处理器的配置,系统会捕获该异常,并返回一个 AjaxResult 封装的 JSON 数据。

输出示例:

{
    "msg": "用户未登录,无法访问请求。",
    "code": 500
}
1
2
3
4

# 五、针对不同请求类型的异常处理

在某些情况下,同一个异常处理方法需要返回不同类型的响应。例如,对于 AJAX 请求返回 JSON 数据,而对于普通页面请求则返回 HTML 页面。这可以通过检查请求类型来实现。

@ExceptionHandler(LoginException.class)
public Object loginException(HttpServletRequest request, LoginException e)
{
    log.error(e.getMessage(), e);

    // 判断请求是否为AJAX请求
    if (ServletUtils.isAjaxRequest(request))
    {
        return AjaxResult.error(e.getMessage());  // 返回JSON数据
    }
    else
    {
        return new ModelAndView("/error/500");  // 返回500错误页面
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 六、注意事项与扩展

# 1. 使用 @RestControllerAdvice 注解

如果你希望所有异常处理方法都返回 JSON,可以使用 @RestControllerAdvice 注解。这会使得返回的数据自动封装为 JSON,而不需要在每个方法上添加 @ResponseBody 注解。

# 2. 无法捕获异常的原因

如果你发现某些异常无法被全局异常处理器捕获,可以检查以下几点:

  • 异常是否已被业务代码中的 try-catch 块捕获并处理。
  • 异常是否是在 Controller 之外抛出的,例如在拦截器或过滤器中。

# 3. 扩展异常处理器

你可以根据需要扩展全局异常处理器,添加对更多自定义异常或框架异常的处理。例如,处理数据库连接异常、数据完整性异常等。

# 七、总结

全局异常处理器的引入极大地简化了异常处理逻辑,使得控制器中的业务代码更加简洁。通过合理使用 @ControllerAdvice 和 @ExceptionHandler,可以有效地管理和响应各种异常,提升系统的稳定性和用户体验。

  • 统一处理: 全局异常处理器让异常处理逻辑集中管理,避免代码重复。
  • 灵活扩展: 可以根据业务需求灵活扩展异常处理器,处理不同类型的异常。
  • 自动化返回: 使用 @RestControllerAdvice 简化了 JSON 数据的返回处理。
编辑此页 (opens new window)
上次更新: 2024/12/28, 18:32:08
事务管理详解
参数验证详解

← 事务管理详解 参数验证详解→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式