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

如何让Java程序按需解析单个Simple对象或List<Simple>并保留原JSON格式?

解决方案

针对你的需求——既支持解析单个Simple对象或Simple数组,又能在序列化时保留原格式(单个对象输出为JSON对象,数组输出为JSON数组),可以通过以下两种方式实现:

方式一:手动判断JSON节点类型解析

先将JSON字符串解析为JsonNode,判断目标字段的节点类型后再分别处理,这种方式直观且灵活:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;

public class ParserDemo {
    private static final ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws Exception {
        // 场景1:数组输入解析为List<Simple>
        String arrayJson = "{\"simple\" : [ {\"name\":\"a\", \"email\" : \"a@z.com\"}, {\"name\":\"b\", \"email\" : \"b@z.com\"} ]}";
        JsonNode arrayNode = objectMapper.readTree(arrayJson).get("simple");
        if (arrayNode.isArray()) {
            List<Simple> simpleList = objectMapper.convertValue(
                arrayNode,
                objectMapper.getTypeFactory().constructCollectionType(List.class, Simple.class)
            );
            System.out.println("解析结果:" + simpleList);
        }

        // 场景2:单个对象输入解析为Simple
        String objectJson = "{\"simple\" : {\"name\":\"c\", \"email\" : \"c@z.com\"} }";
        JsonNode objectNode = objectMapper.readTree(objectJson).get("simple");
        if (objectNode.isObject()) {
            Simple simple = objectMapper.convertValue(objectNode, Simple.class);
            System.out.println("解析结果:" + simple);
        }
    }
}

序列化时直接根据对象类型输出即可,ObjectMapper会自动识别并输出对应格式:

import java.util.Arrays;
import java.util.Map;

// 序列化单个Simple对象
Simple simple = new Simple("c", "c@z.com");
String singleJson = objectMapper.writeValueAsString(Map.of("simple", simple));
// 输出:{"simple":{"name":"c","email":"c@z.com"}}

// 序列化List<Simple>
List<Simple> list = Arrays.asList(new Simple("a", "a@z.com"), new Simple("b", "b@z.com"));
String arrayJson = objectMapper.writeValueAsString(Map.of("simple", list));
// 输出:{"simple":[{"name":"a","email":"a@z.com"},{"name":"b","email":"b@z.com"}]}

方式二:自定义反序列化器(适用于包装类场景)

如果你的业务需要通过包装类统一接收参数,可以给包装类的字段自定义反序列化器,实现自动适配单个对象或数组:

1. 定义包装类

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

class SimpleWrapper {
    @JsonDeserialize(using = SimpleListOrObjectDeserializer.class)
    private Object simple; // 实际类型为Simple或List<Simple>

    // getter、setter
    public Object getSimple() {
        return simple;
    }

    public void setSimple(Object simple) {
        this.simple = simple;
    }
}

2. 实现自定义反序列化器

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;

import java.io.IOException;
import java.util.List;

public class SimpleListOrObjectDeserializer extends JsonDeserializer<Object> {
    private static final ObjectMapper mapper = new ObjectMapper();
    private static final CollectionType LIST_TYPE = mapper.getTypeFactory().constructCollectionType(List.class, Simple.class);

    @Override
    public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonNode node = p.getCodec().readTree(p);
        if (node.isArray()) {
            return mapper.readValue(node.traverse(), LIST_TYPE);
        } else if (node.isObject()) {
            return mapper.readValue(node.traverse(), Simple.class);
        }
        throw new IllegalArgumentException("Unsupported JSON type for 'simple' field");
    }
}

3. 使用示例

public class WrapperDemo {
    private static final ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws Exception {
        // 解析数组输入
        String arrayJson = "{\"simple\" : [ {\"name\":\"a\", \"email\" : \"a@z.com\"}, {\"name\":\"b\", \"email\" : \"b@z.com\"} ]}";
        SimpleWrapper arrayWrapper = objectMapper.readValue(arrayJson, SimpleWrapper.class);
        System.out.println("数组解析结果类型: " + arrayWrapper.getSimple().getClass()); // 输出class java.util.ArrayList

        // 解析单个对象输入
        String objectJson = "{\"simple\" : {\"name\":\"c\", \"email\" : \"c@z.com\"} }";
        SimpleWrapper objectWrapper = objectMapper.readValue(objectJson, SimpleWrapper.class);
        System.out.println("对象解析结果类型: " + objectWrapper.getSimple().getClass()); // 输出class Simple
    }
}

序列化包装类时,ObjectMapper会根据simple字段的实际类型自动输出对应格式,不会将单个对象转为数组。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 07:50:28