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

Spring Boot玩轉(zhuǎn)JSON!解鎖Jackson的八大高階技能,太強(qiáng)了

開發(fā) 前端
本篇文章將介紹使用Jackson庫(kù)處理JSON數(shù)據(jù)的多種高級(jí)技術(shù),涵蓋了JSON解析、查詢、序列化/反序列化控制等核心功能。主要實(shí)現(xiàn)了以下能力:JSON路徑查詢:通過(guò)findValue()和at()方法實(shí)現(xiàn)嵌套JSON結(jié)構(gòu)的深度查詢,多值提?。褐С峙揩@取相同名稱的多個(gè)值。

環(huán)境:SpringBoot3.4.2

1. 簡(jiǎn)介

本篇文章將介紹使用Jackson庫(kù)處理JSON數(shù)據(jù)的多種高級(jí)技術(shù),涵蓋了JSON解析、查詢、序列化/反序列化控制等核心功能。主要實(shí)現(xiàn)了以下能力:

  • JSON路徑查詢:通過(guò)findValue()和at()方法實(shí)現(xiàn)嵌套JSON結(jié)構(gòu)的深度查詢
  • 多值提?。褐С峙揩@取相同名稱的多個(gè)值
  • 視圖控制:使用@JsonView實(shí)現(xiàn)字段級(jí)序列化控制,區(qū)分公開和內(nèi)部視圖
  • 動(dòng)態(tài)屬性處理:通過(guò)@JsonAnySetter/Getter處理未知字段,實(shí)現(xiàn)靈活的動(dòng)態(tài)對(duì)象
  • 對(duì)象展開:使用@JsonUnwrapped將嵌套對(duì)象屬性扁平化到父級(jí)
  • 原始JSON保留:通過(guò)@JsonRawValue保持字符串字段的原始JSON格式

這些功能組合構(gòu)成了強(qiáng)大的JSON數(shù)據(jù)處理能力,適用于API開發(fā)、配置解析、數(shù)據(jù)轉(zhuǎn)換等場(chǎng)景,特別適合需要靈活處理復(fù)雜JSON結(jié)構(gòu)的Java應(yīng)用程序。

2.實(shí)戰(zhàn)案例

2.1 findValue查找值

Jackson中的findValue()方法允許我們?cè)贘SON樹中搜索特定鍵值并獲取其關(guān)聯(lián)的值。首先,我們將使用ObjectMapper將JSON字符串轉(zhuǎn)換為JsonNode,從而創(chuàng)建JSON數(shù)據(jù)的樹形表示:

@Test
public void test1() throws Exception {
  String json = """
      {
        "user": {
          "id": 1,
          "name": "Pack_xg",
          "details": {
            "email": "pack@gmail.com",
            "phone": "18999999999"
          }
        }
      }
      """ ;
  ObjectMapper mapper = new ObjectMapper();
  JsonNode rootNode = mapper.readTree(json) ;


  String email = rootNode.findValue("email").asText();
  System.err.println(email) ;
}
輸出結(jié)果
pack@gmail.com

2.2 優(yōu)雅處理缺失的鍵

在處理 JSON 時(shí),我們可能會(huì)遇到鍵值缺失的情況。當(dāng) JSON 結(jié)構(gòu)中找不到指定鍵時(shí),findValue() 方法將返回 null。如下示例:

@Test
public void test2() throws Exception {
  String json = """
      {
        "user": {
          "id": 1,
          "name": "Pack_xg",
          "details": {
            "phone": "18999999999"
          }
        }
      }
      """ ;
  ObjectMapper mapper = new ObjectMapper();
  JsonNode rootNode = mapper.readTree(json);
  JsonNode emailNode = rootNode.findValue("email");
  System.err.println(emailNode) ;
}
輸出結(jié)果
null

在此示例中,findValue("email") 返回 null,因?yàn)?JSON 中不存在 email 鍵。

2.3 使用 findValues() 方法處理數(shù)組

