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
相关产品推荐
相关产品推荐

