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

升级Spring Boot后,如何恢复1.5版本的默认异常映射?

刚升级完Spring Boot和Jersey就遇到异常响应格式变了?我太懂这种糟心的感觉了——Spring Boot 2.0确实调整了默认的错误输出结构,结合Jersey 2.26的升级,导致你原来1.5版本的熟悉格式不见了。下面给你两种靠谱的恢复方案:

解决方案一:自定义ErrorAttributes(全局生效)

Spring Boot 2.x用新的DefaultErrorAttributes实现替换了1.5版本的逻辑,我们可以通过继承它并重写方法,强制恢复旧的响应格式。

创建一个自定义的ErrorAttributes组件:

import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.WebRequest;

import java.util.Map;

@Component
public class LegacyErrorAttributes extends DefaultErrorAttributes {

    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
        // 先获取默认的错误属性
        Map<String, Object> attributes = super.getErrorAttributes(webRequest, includeStackTrace);
        
        // 调整为Spring Boot 1.5的字段结构(移除2.x新增字段并确保核心字段保留)
        attributes.remove("trace"); // 移除2.x新增的堆栈追踪字段,按需保留
        
        // 确保必要字段都存在
        attributes.putIfAbsent("timestamp", attributes.get("timestamp"));
        attributes.putIfAbsent("status", attributes.get("status"));
        attributes.putIfAbsent("error", attributes.get("error"));
        attributes.putIfAbsent("exception", attributes.get("exception"));
        attributes.putIfAbsent("message", attributes.get("message"));
        attributes.putIfAbsent("path", attributes.get("path"));
        
        return attributes;
    }
}

这个组件会被Spring自动加载,全局覆盖默认的错误属性生成逻辑,不管是Jersey接口还是Spring MVC接口,都会返回1.5版本的格式。

解决方案二:适配Jersey的ExceptionMapper(针对Jersey接口)

如果你的Jersey接口异常被Jersey自身的处理机制接管,需要自定义ExceptionMapper,让它使用上面的LegacyErrorAttributes生成响应。

创建一个Jersey的异常映射器:

import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;

import javax.inject.Inject;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import java.util.Map;

@Provider
public class LegacyJerseyExceptionMapper implements ExceptionMapper<Throwable> {

    private final ErrorAttributes errorAttributes;

    @Inject
    public LegacyJerseyExceptionMapper(ErrorAttributes errorAttributes) {
        this.errorAttributes = errorAttributes;
    }

    @Override
    public Response toResponse(Throwable throwable) {
        // 获取当前请求的WebRequest上下文
        WebRequest webRequest = new ServletWebRequest(
                RequestContextHolder.getRequestAttributes().getRequest()
        );
        
        // 用自定义的ErrorAttributes生成符合1.5格式的属性
        Map<String, Object> errorAttributesMap = errorAttributes.getErrorAttributes(webRequest, false);
        
        // 确保异常类名和消息正确填充
        errorAttributesMap.put("exception", throwable.getClass().getName());
        errorAttributesMap.put("message", throwable.getMessage());
        
        // 返回JSON格式的错误响应
        return Response.status((Integer) errorAttributesMap.get("status"))
                .type(MediaType.APPLICATION_JSON_TYPE)
                .entity(errorAttributesMap)
                .build();
    }
}

记得把这个类注册到Jersey的配置里(比如在ResourceConfig的register方法中添加),这样Jersey处理未捕获异常时就会用我们的格式返回。

注意事项

  • 如果你需要保留堆栈追踪,可以把includeStackTrace参数设为true,1.5版本默认不返回该字段,按需调整即可
  • 测试时直接抛出未处理异常(比如IllegalStateException),对比响应结构是否和升级前一致
  • 确保自定义组件被Spring或Jersey正确扫描到(比如@Component和@Provider注解)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:34:13