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

使用Jackson将含List<Map<String,String>>的JSON反序列化为自定义对象遇错

Jackson反序列化MyCustomObject的注解解决方案

常见问题及对应注解修复

1. 属性名与JSON字段不匹配

如果Java对象的属性名和JSON里的字段名对不上(比如Java里是userName,JSON里是user_name),直接用@JsonProperty指定映射关系:

public class MyCustomObject {
    @JsonProperty("user_name")
    private String userName;
    // 其他属性...
}

2. 嵌套对象反序列化异常

如果你的对象里包含自定义嵌套对象,要确保嵌套对象也配置好Jackson规则:

  • 嵌套对象如果只有带参构造器,必须给构造器加@JsonCreator,同时每个参数用@JsonProperty标记对应JSON字段:
public class MyCustomObject {
    private NestedObject nested;
    
    public static class NestedObject {
        private String nestedField;
        
        @JsonCreator
        public NestedObject(@JsonProperty("nested_field") String nestedField) {
            this.nestedField = nestedField;
        }
    }
}
  • 嵌套对象最好加上@JsonIgnoreProperties(ignoreUnknown = true),避免JSON里有多余字段导致报错。

3. List<Map<String,String>>类型属性处理

这个类型Jackson默认就能处理,但要注意两个点:

  • 如果JSON里的字段名和Java属性名不一致,用@JsonProperty指定,比如:
@JsonProperty("data_list")
private List<Map<String,String>> dataList;
  • 如果该字段可能为null或者在某些JSON里不存在,给属性加@JsonProperty(required = false),或者在类上全局加@JsonIgnoreProperties(ignoreUnknown = true)忽略未知字段。

4. 缺少无参构造器

Jackson默认需要类有无参构造器,如果你的MyCustomObject只有带参构造器,要么补一个无参构造器,要么给带参构造器加@JsonCreator+@JsonProperty:

public class MyCustomObject {
    private String name;
    private List<Map<String,String>> data;
    
    // 推荐:补无参构造器
    public MyCustomObject() {}
    
    // 备选:带参构造器加注解
    @JsonCreator
    public MyCustomObject(@JsonProperty("name") String name, @JsonProperty("data") List<Map<String,String>> data) {
        this.name = name;
        this.data = data;
    }
}

5. JSON存在未知字段

如果JSON里有MyCustomObject没定义的字段,会直接触发MismatchedInputException,在类上加@JsonIgnoreProperties(ignoreUnknown = true)就能忽略这些多余字段:

@JsonIgnoreProperties(ignoreUnknown = true)
public class MyCustomObject {
    // 属性定义...
}

完整可运行示例

自定义对象MyCustomObject

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import java.util.Map;

@JsonIgnoreProperties(ignoreUnknown = true)
public class MyCustomObject {
    private String id;
    private NestedInfo nestedInfo;
    private List<Map<String, String>> detailList;

    // 无参构造器必须有
    public MyCustomObject() {}

    // 可选:带参构造器(方便初始化,反序列化也能用)
    @JsonCreator
    public MyCustomObject(
            @JsonProperty("id") String id,
            @JsonProperty("nested_info") NestedInfo nestedInfo,
            @JsonProperty("detail_list") List<Map<String, String>> detailList) {
        this.id = id;
        this.nestedInfo = nestedInfo;
        this.detailList = detailList;
    }

    // Getter/Setter必须有,Jackson需要通过这些访问属性
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    public NestedInfo getNestedInfo() { return nestedInfo; }
    public void setNestedInfo(NestedInfo nestedInfo) { this.nestedInfo = nestedInfo; }

    public List<Map<String, String>> getDetailList() { return detailList; }
    public void setDetailList(List<Map<String, String>> detailList) { this.detailList = detailList; }

    // 嵌套内部类
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class NestedInfo {
        private String name;
        private Integer age;

        public NestedInfo() {}

        @JsonCreator
        public NestedInfo(@JsonProperty("name") String name, @JsonProperty("age") Integer age) {
            this.name = name;
            this.age = age;
        }

        public String getName() { return name; }
        public void setName(String name) { this.name = name; }

        public Integer getAge() { return age; }
        public void setAge(Integer age) { this.age = age; }
    }
}

反序列化测试代码

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;

public class DeserializeTest {
    public static void main(String[] args) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        
        // 示例JSON(适配上面的对象结构)
        String json = "{\n" +
                "  \"id\": \"123\",\n" +
                "  \"nested_info\": {\n" +
                "    \"name\": \"张三\",\n" +
                "    \"age\": 25\n" +
                "  },\n" +
                "  \"detail_list\": [\n" +
                "    {\"key1\": \"value1\"},\n" +
                "    {\"key2\": \"value2\"}\n" +
                "  ]\n" +
                "}";
        
        MyCustomObject obj = objectMapper.readValue(json, MyCustomObject.class);
        System.out.println(obj.getId());
        System.out.println(obj.getNestedInfo().getName());
        System.out.println(obj.getDetailList().get(0).get("key1"));
    }
}

适配多结构JSON的额外技巧

如果你的三种JSON响应结构有差异(比如字段名多变、字段可选),可以用这些注解:

  • @JsonAlias({"field1", "field2"}):给属性指定多个别名,适配不同JSON里的不同字段名,比如:
    @JsonAlias({"detail_list", "details"})
    private List<Map<String,String>> detailList;
    
  • @JsonProperty(required = false):标记属性非必填,避免某些JSON里缺少该字段时报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 11:25:25