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

如何基于Lombok @Builder与Jackson @JsonProperty实现含动态数量递增键名重复对象的模型序列化

Avoid Repetitive Code for Dynamic Numbered Keys in Jackson Serialization

Great question! Having to manually define fields like object1, object2, etc., gets messy fast—especially if you need to support a variable number of these objects. Here are a couple of clean, maintainable solutions that eliminate code duplication while producing the exact JSON structure you need.

Solution 1: Use a Map<String, RandomObject> (Simplest Approach)

Instead of hardcoding individual fields, use a Map where the keys follow the objectN pattern. Jackson will automatically serialize the Map's keys as top-level JSON properties, which matches your required output perfectly.

Implementation Code

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import lombok.Builder;
import lombok.Singular;
import java.util.LinkedHashMap;
import java.util.Map;

@Builder
public class Sample {
    // Use Singular to easily add items one by one via the builder
    @Singular("object")
    private final Map<String, RandomObject> objects = new LinkedHashMap<>();

    // Optional: Enforce the "objectN" key format when adding items
    public static class SampleBuilder {
        public SampleBuilder object(int index, RandomObject obj) {
            if (objects == null) {
                objects = new LinkedHashMap<>();
            }
            objects.put("object" + index, obj);
            return this;
        }
    }

    // Jackson uses this to serialize the Map as top-level properties
    @JsonAnyGetter
    public Map<String, RandomObject> getObjects() {
        return objects;
    }
}

How to Use the Builder

// Build your request with dynamic number of objects
Sample sample = Sample.builder()
    .object(1, new RandomObject("random", true))
    .object(2, new RandomObject("random", false))
    .object(3, new RandomObject("random", true))
    .build();

Why This Works

  • LinkedHashMap preserves the order of your objects (so object1 comes before object2, etc.).
  • @JsonAnyGetter tells Jackson to treat each Map entry as a top-level JSON property instead of nesting them under an objects key.
  • Lombok's @Singular lets you add objects one by one without manually managing the Map.

Solution 2: Use a List<RandomObject> with Custom Serialization

If you prefer working with a List (e.g., for easier iteration or collection operations), you can create a custom Jackson serializer to convert the List into the numbered key structure.

Step 1: Define the Model Class

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Builder;
import lombok.Singular;
import java.util.List;

@Builder
@JsonSerialize(using = SampleSerializer.class)
public class Sample {
    @Singular("object")
    private final List<RandomObject> objects;

    // Getter needed for the serializer to access the list
    public List<RandomObject> getObjects() {
        return objects;
    }
}

Step 2: Create the Custom Serializer

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;

public class SampleSerializer extends JsonSerializer<Sample> {
    @Override
    public void serialize(Sample sample, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeStartObject();
        
        if (sample.getObjects() != null) {
            for (int i = 0; i < sample.getObjects().size(); i++) {
                // Generate "object1", "object2", etc. as keys
                gen.writeObjectField("object" + (i + 1), sample.getObjects().get(i));
            }
        }
        
        gen.writeEndObject();
    }
}

How to Use the Builder

Sample sample = Sample.builder()
    .object(new RandomObject("random", true))
    .object(new RandomObject("random", false))
    .object(new RandomObject("random", true))
    .build();

Pros of This Approach

  • Uses a List, which is more intuitive for managing a collection of identical objects.
  • Full control over the serialization logic (e.g., you could add validation for the number of objects if needed).

Bonus: Adding Deserialization Support (If Needed)

If you also need to parse JSON with these numbered keys back into your model, you can create a custom JsonDeserializer that reads all keys starting with object and maps them to either a Map or List. For example, a deserializer for the List approach would iterate over all JSON properties, filter for objectN keys, sort them, and populate the List.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 07:32:27