成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

動態 JSON 字段太頭疼?SpringBoot + Jackson 兩個注解輕松搞定序列化!

開發 前端
在開發 Web 接口時,經常會碰到一種情況:前端或第三方返回的 JSON 字段是動態變化的,有些字段你一開始知道,有些字段卻是根據用戶輸入、配置項或業務狀態“臨時冒出來”的。

在開發 Web 接口時,經常會碰到一種情況:前端或第三方返回的 JSON 字段是動態變化的,有些字段你一開始知道,有些字段卻是根據用戶輸入、配置項或業務狀態“臨時冒出來”的。

你可能一開始會想到用 Map<String, Object> 來兜底處理這些字段,但這種方式會讓數據結構不清晰、可維護性差。 其實 Jackson 已經為我們準備好了“動態屬性處理器”:@JsonAnySetter 和 @JsonAnyGetter,它們可以把這些不確定字段收進來、再自動輸出,不影響已有字段邏輯。

Jackson 注解的“萬能抽屜”方案設計

我們可以把處理邏輯想象成一個數據“雜貨鋪”:

  • 常規字段:貨架上擺著 name、age、email 等常用品;
  • 動態字段:顧客突然問你“有沒有咖喱味的洗發水”?雖然你之前沒準備,但你能靈活處理,收進一個 Map,這就是“萬能抽屜”。

使用注解:

目標

Jackson 注解

功能說明

接收未知字段

@JsonAnySetter

反序列化時接收未定義的字段

序列化輸出動態字段

@JsonAnyGetter

序列化時輸出 Map 中的字段

忽略字段

@JsonIgnoreProperties

顯式忽略某些字段

項目結構預覽

src/
├── main/
│   ├── java/
│   │   └── com/
│   │       └── icoderoad/
│   │           └── json/
│   │               └── handler/
│   │                   ├── Person.java
│   │                   ├── JsonController.java
│   │                   └── JsonApplication.java
│   └── resources/
│       ├── templates/
│       │   ├── form.html
│       │   └── result.html
│       └── application.yml

后端核心類

Person.java — 支持動態字段的模型類

package com.icoderoad.json.handler;


import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;


import java.util.HashMap;
import java.util.Map;


/**
 * JSON 映射模型:既支持固定字段,也支持動態字段擴展。
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class Person {


    private String name;
    private int age;


    // 用于存放動態字段
    private Map<String, Object> additionalFields = new HashMap<>();


    public Person() {}


    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }


    @JsonAnySetter
    public void addField(String key, Object value) {
        additionalFields.put(key, value);
    }


    @JsonAnyGetter
    public Map<String, Object> getAdditionalFields() {
        return additionalFields;
    }


    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


public int getAge() {
return age;
	}


public void setAge(int age) {
this.age = age;
	}
}

Spring Boot 控制器:JsonController.java

package com.icoderoad.json.controller;


import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;


import java.util.Map;


/**
 * Web 控制器:展示表單、處理提交、展示結果。
 */
@Controller
@RequestMapping("/person")
public class JsonController {


    @GetMapping("/form")
    public String showForm() {
        return "form";
    }


    @PostMapping("/submit")
    public String handleSubmit(
            @RequestParam String name,
            @RequestParam int age,
            @RequestParam Map<String, String> allParams,
            Model model
    ) {
        Person person = new Person();
        person.setName(name);
        person.setAge(age);


        for (Map.Entry<String, String> entry : allParams.entrySet()) {
            String key = entry.getKey();
            if (!key.equals("name") && !key.equals("age")) {
                person.addField(key, entry.getValue());
            }
        }


        model.addAttribute("person", person);
        return "result";
    }
}

application.yml 配置

server:
  port: 8080


spring:
  thymeleaf:
    cache: false
    prefix: classpath:/templates/
    suffix: .html
    mode: HTML

Thymeleaf + Bootstrap 表單頁:form.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>動態字段提交表單</title>
    <link  rel="stylesheet">
</head>
<body class="p-4">
<div class="container">
    <h2>人員信息提交</h2>
    <form method="post" action="/person/submit" id="personForm">
        <div class="mb-3">
            <label class="form-label">姓名</label>
            <input type="text" name="name" class="form-control" required/>
        </div>
        <div class="mb-3">
            <label class="form-label">年齡</label>
            <input type="number" name="age" class="form-control" required/>
        </div>
        <hr>
        <h4>添加自定義字段</h4>
        <div id="dynamicFields"></div>
        <button type="button" class="btn btn-outline-secondary mb-3" onclick="addField()">添加字段</button>
        <br>
        <button type="submit" class="btn btn-primary">提交</button>
    </form>
</div>