findValues方法查找指定名稱的JSON對(duì)象字段的方法——包括直接子值和后代值——并將找到的字段作為L(zhǎng)ist返回。

@Test
public void test3() throws Exception {
  String json = """
        {
          "users": [
            { "id": 1, "name": "pack", "details": { "email": "pack@gmail.com" } },
            { "id": 2, "name": "xg", "details": { "email": "xg@qq.com" } }
          ]
        }
      """;
  ObjectMapper mapper = new ObjectMapper();
  JsonNode rootNode = mapper.readTree(json);
  List<String> emails = rootNode.findValues("email")
      .stream()
      .map(JsonNode::asText)
      .toList() ;
  System.err.println(emails) ;
}
輸出結(jié)果
[pack@gmail.com, xg@qq.com]

2.4 處理深度嵌套的key

與其在JSON結(jié)構(gòu)中通過(guò)名稱查找鍵值,我們可使用at()方法定位深層嵌套JSON結(jié)構(gòu)中特定路徑下的字段。如下示例:

@Test
public void test4() throws Exception {
  String json = """
      {
        "company": {
          "dept": {
            "team": {
              "lead": {
                "name": "Pack_xg",
                "details": {
                  "email": "pack@gmail.com"
                }
              }
            }
          }
        }
      }
      """ ;


  ObjectMapper mapper = new ObjectMapper();
  JsonNode rootNode = mapper.readTree(json);
  String email = rootNode.at("/company/dept/team/lead/details/email").asText() ;
  System.err.println(email) ;
}
輸出結(jié)果
pack@gmail.com

此處傳遞給 at() 方法的路徑是一個(gè) JSON 指針,它是一種使用字符串語(yǔ)法遍歷 JSON 文檔的標(biāo)準(zhǔn)化方式。

2.5 使用@JsonView視圖控制字段輸出

用于指示由被注解的方法或字段所定義的屬性所屬視圖(一個(gè)或多個(gè))的注解。示例注解如下:

@JsonView(BasicView.class)

該注解指定,被注解的屬性在處理(序列化、反序列化)由BasicView.class(或其子類)標(biāo)識(shí)的視圖時(shí)將被包含。如果包含多個(gè)視圖類標(biāo)識(shí)符,則該屬性將屬于所有這些視圖。

public class User {
  public interface PublicView {}
  public interface InternalView extends PublicView {}
  @JsonView(PublicView.class)
  private String name;
  @JsonView(InternalView.class)
  private String email;
  @JsonView(InternalView.class)
  private String password;
}

測(cè)試用例

@Test
public void test5() throws Exception {
  User user = new User("Pack_xg", "pack@gmail.com", "123456") ;
  // 使用
  ObjectMapper mapper = new ObjectMapper();
  // 只輸出 public 字段
  String publicJson = mapper
      .writerWithView(User.PublicView.class)
      .writeValueAsString(user);
  System.err.println(publicJson) ;
  // 輸出所有字段
  String internalJson = mapper
      .writerWithView(User.InternalView.class)
      .writeValueAsString(user);
  System.err.println(internalJson) ;
}
輸出結(jié)果
{"name":"Pack_xg"}
{"name":"Pack_xg","email":"pack@gmail.com","password":"123456"}

2.6 處理未知屬性

@JsonAnySetter / @JsonAnyGetter 用于處理 JSON 中可能存在的額外字段,避免反序列化失敗。如下示例:

public class DynamicObject {
  private Long id ;
  private String name ;
  private Map<String, Object> properties = new HashMap<>();
  // ...
  @JsonAnySetter
  public void set(String name, Object value) {
    properties.put(name, value);
  }
  @JsonAnyGetter
  public Map<String, Object> getProperties() {
    return properties;
  }
}
測(cè)試用例
@Test
public void test6() throws Exception {
  String json = """
      {
        "id": 666,
        "name": "Pack_xg",
        "age": 33,
        "details": {
          "phone": "18999999999",
          "addr": "中國(guó)"
        }
      }
      """;
  ObjectMapper objectMapper = new ObjectMapper() ;
  // 反序列化:未知字段會(huì)被 @JsonAnySetter 捕獲
  DynamicObject user = objectMapper.readValue(json, DynamicObject.class);
  System.out.println(user);
  // 序列化:properties 中的內(nèi)容會(huì)被 @JsonAnyGetter 寫回 JSON
  String serializedJson = objectMapper.writeValueAsString(user);
  System.out.println("\n重新序列化后的 JSON:");
  System.out.println(serializedJson);
}
輸出結(jié)果

