偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

震驚!50% 的 Java 程序員都不知道的 Jackson 高階用法(含工具類封裝)

開發(fā) 前端
Jackson 的功能遠(yuǎn)不止于此,建議在實踐中結(jié)合官方文檔深入探索,例如多態(tài)序列化、自定義模塊、性能調(diào)優(yōu)等,能讓你的 JSON 處理能力更上一層樓。?

在當(dāng)下的 Java 開發(fā)中,JSON 數(shù)據(jù)處理已經(jīng)成為繞不開的核心技能。無論是 Web API、微服務(wù)通信,還是前后端交互,JSON 都是事實上的通用標(biāo)準(zhǔn)。

在眾多 JSON 解析框架中,Jackson 以性能優(yōu)越、功能完備、生態(tài)豐富而脫穎而出,幾乎成為企業(yè)級 Java 項目的首選工具。

但很多開發(fā)者對 Jackson 的使用仍停留在最基本的“對象與 JSON 字符串互轉(zhuǎn)”。事實上,Jackson 提供了大量高級特性,能夠幫助我們處理復(fù)雜業(yè)務(wù)場景,例如:

  • 統(tǒng)一日期格式
  • 處理嵌套對象與集合
  • 動態(tài)字段過濾
  • 操作 JSON 樹模型

本文將基于實際開發(fā)場景,逐步解析 Jackson 的高階用法,并給出一個經(jīng)過封裝的 工具類 JacksonUtils,幫助你在日常開發(fā)中高效、優(yōu)雅地處理 JSON 數(shù)據(jù)。

典型場景與解決方案

場景一:復(fù)雜對象的序列化與反序列化

需求:將 Java 對象轉(zhuǎn)為 JSON 字符串,或從 JSON 恢復(fù)成 Java 對象。方案:使用 ObjectMapper,并結(jié)合注解控制序列化行為。

import com.fasterxml.jackson.databind.ObjectMapper;


ObjectMapper mapper = new ObjectMapper();


// 對象轉(zhuǎn) JSON
String json = mapper.writeValueAsString(user);


// JSON 轉(zhuǎn)對象
User user = mapper.readValue(json, User.class);

場景二:統(tǒng)一日期格式

需求:保證 JSON 中的日期字段格式統(tǒng)一,支持 java.util.Date 與 java.time.LocalDateTime。方案:注冊 JavaTimeModule 并指定格式化規(guī)則。

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);
        }
    }
}

場景三:嵌套對象與集合處理

需求:解析包含復(fù)雜嵌套結(jié)構(gòu)的 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 轉(zhuǎn) 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 轉(zhuǎn)復(fù)雜對象失敗", e);
        }
    }
}

場景四:動態(tài)字段過濾

需求:根據(jù)業(yè)務(wù)場景動態(tài)控制字段序列化(如隱藏敏感信息)。方案:使用 @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 數(shù)據(jù)節(jié)點,支持動態(tài)新增、修改、刪除字段。方案:使用 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 轉(zhuǎn) 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 節(jié)點失敗", e);
        }
    }
}

完整工具類封裝

結(jié)合以上所有功能,我們封裝了一個通用的 JacksonUtils 工具類,位于路徑:

/src/main/java/com/icoderoad/utils/JacksonUtils.java

它提供:

  • 對象與 JSON 的互轉(zhuǎn)
  • 日期統(tǒng)一處理
  • 集合與復(fù)雜嵌套結(jié)構(gòu)解析
  • 動態(tài)字段過濾
  • 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 轉(zhuǎn)換、日期格式化、集合解析、字段過濾、樹模型操作等功能
 */
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);
    }


    /** 對象轉(zhuǎn) JSON 字符串 */
    public static String toJson(Object obj) {
        try {
            return mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("對象轉(zhuǎn) JSON 失敗", e);
        }
    }


    /** JSON 字符串轉(zhuǎn)對象 */
    public static <T> T toObject(String json, Class<T> clazz) {
        try {
            return mapper.readValue(json, clazz);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("JSON 轉(zhuǎn)對象失敗", e);
        }
    }


    /** JSON 轉(zhuǎn) 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 轉(zhuǎn) List 失敗", e);
        }
    }


    /** JSON 轉(zhuǎn)復(fù)雜對象(如 Map、嵌套結(jié)構(gòu)) */
    public static <T> T toComplexObject(String json, TypeReference<T> typeReference) {
        try {
            return mapper.readValue(json, typeReference);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("JSON 轉(zhuǎn)復(fù)雜對象失敗", e);
        }
    }


    /** 指定過濾字段進(jìn)行序列化 */
    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 轉(zhuǎn) JsonNode */
    public static JsonNode toJsonNode(String json) {
        try {
            return mapper.readTree(json);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("JSON 轉(zhuǎn) 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 節(jié)點失敗", e);
        }
    }
}

最佳實踐建議

  1. 單例模式:ObjectMapper 是線程安全的,應(yīng)全局復(fù)用。
  2. 異常處理:工具類中統(tǒng)一封裝異常,避免業(yè)務(wù)代碼重復(fù) try-catch。
  3. 統(tǒng)一日期:推薦使用 Java 8 的 LocalDateTime,避免 Date 的線程安全問題。
  4. 字段控制:通過注解和過濾器靈活控制 JSON 輸出。
  5. 性能優(yōu)化:大數(shù)據(jù)量場景下可考慮 Jackson Streaming API (JsonParser / JsonGenerator)。

結(jié)語

掌握 Jackson 不僅僅是學(xué)會“對象和 JSON 的互轉(zhuǎn)”,而是要善用其豐富的生態(tài)與擴展能力。

通過本文的工具類與實戰(zhàn)案例,你可以:

  • 高效應(yīng)對各種 JSON 場景
  • 統(tǒng)一團(tuán)隊代碼風(fēng)格
  • 顯著提升開發(fā)效率與代碼質(zhì)量

Jackson 的功能遠(yuǎn)不止于此,建議在實踐中結(jié)合官方文檔深入探索,例如多態(tài)序列化、自定義模塊、性能調(diào)優(yōu)等,能讓你的 JSON 處理能力更上一層樓。

責(zé)任編輯:武曉燕 來源: 路條編程
相關(guān)推薦

2019-07-12 15:28:41

緩存數(shù)據(jù)庫瀏覽器

2021-03-01 19:13:45

YAML程序員數(shù)據(jù)

2021-02-08 22:32:43

程序員 靜態(tài)網(wǎng)頁

2018-05-08 15:30:46

程序員代碼框架

2022-08-08 11:13:35

API接口前端

2011-08-23 13:50:17

程序員

2022-10-29 17:34:18

JVMJava

2020-12-21 09:00:04

MySQL緩存SQL

2018-09-20 17:05:01

前端程序員JavaScript

2021-02-23 07:10:54

Redis數(shù)據(jù)庫緩存

2020-12-21 09:44:53

MySQL查詢緩存數(shù)據(jù)庫

2013-11-21 13:35:19

程序員牛人

2020-07-29 09:53:09

VSCode編碼工具插件

2010-10-19 15:31:44

Java

2025-04-17 02:30:00

2017-04-21 08:18:14

Java程序員反射機制

2010-08-23 09:56:09

Java性能監(jiān)控

2021-11-12 10:05:19

跳表BAT面試

2024-10-22 09:03:35

前端signalAPI

2020-08-05 12:17:00

C語言代碼分配
點贊
收藏

51CTO技術(shù)棧公眾號