ObjectMapper的高级使用
时间: 2025-06-10 21:13:36 浏览: 27
<think>我们正在讨论ObjectMapper的高级使用,ObjectMapper是Jackson库中的核心类,用于JSON的序列化和反序列化。高级使用包括:配置选项、处理多态类型、自定义序列化/反序列化、JSON树模型等。下面将介绍几个高级特性,并给出代码示例。1.配置选项:可以设置ObjectMapper的各种特性,例如是否美化输出,是否允许未知属性等。2.处理多态类型:使用@JsonTypeInfo和@JsonSubTypes注解来处理多态类型。3.自定义序列化和反序列化:通过继承StdSerializer和StdDeserializer来实现。4.使用JsonNode(树模型)来动态处理JSON。我们使用Java语言进行演示。首先,我们来看一些配置选项的示例:</think>
### ObjectMapper 的高级使用详解
`ObjectMapper` 是 Jackson 库的核心类,用于处理 JSON 数据的序列化和反序列化。以下是其高级使用方法和示例代码:
---
### 1. **自定义序列化/反序列化**
通过 `SimpleModule` 注册自定义转换器处理特殊对象:
```java
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
// 自定义序列化器
class LocalDateSerializer extends JsonSerializer<LocalDate> {
@Override
public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider provider)
throws IOException {
gen.writeString(value.format(DateTimeFormatter.ISO_LOCAL_DATE));
}
}
// 自定义反序列化器
class LocalDateDeserializer extends JsonDeserializer<LocalDate> {
@Override
public LocalDate deserialize(JsonParser p, DeserializationContext ctx)
throws IOException {
return LocalDate.parse(p.getText(), DateTimeFormatter.ISO_LOCAL_DATE);
}
}
public class AdvancedMapper {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(LocalDate.class, new LocalDateSerializer());
module.addDeserializer(LocalDate.class, new LocalDateDeserializer());
mapper.registerModule(module); // 注册模块
// 测试对象
class User {
public String name;
public LocalDate birthDate;
}
User user = new User();
user.name = "Alice";
user.birthDate = LocalDate.now();
String json = mapper.writeValueAsString(user);
System.out.println(json); // {"name":"Alice","birthDate":"2023-10-05"}
User parsed = mapper.readValue(json, User.class);
System.out.println(parsed.birthDate); // 2023-10-05
}
}
```
---
### 2. **动态忽略属性**
使用 `@JsonView` 实现动态字段过滤:
```java
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
public class ViewExample {
// 定义视图接口
public static class PublicView {}
public static class PrivateView extends PublicView {}
static class User {
@JsonView(PublicView.class)
public String name;
@JsonView(PrivateView.class)
public String password;
}
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
User user = new User();
user.name = "Bob";
user.password = "secret";
// 序列化时选择视图
String publicJson = mapper
.writerWithView(ViewExample.PublicView.class)
.writeValueAsString(user);
System.out.println(publicJson); // {"name":"Bob"}
String privateJson = mapper
.writerWithView(ViewExample.PrivateView.class)
.writeValueAsString(user);
System.out.println(privateJson); // {"name":"Bob","password":"secret"}
}
}
```
---
### 3. **处理多态类型**
通过 `@JsonTypeInfo` 支持继承结构的序列化:
```java
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.ObjectMapper;
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type"
)
@JsonSubTypes({
@JsonSubTypes.Type(value = Cat.class, name = "cat"),
@JsonSubTypes.Type(value = Dog.class, name = "dog")
})
abstract class Animal {
public String name;
}
class Cat extends Animal {
public int lives = 9;
}
class Dog extends Animal {
public boolean goodBoy = true;
}
public class PolymorphicExample {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
Animal cat = new Cat();
cat.name = "Whiskers";
String json = mapper.writeValueAsString(cat);
System.out.println(json);
// {"type":"cat","name":"Whiskers","lives":9}
Animal parsed = mapper.readValue(json, Animal.class);
System.out.println(parsed.getClass().getSimpleName()); // Cat
}
}
```
---
### 4. **JSON 树模型**
使用 `JsonNode` 动态操作 JSON 结构:
```java
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
public class TreeModelExample {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
// 创建新JSON
ObjectNode root = mapper.createObjectNode();
root.put("name", "Charlie");
ArrayNode hobbies = root.putArray("hobbies");
hobbies.add("Reading");
hobbies.add("Hiking");
System.out.println(root.toString());
// {"name":"Charlie","hobbies":["Reading","Hiking"]}
// 修改已有JSON
String inputJson = "{\"city\":\"Paris\",\"population\":2161000}";
ObjectNode node = (ObjectNode) mapper.readTree(inputJson);
node.put("country", "France");
node.put("population", node.get("population").asInt() + 100000);
System.out.println(node.toPrettyString());
/*
{
"city" : "Paris",
"population" : 2261000,
"country" : "France"
}
*/
}
}
```
---
### **关键配置选项**
```java
ObjectMapper mapper = new ObjectMapper()
// 美化输出
.enable(SerializationFeature.INDENT_OUTPUT)
// 允许单引号
.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES)
// 允许注释
.enable(JsonParser.Feature.ALLOW_COMMENTS)
// 未知属性不报错
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
// 空值处理
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
```
---
### **注意事项**
1. 处理循环引用:使用 `@JsonIdentityInfo`
2. 自定义日期格式:`mapper.setDateFormat()`
3. 字段命名策略:`mapper.setPropertyNamingStrategy()`
4. 线程安全:`ObjectMapper` 实例可全局共享
阅读全文
相关推荐



















