震惊!50% 的 Java 程序员都不知道的 Jackson 高阶用法-含工具类封装

在当下的 Java 开发中,JSON 数据处理已经成为绕不开的核心技能。无论是 Web API、微服务通信,还是前后端交互,JSON 都是实际上的通用标准。
在众多 JSON 解析框架中,Jackson 以性能优越、功能完备、生态丰富而脱颖而出,几乎成为企业级 Java 项目的首选工具。
但许多开发者对 Jackson 的使用仍停留在最基本的“对象与 JSON 字符串互转”。实际上,Jackson 提供了大量高级特性,能够协助我们处理复杂业务场景,例如:
- 统一日期格式
- 处理嵌套对象与集合
- 动态字段过滤
- 操作 JSON 树模型
本文将基于实际开发场景,逐步解析 Jackson 的高阶用法,并给出一个经过封装的 工具类 JacksonUtils,协助你在日常开发中高效、优雅地处理 JSON 数据。
典型场景与解决方案
场景一:复杂对象的序列化与反序列化
需求:将 Java 对象转为 JSON 字符串,或从 JSON 恢复成 Java 对象。方案:使用 ObjectMapper,并结合注解控制序列化行为。
import com.fasterxml.jackson.databind.ObjectMapper;
ObjectMapper mapper = new ObjectMapper();
// 对象转 JSON
String json = mapper.writeValueAsString(user);
// JSON 转对象
User user = mapper.readValue(json, User.class);
场景二:统一日期格式
需求:保证 JSON 中的日期字段格式统一,支持 java.util.Date 与 java.time.LocalDateTime。方案:注册 JavaTimeModule 并指定格式化规则。
package com.icoderoad.utils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class JacksonUtils {
private static final ObjectMapper mapper;
private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
static {
mapper = new ObjectMapper();
JavaTimeModule timeModule = new JavaTimeModule();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT);
timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
timeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
mapper.registerModule(timeModule);
}
public static String toJsonWithFormat(Object obj) {
try {
return mapper.writeValueAsString(obj);
} catch (Exception e) {
throw new RuntimeException("日期格式化失败", e);
}
}
}
场景三:嵌套对象与集合处理
需求:解析包含复杂嵌套结构的 JSON(如订单、商品、分类)。方案:借助 TypeReference 处理泛型集合。
import com.fasterxml.jackson.core.type.TypeReference;
import java.util.List;
import java.util.Map;
class Order {
private String orderId;
private List<Product> products;
private Map<String, Object> extraInfo;
}
class Product {
private String productId;
private String name;
private double price;
}
public class JacksonUtils {
public static <T> List<T> toList(String json, Class<T> elementClass) {
try {
return mapper.readValue(json,
mapper.getTypeFactory().constructCollectionType(List.class, elementClass));
} catch (Exception e) {
throw new RuntimeException("JSON 转 List 失败", e);
}
}
public static <T> T toComplexObject(String json, TypeReference<T> typeReference) {
try {
return mapper.readValue(json, typeReference);
} catch (Exception e) {
throw new RuntimeException("JSON 转复杂对象失败", e);
}
}
}
场景四:动态字段过滤
需求:根据业务场景动态控制字段序列化(如隐藏敏感信息)。方案:使用 @JsonFilter 配合 SimpleFilterProvider。
import com.fasterxml.jackson.annotation.JsonFilter;
@JsonFilter("userFilter")
class User {
private String userId;
private String username;
private String password; // 敏感字段
private String email;
}
public class JacksonUtils {
public static String toJsonWithFilter(Object obj, String filterName, String... fieldsToExclude) {
try {
var filters = new com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider()
.addFilter(filterName,
com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter.serializeAllExcept(fieldsToExclude));
return mapper.writer(filters).writeValueAsString(obj);
} catch (Exception e) {
throw new RuntimeException("字段过滤失败", e);
}
}
}
场景五:JSON 树模型操作
需求:直接操作 JSON 数据节点,支持动态新增、修改、删除字段。方案:使用 JsonNode 与 ObjectNode。
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class JacksonUtils {
public static JsonNode toJsonNode(String json) {
try {
return mapper.readTree(json);
} catch (Exception e) {
throw new RuntimeException("JSON 转 JsonNode 失败", e);
}
}
public static String modifyNode(String json, String fieldName, Object newValue) {
try {
ObjectNode node = (ObjectNode) mapper.readTree(json);
node.putPOJO(fieldName, newValue);
return node.toString();
} catch (Exception e) {
throw new RuntimeException("修改 JSON 节点失败", e);
}
}
}
完整工具类封装
结合以上所有功能,我们封装了一个通用的 JacksonUtils 工具类,位于路径:
/src/main/java/com/icoderoad/utils/JacksonUtils.java
它提供:
- 对象与 JSON 的互转
- 日期统一处理
- 集合与复杂嵌套结构解析
- 动态字段过滤
- JSON 树模型操作
package com.icoderoad.utils;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
/**
* Jackson JSON 工具类
* 提供对象-JSON 转换、日期格式化、集合解析、字段过滤、树模型操作等功能
*/
public class JacksonUtils {
private static final ObjectMapper mapper;
private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
static {
mapper = new ObjectMapper();
// 序列化时忽略 null 字段
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// 反序列化时忽略未知字段
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 配置 Java 8 时间模块
JavaTimeModule timeModule = new JavaTimeModule();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT);
timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
timeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
mapper.registerModule(timeModule);
}
/** 对象转 JSON 字符串 */
public static String toJson(Object obj) {
try {
return mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new RuntimeException("对象转 JSON 失败", e);
}
}
/** JSON 字符串转对象 */
public static <T> T toObject(String json, Class<T> clazz) {
try {
return mapper.readValue(json, clazz);
} catch (JsonProcessingException e) {
throw new RuntimeException("JSON 转对象失败", e);
}
}
/** JSON 转 List */
public static <T> List<T> toList(String json, Class<T> elementClass) {
try {
return mapper.readValue(json,
mapper.getTypeFactory().constructCollectionType(List.class, elementClass));
} catch (JsonProcessingException e) {
throw new RuntimeException("JSON 转 List 失败", e);
}
}
/** JSON 转复杂对象(如 Map、嵌套结构) */
public static <T> T toComplexObject(String json, TypeReference<T> typeReference) {
try {
return mapper.readValue(json, typeReference);
} catch (JsonProcessingException e) {
throw new RuntimeException("JSON 转复杂对象失败", e);
}
}
/** 指定过滤字段进行序列化 */
public static String toJsonWithFilter(Object obj, String filterName, String... fieldsToExclude) {
try {
FilterProvider filters = new SimpleFilterProvider()
.addFilter(filterName, SimpleBeanPropertyFilter.serializeAllExcept(fieldsToExclude));
return mapper.writer(filters).writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new RuntimeException("JSON 序列化字段过滤失败", e);
}
}
/** JSON 转 JsonNode */
public static JsonNode toJsonNode(String json) {
try {
return mapper.readTree(json);
} catch (JsonProcessingException e) {
throw new RuntimeException("JSON 转 JsonNode 失败", e);
}
}
/** 获取 JsonNode 中指定字段值 */
public static String getNodeValue(JsonNode node, String fieldName) {
JsonNode valueNode = node.get(fieldName);
return valueNode != null ? valueNode.asText() : null;
}
/** 修改 JSON 中指定字段 */
public static String modifyNode(String json, String fieldName, Object newValue) {
try {
ObjectNode node = (ObjectNode) mapper.readTree(json);
if (newValue instanceof String) {
node.put(fieldName, (String) newValue);
} else if (newValue instanceof Integer) {
node.put(fieldName, (Integer) newValue);
} else if (newValue instanceof Boolean) {
node.put(fieldName, (Boolean) newValue);
} else if (newValue instanceof Double) {
node.put(fieldName, (Double) newValue);
} else {
node.putPOJO(fieldName, newValue);
}
return node.toString();
} catch (JsonProcessingException e) {
throw new RuntimeException("修改 JSON 节点失败", e);
}
}
}
最佳实践提议
- 单例模式:ObjectMapper 是线程安全的,应全局复用。
- 异常处理:工具类中统一封装异常,避免业务代码重复 try-catch。
- 统一日期:推荐使用 Java 8 的 LocalDateTime,避免 Date 的线程安全问题。
- 字段控制:通过注解和过滤器灵活控制 JSON 输出。
- 性能优化:大数据量场景下可思考 Jackson Streaming API (JsonParser / JsonGenerator)。
结语
掌握 Jackson 不仅仅是学会“对象和 JSON 的互转”,而是要善用其丰富的生态与扩展能力。
通过本文的工具类与实战案例,你可以:
- 高效应对各种 JSON 场景
- 统一团队代码风格
- 显著提升开发效率与代码质量
Jackson 的功能远不止于此,提议在实践中结合官方文档深入探索,例如多态序列化、自定义模块、性能调优等,能让你的 JSON 处理能力更上一层楼。

收藏了,感谢分享