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

如何解决Jackson反序列化ApiException时的HttpStatus枚举格式错误?

问题根源

你的ApiException类仅提供了接收HttpStatus枚举的构造函数,Jackson反序列化时会尝试使用该构造函数,将JSON中status字段的数值400误当作枚举的ordinal(序号)值解析,而HttpStatus枚举的序号范围是0~68,因此触发超出范围的报错。

解决方法

方法一:添加无参构造函数

Lombok的@Data注解默认不会生成无参构造,显式添加@NoArgsConstructor后,Jackson会先创建空对象再逐个赋值,避免触发带HttpStatus参数的构造函数:

@JsonIncludeProperties({"timestamp", "status", "error", "message", "path"})
@JsonPropertyOrder({"timestamp", "status", "error", "message", "path"})
@Data
@NoArgsConstructor // 新增无参构造
public class ApiException extends RuntimeException {

    private String timestamp;
    private int status;
    private String error;
    private String message;
    private String path;

    public ApiException(HttpStatus status, String message, String path) {
        this.timestamp = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now(Clock.systemUTC()));
        this.status = status.value();
        this.error = status.getReasonPhrase();
        this.message = message;
        this.path = path;
    }
}

方法二:给构造函数添加Jackson注解

如果不想用无参构造,可通过@JsonCreator和@JsonProperty指定JSON字段到构造参数的映射逻辑,直接接收状态码数值并转换为HttpStatus枚举:

@JsonCreator // 标记为反序列化专用构造函数
public ApiException(
        @JsonProperty("status") int statusCode,
        @JsonProperty("message") String message,
        @JsonProperty("path") String path
) {
    HttpStatus status = HttpStatus.valueOf(statusCode);
    this.timestamp = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now(Clock.systemUTC()));
    this.status = status.value();
    this.error = status.getReasonPhrase();
    this.message = message;
    this.path = path;
}

方法三:全局配置Jackson处理枚举

通过配置让Jackson默认使用枚举的名称/值而非序号解析,同时注册Spring提供的HttpStatus序列化模块:

配置文件方式(application.properties)

spring.jackson.deserialization.read-enums-by-name=true

配置类方式

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(DeserializationFeature.READ_ENUMS_BY_NAME);
        mapper.registerModule(new SpringModule()); // 内置HttpStatus的正确序列化规则
        return mapper;
    }
}

注意:此方式会影响全局枚举的反序列化行为,需确保其他枚举场景适配该规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 22:35:27