圖片

2.7 扁平化嵌套對(duì)象

將嵌套對(duì)象的字段“展開”到外層。

public class Order {
  private Long id ;
  private String orderNo ;
  @JsonUnwrapped
  private Address address ;
}
public class Address {
  private String provice;
  private String city ;
  private String county ;
}
測(cè)試用例
@Test
public void test7() throws Exception {
  Order order = new Order(1L, "XP-00001", new Address("新疆", "烏魯木齊", "天山區(qū)")) ;
  ObjectMapper objectMapper = new ObjectMapper() ;
  System.err.println(objectMapper.writeValueAsString(order)) ;
}
輸出結(jié)果
{
  "id" : 1,
  "orderNo" : "XP-00001",
  "provice" : "新疆",
  "city" : "烏魯木齊",
  "county" : "天山區(qū)"
}

2.8 插入原始JSON

@JsonRawValue將一個(gè)字符串字段的內(nèi)容直接作為原始 JSON 片段寫入最終的 JSON 輸出中,而不是將其轉(zhuǎn)義為字符串。這在你需要嵌入已生成的 JSON 或動(dòng)態(tài) JSON 結(jié)構(gòu)時(shí)非常有用。如下示例:

public class Product {
  private String name ;
  private BigDecimal price ;
  /**json字符串內(nèi)容*/
  @JsonRawValue
  private String details ;
}
測(cè)試用例
@Test
public void test7() throws Exception {
  Order order = new Order(1L, "XP-00001", new Address("新疆", "烏魯木齊", "天山區(qū)")) ;
  ObjectMapper objectMapper = new ObjectMapper() ;
  objectMapper.enable(SerializationFeature.INDENT_OUTPUT) ;
  System.err.println(objectMapper.writeValueAsString(order)) ;
}
輸出結(jié)果
{
  "name" : "Spring Boot3實(shí)戰(zhàn)案例200講",
  "price" : 70,
  "details" : {"author": "pack_xg", "page_count": 1000}
}

如果沒(méi)有@JsonRawValue注解,輸出結(jié)果如下:

{
  "name" : "Spring Boot3實(shí)戰(zhàn)案例200講",
  "price" : 70,
  "details" : "{\"author\": \"pack_xg\", \"page_count\": 1000}"
}

字符串被轉(zhuǎn)義了。

責(zé)任編輯:武曉燕 來(lái)源: Springboot全家桶實(shí)戰(zhàn)案例
相關(guān)推薦

2025-01-13 13:47:13

2025-05-14 01:00:00

Spring工具工廠類

2025-03-26 08:28:36

2025-08-07 09:30:57

2013-09-26 11:00:53

2025-01-22 14:02:35

2025-04-10 00:25:00

Spring@JsonView注解

2021-10-22 08:00:00

架構(gòu)開發(fā)技術(shù)

2025-09-01 02:00:00

2009-06-22 14:07:46

JSF優(yōu)勢(shì)

2025-09-08 02:32:00

2011-04-29 09:15:16

Servlet

2024-04-24 09:52:19

云技能云遷移云計(jì)算

2023-03-06 08:03:10

Python可視化工具

2010-11-08 11:31:34

職場(chǎng)

2025-02-08 08:00:00

JavaDeepSeekIDEA

2022-05-30 16:31:08

CSS

2022-01-05 09:26:56

IT災(zāi)難IT故障

2025-01-02 12:51:06

2012-05-10 16:45:54

linux系統(tǒng)
點(diǎn)贊
收藏

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