Jackson反序列化含final类的Map对象时抛出异常求助
解决Jackson反序列化嵌套Map结构JSON的异常问题
看起来你在Jackson反序列化嵌套Map结构的JSON时遇到了问题,我来帮你梳理下解决方案。首先先明确你的JSON结构:外层是包含config字段的对象,config的值是一个Map,其中每个键(比如configItem1)对应的值又是另一个以字符串数字为键的Map,最终映射到包含valueBit、valueInt等字段的对象。
步骤1:定义对应的实体类
首先需要为最底层的数值对象创建实体类,确保字段和JSON中的键对应:
import com.fasterxml.jackson.annotation.JsonProperty; import java.time.Instant; public class ConfigValue { @JsonProperty("valueBit") private boolean valueBit; @JsonProperty("valueInt") private int valueInt; @JsonProperty("valueFloat") private float valueFloat; @JsonProperty("timestamp") private Instant timestamp; // 生成无参构造函数、getter和setter方法 // 如果你用Lombok,可以直接加@Data注解简化代码 }
然后定义外层的根对象类,用来包裹config字段:
import com.fasterxml.jackson.annotation.JsonProperty; import java.util.Map; public class ConfigRoot { @JsonProperty("config") private Map<String, Map<String, ConfigValue>> config; // getter和setter方法 }
步骤2:正确配置Jackson并执行反序列化
Jackson默认不支持Java 8的时间类型(比如Instant),所以需要注册JavaTimeModule来处理ISO8601格式的时间戳。以下是完整的反序列化代码:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; public class ConfigDeserializer { public static void main(String[] args) throws Exception { // 替换成你的完整JSON字符串(确保JSON格式闭合、无语法错误) String json = "{\"config\": { \"configItem1\": { \"0\": { \"valueBit\": false, \"valueInt\": 0, \"valueFloat\": 0, \"timestamp\": \"2016-10-05T13:44:04.223Z\" }, \"1\": { \"valueBit\": false, \"valueInt\": 0, \"valueFloat\": 0, \"timestamp\": \"2016-10-05T13:44:04.223Z\" } }, \"configItem2\": { \"0\": { \"valueBit\": false, \"valueInt\": 0, \"valueFloat\": 0, \"timestamp\": \"2016-10-05T13:44:04.223Z\" } } }}"; ObjectMapper objectMapper = new ObjectMapper(); // 注册JavaTimeModule处理时间类型 objectMapper.registerModule(new JavaTimeModule()); // 反序列化到根对象 ConfigRoot configRoot = objectMapper.readValue(json, ConfigRoot.class); // 示例:访问configItem1下的第0个值 Map<String, Map<String, ConfigValue>> configMap = configRoot.getConfig(); ConfigValue firstItem = configMap.get("configItem1").get("0"); System.out.println("Timestamp: " + firstItem.getTimestamp()); } }
常见异常原因及解决
如果还是抛出异常,大概率是以下几个问题:
- 时间类型未处理:没有注册
JavaTimeModule,导致Jackson无法解析timestamp字段的ISO8601格式,解决方法就是上面代码中的objectMapper.registerModule(new JavaTimeModule())。 - 泛型类型错误:比如把内层Map的键定义为
Integer,但JSON中的键是字符串形式的数字("0"、"1"),Jackson无法自动转换,必须用String作为内层Map的键类型。 - JSON格式无效:你的JSON是截断的,必须确保整个JSON结构完整(所有大括号、引号都闭合),否则会抛出
JsonParseException。 - 字段映射不匹配:如果实体类的字段名和JSON中的键不一致(比如大小写错误),可以用
@JsonProperty注解明确映射关系。
可选:直接反序列化到Map(无需根类)
如果你不想创建ConfigRoot类,可以直接用TypeReference反序列化到嵌套Map:
import com.fasterxml.jackson.core.type.TypeReference; // ... Map<String, Map<String, ConfigValue>> config = objectMapper.readValue( json, new TypeReference<Map<String, Map<String, ConfigValue>>>() {} );
内容的提问来源于stack exchange,提问作者user1501171
相关产品推荐
相关产品推荐

