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

如何通过GET接口从Spring Boot向ReactJS传递嵌套Map格式的POJO对象

解决方案

核心问题来自两个常见序列化坑:一是Jackson默认对非String类型的Map键序列化逻辑不符合预期,二是Jackson没有内置Spring/Apache Commons的Pair类型的序列化规则,会导致嵌套结构被拆分或输出异常。按以下步骤操作即可实现结构原样传递:


1. 配置Pair类型的序列化规则

你可以选择全局配置或者字段单独注解两种方式:

全局配置(推荐)

先自定义Pair序列化器(以Spring自带的org.springframework.data.util.Pair为例,Apache Commons Pair仅需替换对应包路径即可):

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.springframework.data.util.Pair;
import java.io.IOException;

public class PairSerializer extends StdSerializer<Pair<?, ?>> {
    public PairSerializer() {
        super(Pair.class);
    }

    @Override
    public void serialize(Pair<?, ?> pair, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeStartObject();
        gen.writeObjectField("left", pair.getFirst());
        gen.writeObjectField("right", pair.getSecond());
        gen.writeEndObject();
    }
}

再把序列化器注册到Spring Boot的Jackson全局配置中:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

@Configuration
public class JacksonConfig {
    @Bean
    public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
        return new Jackson2ObjectMapperBuilder()
                .serializerByType(Pair.class, new PairSerializer())
                // 可选配置:保留Map中的空值字段
                .featuresToEnable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_NULL_MAP_VALUES);
    }
}

单独注解配置

如果不想全局修改,也可以在返回Map的对应字段上添加序列化注解:

@JsonSerialize(using = PairSerializer.class)
private Map<Integer, Pair<Map<String,String>,String>> nestedMap;

2. 明确接口返回的泛型类型

避免因为Java泛型擦除导致Jackson无法识别嵌套结构,Controller层的接口返回值必须写全泛型类型,不要用Object或无泛型的Map承接:

@GetMapping("/getNestedData")
public ResponseEntity<Map<Integer, Pair<Map<String, String>, String>>> getNestedData() {
    // 你的业务逻辑生成对应嵌套结构
    Map<Integer, Pair<Map<String, String>, String>> result = yourService.buildNestedMap();
    return ResponseEntity.ok(result);
}

3. React侧接收验证

受JSON规范限制,Java侧的Integer类型Map键传到JS侧会自动转为字符串类型的数字,但JS支持直接用数字索引访问对象属性,结构完全和Java侧一致,使用无影响:

// 以axios请求为例
axios.get('/getNestedData').then(res => {
  const nestedMap = res.data;
  // 示例访问:取键为1的Pair的right值
  console.log(nestedMap[1].right);
  // 示例访问:取键为2的Pair的left中key为"userName"的值
  console.log(nestedMap[2].left.userName);
})

兜底方案:用VO类替换嵌套泛型

如果嵌套泛型过深还是出现序列化异常,直接定义结构对齐的VO类即可完全规避泛型问题:

// 对应Pair结构
public class PairVO {
    private Map<String, String> left;
    private String right;
    // 补全getter、setter
}

接口返回类型改为Map<Integer, PairVO>即可,序列化结构和原嵌套Map完全一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 15:36:03