如何解决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
相关产品推荐
相关产品推荐

