Java JSON反序列化技术详解

1. 选择 JSON 库

Java 中常用的 JSON 库:

  • Jackson(推荐):高性能,功能丰富,支持注解和复杂类型。

  • Gson:Google 的库,简单易用。

  • org.json:轻量级,但功能较少。

Maven 依赖(Jackson):

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.0</version>
</dependency>

2. 基本反序列化步骤

示例(Jackson):

import com.fasterxml.jackson.databind.ObjectMapper;

public class Person {
    public String name;
    public int age;
}

public class Main {
    public static void main(String[] args) throws Exception {
        String jsonStr = "{\"name\":\"Alice\",\"age\":30}";
        ObjectMapper mapper = new ObjectMapper();
        Person person = mapper.readValue(jsonStr, Person.class);
        System.out.println(person.name); // 输出: Alice
    }
}

3. 处理字段名称不一致

使用 @JsonProperty 注解映射 JSON 字段名与类属性:

public class Person {
    @JsonProperty("user_name")
    public String name;
}

4. 处理日期格式

JSON 中没有日期类型,需指定格式:

public class Event {
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "UTC")
    public Date eventDate;
}

5. 处理嵌套对象和数组

嵌套对象:

public class Address {
    public String city;
}

public class User {
    public String name;
    public Address address;
}

String json = "{\"name\":\"Bob\",\"address\":{\"city\":\"Paris\"}}";
User user = mapper.readValue(json, User.class);

数组:

String jsonArray = "[{\"name\":\"Alice\"}, {\"name\":\"Bob\"}]";
Person[] people = mapper.readValue(jsonArray, Person[].class);

6. 处理多态类型(子类选择)

使用 @JsonTypeInfo 和 @JsonSubTypes 注解:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = Cat.class, name = "cat"),
    @JsonSubTypes.Type(value = Dog.class, name = "dog")
})
public abstract class Animal {}

public class Cat extends Animal { public boolean likesCream; }
public class Dog extends Animal { public int boneCount; }

String json = "{\"type\":\"dog\",\"boneCount\":3}";
Animal animal = mapper.readValue(json, Animal.class);

7. 处理未知字段

配置 Jackson 忽略未知字段:

ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

8. 自定义反序列化逻辑

实现 JsonDeserializer 接口:

public class CustomDeserializer extends JsonDeserializer<CustomObject> {
    @Override
    public CustomObject deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonNode node = p.getCodec().readTree(p);
        String value = node.get("field").asText();
        return new CustomObject(value);
    }
}

// 注册自定义反序列化器
SimpleModule module = new SimpleModule();
module.addDeserializer(CustomObject.class, new CustomDeserializer());
mapper.registerModule(module);

9. 处理空值和默认值

允许字段为 null:

public class Person {
    public String middleName; // 默认允许 null
}

设置默认值(使用构造函数或 Builder 模式):

public class Person {
    private String name;
    private int age = 18; // 默认值

    @JsonCreator
    public Person(@JsonProperty("name") String name, @JsonProperty("age") Integer age) {
        this.name = name;
        if (age != null) this.age = age;
    }
}

10. 验证和调试

  • 捕获异常:处理 JsonParseException 和 JsonMappingException

  • 日志记录:启用 Jackson 的 DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES 调试。

  • 单元测试:验证复杂 JSON 的解析逻辑。


常见错误排查

  1. 类型不匹配
    JSON 中的值类型必须与 Java 类字段类型一致(如 int vs String)。

  2. 缺少无参构造函数
    如果类没有无参构造器,需使用 @JsonCreator 注解:

    public class Person {
        private String name;
    
        @JsonCreator
        public Person(@JsonProperty("name") String name) {
            this.name = name;
        }
    }
  3. 循环引用
    避免对象间循环依赖,或使用 @JsonIgnore 忽略某个字段:

    public class User {
        public String name;
        @JsonIgnore
        public User friend; // 忽略循环引用
    }
  4. 泛型类型擦除
    反序列化泛型集合时,需使用 TypeReference

    String json = "[{\"name\":\"Alice\"}]";
    List<Person> list = mapper.readValue(json, new TypeReference<List<Person>>() {});

高级技巧

  • 全局配置 ObjectMapper
    配置日期格式、时区、空值处理等:

    ObjectMapper mapper = new ObjectMapper();
    mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
    mapper.setTimeZone(TimeZone.getTimeZone("UTC"));
    mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
  • 性能优化
    复用 ObjectMapper 实例(线程安全),避免重复创建。

  • JSON 到 Map 的转换

    String json = "{\"key\":\"value\"}";
    Map<String, Object> map = mapper.readValue(json, new TypeReference<Map<String, Object>>() {});

通过以上步骤和技巧,可以高效解决 Java 中 JSON 反序列化的常见问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值