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

Jackson反序列化含可选List的Record遇SetterlessProperty问题求解

解决方案

针对Jackson反序列化Java Record时出现的Should never call set() on setterless property错误,以及可选List字段的处理需求,结合你的技术栈(jackson-databind 2.13.5、Spring Boot 2.7.11),以下是简洁规范的解决方法:

核心问题分析

Java Record是不可变类型,Jackson默认通过构造器完成反序列化,而非调用setter方法。之前的错误源于在Record属性上使用@JsonSetter,Jackson试图调用不存在的setter;自定义StringClone类属于冗余操作,直接使用List<String>即可满足需求。

方案一:用@JsonProperty统一字段映射(推荐)

直接在Record的构造器参数上添加@JsonProperty,同时控制反序列化(JSON→Record)和序列化(Record→JSON)的字段名,无需单独使用@JsonGetter/@JsonSetter,代码最简洁:

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;

// 同时作为反序列化目标和响应模型
public record MediaRecord(
    // 适配前后端不同字段名:JSON的user_id → Record的userId;序列化时userId输出为user_id
    @JsonProperty("user_id") String userId,
    // 处理可选字段:JSON的media_links_txt → Record的mediaLinks,缺失则为null
    @JsonProperty("media_links_txt") List<String> mediaLinks
) {}

方案二:针对特殊场景的@JsonGetter/@JsonSetter适配

如果需要对部分属性单独指定序列化输出的字段名(和反序列化输入字段名不同),可以在构造器参数用@JsonProperty处理输入,在getter方法上用@JsonGetter处理输出:

import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;

public record MediaRecord(
    // 反序列化时映射JSON的user_id到userId
    @JsonProperty("user_id") String userId,
    // 反序列化时映射JSON的media_links_txt到mediaLinks,缺失则为null
    @JsonProperty("media_links_txt") List<String> mediaLinks
) {
    // 序列化时将userId输出为external_user_id(和输入字段名不同)
    @JsonGetter("external_user_id")
    public String getUserIdForResponse() {
        return this.userId;
    }
}

配套Jackson配置(可选)

在Spring Boot中,添加以下配置确保可选字段和空值的正确处理:

方式1:application.yml配置

spring:
  jackson:
    deserialization:
      # 可选:将空数组转为null(如果业务需要)
      accept-empty-array-as-null-object: true
      # 可选:忽略JSON中未知字段,避免反序列化报错
      fail-on-unknown-properties: false
    serialization:
      # 可选:序列化时忽略null字段(如果响应不需要返回null)
      write-null-map-values: false

方式2:Java配置类

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        return new ObjectMapper()
            .enable(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT)
            .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
            .disable(SerializationFeature.WRITE_NULL_MAP_VALUES);
    }
}

关键注意事项

  1. Jackson 2.12+对Java Record的支持已经成熟,默认通过构造器注入属性,无需手动编写setter
  2. 可选字段直接定义为List<String>,当JSON中缺失该字段时,Jackson会自动传入null到构造器(默认配置下)
  3. 优先使用@JsonProperty统一处理字段映射,比拆分@JsonGetter/@JsonSetter更简洁易维护

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 05:22:41