50% 的 Java 程序员都不知道的 Jackson 高级用法!(附工具类封装)

在现代 Java 开发中,JSON 处理是一项基础且关键的技能。Jackson 作为业界领先的 JSON 处理库,凭借其高性能、灵活性和丰富的特性,成为了大多数 Java 项目的首选。本文将结合实际场景,深入讲解 Jackson 的实战应用,并提供一个封装完善的工具类,帮助你高效处理 JSON 数据。

一、典型应用场景与解决方案

场景 1:复杂对象的序列化与反序列化

需求:将 Java 对象转换为 JSON 字符串,或从 JSON 字符串还原为 Java 对象。

解决方案:使用 Jackson 的ObjectMapper进行基础转换,通过注解控制序列化行为。

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.LocalDateTime;

// 用户类示例
@JsonInclude(JsonInclude.Include.NON_NULL) // 忽略null字段
class User {
    @JsonProperty("user_id") // 自定义JSON字段名
    private String userId;
    private String username;
    private LocalDateTime createTime;
    
    // 构造方法、Getter和Setter略
}

// 工具类方法
public class JacksonUtils {
    private static final ObjectMapper mapper = new ObjectMapper();
    
    // 对象转JSON字符串
    public static String toJson(Object obj) {
        try {
            return mapper.writeValueAsString(obj);
        } catch (Exception e) {
            throw new RuntimeException("JSON序列化失败", e);
        }
    }
    
    // JSON字符串转对象
    public static <T> T toObject(String json, Class<T> clazz) {
        try {
            return mapper.readValue(json, clazz);
        } catch (Exception e) {
            throw new RuntimeException("JSON反序列化失败", e);
        }
    }
}

// 使用示例
User user = new User("1001", "john_doe", LocalDateTime.now());
String json = JacksonUtils.toJson(user);
User parsedUser = JacksonUtils.toObject(json, User.class);

场景 2:处理日期格式

需求:统一 JSON 中的日期格式,支持多种日期类型(如java.util.Date、java.time.LocalDateTime)。

解决方案:注册 JavaTimeModule 并配置日期格式化。

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();
        
        // 配置Java 8日期时间模块
        JavaTimeModule timeModule = new JavaTimeModule();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT);
        
        // 注册LocalDateTime序列化器和反序列化器
        timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
        timeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
        
        mapper.registerModule(timeModule);
    }
    
    // 新增支持日期格式化的转换方法
    public static String toJsonWithFormat(Object obj) {
        return toJson(obj); // 使用已配置的mapper
    }
}

场景 3:处理嵌套对象与集合

需求:处理包含复杂嵌套结构的 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;
    
    // 构造方法、Getter和Setter略
}

// 商品类示例
class Product {
    private String productId;
    private String name;
    private double price;
    
    // 构造方法、Getter和Setter略
}

public class JacksonUtils {
    // 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 (Exception 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 (Exception e) {
            throw new RuntimeException("JSON转复杂对象失败", e);
        }
    }
}

// 使用示例
String jsonList = "[{"productId":"P001","name":"iPhone","price":9999.0}]";
List<Product> productList = JacksonUtils.toList(jsonList, Product.class);

// 处理复杂嵌套结构
TypeReference<Map<String, List<Order>>> typeRef = new TypeReference<>() {};
Map<String, List<Order>> resultMap = JacksonUtils.toComplexObject(jsonString, typeRef);

场景 4:动态过滤字段

需求:根据不同场景,动态控制哪些字段需要序列化或反序列化(如敏感信息过滤)。

解决方案:使用@JsonFilter注解和SimpleFilterProvider。

import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;

// 用户类添加过滤器注解
@JsonFilter("userFilter")
class User {
    private String userId;
    private String username;
    private String password; // 敏感字段
    private String email;
    
    // 构造方法、Getter和Setter略
}

public class JacksonUtils {
    // 过滤指定字段
    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 (Exception e) {
            throw new RuntimeException("带过滤的JSON序列化失败", e);
        }
    }
}

// 使用示例:过滤密码字段
User user = new User("1001", "john_doe", "123456", "john@example.com");
String safeJson = JacksonUtils.toJsonWithFilter(user, "userFilter", "password");

场景 5:处理 JSON 树模型

需求:直接操作 JSON 数据结构,动态增删改查节点。

解决方案:使用 Jackson 的树模型 API(JsonNode)。

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class JacksonUtils {
    // 解析JSON字符串为JsonNode
    public static JsonNode toJsonNode(String json) {
        try {
            return mapper.readTree(json);
        } catch (Exception 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;
    }
    
    // 修改JsonNode并转换为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);
            } // 其他类型可扩展
            
            return node.toString();
        } catch (Exception e) {
            throw new RuntimeException("修改JSON节点失败", e);
        }
    }
}

// 使用示例
String json = "{"name":"Alice","age":30}";
JsonNode node = JacksonUtils.toJsonNode(json);
String name = JacksonUtils.getNodeValue(node, "name"); // "Alice"
String modifiedJson = JacksonUtils.modifyNode(json, "age", 31);

二、完整工具类封装

下面是一个完整的 Jackson 工具类,集成了上述所有功能:

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.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;
import java.util.Map;

/**
 * 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 {
        // 初始化ObjectMapper
        mapper = new ObjectMapper();
        
        // 配置序列化选项
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 忽略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;
    }
    
    /**
     * 修改JsonNode并转换为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);
        }
    }
}

三、最佳实践建议

  1. 单例模式:ObjectMapper线程安全,应全局共享一个实例。
  2. 异常处理:工具类中封装异常处理,避免业务代码中重复 try-catch。
  3. 日期统一:使用 Java 8 日期时间 API,避免java.util.Date的线程安全问题。
  4. 字段控制:通过注解(如@JsonInclude)和过滤器动态控制序列化行为。
  5. 性能优化:大量数据处理时,考虑使用 Jackson 的流式 API(JsonParser/JsonGenerator)。

通过这个工具类和实战方案,你可以轻松应对日常开发中的各种 JSON 处理需求,提高代码质量和开发效率。Jackson 的强大远不止于此,建议深入研究其官方文档,探索更多高级特性

原文链接:,转发请注明来源!