You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中JSON请求体(JSON-payload)的结构化与修改优化方案咨询

Great question—string-based JSON templates like the one you're using quickly become unmanageable, especially as the payload grows or other team members need to work with it. Let's look at three far better approaches that'll make your code more readable, maintainable, and less error-prone:


This is the best long-term solution because it’s type-safe, enables compile-time checks, and makes the JSON structure explicit through Java objects. We’ll use Jackson (one of the most popular JSON libraries for Java), but Gson works just as well.

Step 1: Define POJO Classes

Create classes that mirror your JSON structure:

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;

// Root level of the payload
public class RequestRoot {
    @JsonProperty("request")
    private JsonRequest request;

    // Getters and setters (or use Lombok to auto-generate them)
    public JsonRequest getRequest() { return request; }
    public void setRequest(JsonRequest request) { this.request = request; }
}

public class JsonRequest {
    @JsonProperty("jsonRequest")
    private Alpha alpha;

    public Alpha getAlpha() { return alpha; }
    public void setAlpha(Alpha alpha) { this.alpha = alpha; }
}

public class Alpha {
    @JsonProperty("Bravo")
    private List<BravoItem> bravo;
    @JsonProperty("Desert")
    private List<DesertItem> desert;

    public List<BravoItem> getBravo() { return bravo; }
    public void setBravo(List<BravoItem> bravo) { this.bravo = bravo; }
    public List<DesertItem> getDesert() { return desert; }
    public void setDesert(List<DesertItem> desert) { this.desert = desert; }
}

public class BravoItem {
    @JsonProperty("Delta")
    private String delta;

    public String getDelta() { return delta; }
    public void setDelta(String delta) { this.delta = delta; }
}

public class DesertItem {
    private int id;
    private String name;
    private String age;
    private String city;
    private String street;

    // Getters and setters
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getAge() { return age; }
    public void setAge(String age) { this.age = age; }
    public String getCity() { return city; }
    public void setCity(String city) { this.city = city; }
    public String getStreet() { return street; }
    public void setStreet(String street) { this.street = street; }
}

Step 2: Build and Serialize the Payload

Create instances of these classes, set your dynamic values, then convert to JSON:

import com.fasterxml.jackson.databind.ObjectMapper;

public class PayloadGenerator {
    public String generateDynamicPayload(String lenaStreet, String moaStreet) throws Exception {
        // Initialize the fixed parts of the payload
        RequestRoot root = new RequestRoot();
        JsonRequest jsonRequest = new JsonRequest();
        Alpha alpha = new Alpha();

        BravoItem bravoItem = new BravoItem();
        bravoItem.setDelta("something");
        alpha.setBravo(List.of(bravoItem));

        // Populate dynamic and fixed Desert items
        DesertItem lena = new DesertItem();
        lena.setId(1);
        lena.setName("Lena");
        lena.setAge("25");
        lena.setCity("Florida");
        lena.setStreet(lenaStreet); // Dynamic value

        DesertItem moa = new DesertItem();
        moa.setId(2);
        moa.setName("Moa");
        moa.setAge("21");
        moa.setCity("Mexico");
        moa.setStreet(moaStreet); // Dynamic value

        DesertItem nils = new DesertItem();
        nils.setId(3);
        nils.setName("Nils");
        nils.setAge("29");
        nils.setCity("Tampas");
        nils.setStreet("Tampas Street"); // Fixed value

        alpha.setDesert(List.of(lena, moa, nils));
        jsonRequest.setAlpha(alpha);
        root.setRequest(jsonRequest);

        // Convert to pretty-printed JSON
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(root);
    }
}

Usage

PayloadGenerator generator = new PayloadGenerator();
String payload = generator.generateDynamicPayload("Florida Street", "Mexico Street");

Why this works:

  • No more messy string concatenation or format placeholders
  • Compile-time validation of fields (typos in field names will throw errors immediately)
  • Easy to update the payload structure (just modify the POJOs)
  • Team members can quickly understand the JSON structure from the classes

2. Directly Manipulate JSON Nodes (For Quick Modifications)

If you don’t want to write full POJOs, you can use Jackson’s ObjectNode to parse a base JSON string and modify only the dynamic fields. This is great for one-off changes.

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class DynamicNodePayloadGenerator {
    public String generatePayload(String lenaStreet, String moaStreet) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        // Base payload with placeholder values for dynamic fields
        String baseJson = "{ \"request\": { \"jsonRequest\": { \"Alpha\": { \"Bravo\": [ { \"Delta\": \"something\" } ], \"Desert\": [ { \"id\": 1, \"name\": \"Lena\", \"age\": \"25\", \"city\": \"Florida\", \"street\": \"\" }, { \"id\": 2, \"name\": \"Moa\", \"age\": \"21\", \"city\": \"Mexico\", \"street\": \"\" }, { \"id\": 3, \"name\": \"Nils\", \"age\": \"29\", \"city\": \"Tampas\", \"street\": \"Tampas Street\" } ] } } }";
        
        // Parse base JSON into a mutable ObjectNode
        ObjectNode root = (ObjectNode) mapper.readTree(baseJson);
        
        // Navigate to the Desert array and update dynamic fields
        ArrayNode desertArray = (ArrayNode) root.path("request")
                                           .path("jsonRequest")
                                           .path("Alpha")
                                           .path("Desert");
        
        ((ObjectNode) desertArray.get(0)).put("street", lenaStreet);
        ((ObjectNode) desertArray.get(1)).put("street", moaStreet);
        
        return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(root);
    }
}

Pros:

  • No need to write POJOs
  • Fast to implement for small changes

Cons:

  • No type safety (typos in field names will only be caught at runtime)
  • Harder to follow for complex nested structures

3. Use a Template Engine (Freemarker)

If you prefer a template-based approach but want something cleaner than String.format(), use a dedicated template engine like Freemarker.

Step 1: Create a JSON Template File (payload.ftl)

Place this file in your classpath:

{
  "request": {
    "jsonRequest": {
      "Alpha": {
        "Bravo": [
          { "Delta": "something" }
        ],
        "Desert": [
          {
            "id": 1,
            "name": "Lena",
            "age": "25",
            "city": "Florida",
            "street": "${lenaStreet}"
          },
          {
            "id": 2,
            "name": "Moa",
            "age": "21",
            "city": "Mexico",
            "street": "${moaStreet}"
          },
          {
            "id": 3,
            "name": "Nils",
            "age": "29",
            "city": "Tampas",
            "street": "Tampas Street"
          }
        ]
      }
    }
  }
}

Step 2: Load and Process the Template

import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

public class FreemarkerPayloadGenerator {
    public String generatePayload(String lenaStreet, String moaStreet) throws Exception {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_32);
        cfg.setClassForTemplateLoading(FreemarkerPayloadGenerator.class, "/");
        
        Template template = cfg.getTemplate("payload.ftl");
        Map<String, Object> data = new HashMap<>();
        data.put("lenaStreet", lenaStreet);
        data.put("moaStreet", moaStreet);
        
        StringWriter writer = new StringWriter();
        template.process(data, writer);
        
        return writer.toString();
    }
}

Pros:

  • JSON structure is visually identical to the final payload
  • Easy to modify the template without touching Java code

Cons:

  • Adds an extra dependency
  • No type safety for dynamic values

Final Recommendation

Stick with the POJO + Jackson/Gson approach for most cases—it’s the most maintainable and robust option. Use the JSON node approach for quick fixes, and the template engine only if you need non-developers to edit the payload structure.

内容的提问来源于stack exchange,提问作者klabbaparn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 15:57:39