<script>
    let fieldCount = 0;


    function addField() {
        const container = document.getElementById("dynamicFields");
        const div = document.createElement("div");
        div.classList.add("mb-2", "row");


        div.innerHTML = `
            <div class="col">
                <input type="text" class="form-control" name="key${fieldCount}" placeholder="字段名" required>
            </div>
            <div class="col">
                <input type="text" class="form-control" name="value${fieldCount}" placeholder="字段值" required>
            </div>
        `;


        container.appendChild(div);


        // 將字段名映射成 key=value 的格式
        fieldCount++;
        document.getElementById("personForm").addEventListener("submit", function (e) {
            const allFields = document.querySelectorAll("#dynamicFields .row");
            allFields.forEach(row => {
                const keyInput = row.querySelector("input[name^='key']");
                const valueInput = row.querySelector("input[name^='value']");
                if (keyInput && valueInput) {
                    const hidden = document.createElement("input");
                    hidden.type = "hidden";
                    hidden.name = keyInput.value;
                    hidden.value = valueInput.value;
                    document.getElementById("personForm").appendChild(hidden);
                }
            });
        }, {once: true});
    }
</script>
</body>
</html>

提交結果展示頁:result.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>提交結果</title>
    <link  rel="stylesheet">
</head>
<body class="p-4">
<div class="container">
    <h2>提交結果</h2>
    <table class="table table-bordered">
        <tr>
            <th>字段</th>
            <th>值</th>
        </tr>
        <tr>
            <td>姓名</td>
            <td th:text="${person.name}">-</td>
        </tr>
        <tr>
            <td>年齡</td>
            <td th:text="${person.age}">-</td>
        </tr>
        <tr th:each="entry : ${person.additionalFields}">
            <td th:text="${entry.key}">字段名</td>
            <td th:text="${entry.value}">字段值</td>
        </tr>
    </table>
    <a href="/person/form" class="btn btn-secondary">重新提交</a>
</div>
</body>
</html>

運行效果演示

  1. 啟動項目后,訪問 http://localhost:8080/person/form
  2. 填寫姓名、年齡,并通過“添加字段”添加任意鍵值;
  3. 點擊提交,跳轉到結果頁展示所有字段(包括動態字段);
  4. 所有數據經由 @JsonAnySetter 和 @JsonAnyGetter 自動解析和序列化。

總結:從動態接收到可視化回顯,一站式搞定

通過本文示例,我們完成了一個支持:

  • 不確定 JSON 字段結構解析(@JsonAnySetter);
  • 可序列化輸出的動態字段模型(@JsonAnyGetter);
  • Web 表單中動態字段可視化輸入與管理(Thymeleaf + JS);
  • 提交后結構化展示所有信息(Bootstrap + 表格)。

如果你正在構建配置平臺、參數模板系統、插件引擎、或者靈活的前后端數據結構模型,本文架構可以直接復用或擴展。

責任編輯:武曉燕 來源: 路條編程
相關推薦

2025-06-03 01:22:00

JavaJSON字段

2025-05-07 09:32:00

2025-06-06 02:00:00

JavaJSON字段

2013-03-11 13:55:03

JavaJSON

2021-11-18 07:39:41

Json 序列化Vue

2009-07-29 13:39:02

JSON序列化和反序列ASP.NET AJA

2018-01-17 16:38:07

MSONJSON序列化

2025-03-03 00:00:55

Spring文件下載開發

2022-08-06 08:41:18

序列化反序列化Hessian

2024-06-28 08:28:43

反序列化filterJson

2024-02-22 08:06:45

JSON策略解析器

2016-10-20 15:54:08

Python數據序列化

2023-10-13 08:28:21

.NET平臺序列化庫

2009-08-24 17:14:08

C#序列化

2025-01-13 12:46:31

SpringBootJacksonJSON

2011-06-01 15:05:02

序列化反序列化

2024-01-30 13:32:51

JSON反序列化序列化

2024-10-07 08:26:53

2011-05-18 15:20:13

XML

2023-12-13 13:49:52

Python序列化模塊
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人亚洲| 日韩欧美黄色 | 亚洲成人一区二区 | 亚洲成网| 国产精品成人免费 | 99久久精品国产一区二区三区 | 中文字幕日韩一区 | 日韩中文一区二区三区 | 久久久久国 | 国产欧美精品区一区二区三区 | 水蜜桃久久夜色精品一区 | 欧美一级大片免费观看 | 国产欧美一区二区三区日本久久久 | 亚洲精品在线播放 | h小视频 | 成人啊啊啊 | 久久福利电影 | 久久久一区二区三区 | 日韩精品在线网站 | 韩日一区 | 一级黄色生活视频 | 91直接看 | 国产日韩久久 | 九色 在线| 九色 在线 | 黑人精品 | 91www在线观看 | 精品av天堂毛片久久久借种 | 亚洲激情视频在线 | 亚洲视频一区二区三区 | 国产精品永久久久久久久www | 欧美成人a∨高清免费观看 欧美日韩中 | 久久小视频| 精品欧美一区二区三区久久久 | 国产精品久久精品 | 久久久免费电影 | 在线免费观看视频你懂的 | 久久久久久久久淑女av国产精品 | 国产精品久久 | 中文字幕亚洲国产 | 国产精品99久久久久久久久 |