You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot实现Ajax返回JSON、非Ajax返回HTML的全局异常处理

Spring Boot 全局异常处理:动态切换JSON/HTML响应

要实现Ajax请求返回JSON、非Ajax返回Thymeleaf页面的需求,你需要修改现有代码的返回逻辑,核心是判断请求类型并返回对应格式的响应,具体步骤如下:

1. 调整方法基础配置

首先去掉方法上的@ResponseBody注解(它会强制把返回值序列化为JSON,不符合动态切换的需求),同时把方法返回类型改为Object,这样可以灵活返回ResponseEntity(JSON)或ModelAndView(HTML视图)。

2. 添加请求类型判断逻辑

通过HttpServletRequest获取请求头信息,判断当前请求是否为Ajax:

  • 常规判断:检查X-Requested-With头是否等于XMLHttpRequest(大部分jQuery、Vue等框架的Ajax请求会携带这个头)
  • 兼容判断:检查Accept头是否包含application/json(适配Fetch API、Axios等可能不携带X-Requested-With的场景)

3. 完整修改后的代码

@ExceptionHandler(Exception.class)
public Object handle(Exception exception, WebRequest webRequest, HttpServletRequest request) {
    this.logException(exception, webRequest);
    Map<String, Object> model = getErrorPageModel(exception);

    // 判断是否为Ajax请求
    boolean isAjaxRequest = "XMLHttpRequest".equals(request.getHeader("X-Requested-With"))
            || (request.getHeader("Accept") != null && request.getHeader("Accept").contains("application/json"));

    if (isAjaxRequest) {
        // Ajax请求返回JSON格式异常信息
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(model);
    } else {
        // 非Ajax请求返回Thymeleaf错误页面
        return new ModelAndView("exception", model, HttpStatus.OK);
    }
}

关键细节说明

  • 复用错误数据:getErrorPageModel(exception)方法应该返回包含错误信息的Map(比如errorCode、errorMessage、timestamp等),这样JSON和HTML视图可以共用同一套错误数据
  • 状态码设置:Ajax请求建议返回5xx类状态码(比如INTERNAL_SERVER_ERROR),让前端能识别为异常;非Ajax请求返回200即可,错误信息在页面上展示
  • 模板准备:确保Thymeleaf模板目录下存在exception.html,并能正确渲染model中的属性,比如:
<!-- exception.html 示例 -->
<div class="error-container">
    <h1>出错了</h1>
    <p>错误信息:[[${errorMessage}]]</p>
    <p>错误码:[[${errorCode}]]</p>
</div>

额外注意事项

  • 如果前端使用Fetch API,默认不会携带X-Requested-With头,此时Accept头的判断逻辑会生效
  • 可以把判断Ajax请求的逻辑抽成工具方法,方便在其他地方复用

内容的提问来源于stack exchange,提问作者arash yousefi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 19:22:48