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

Spring中无需新增POJO,如何用Jackson嵌套序列化POJO为API响应

解决方案

在Java Spring环境下,不用单独创建Output POJO的话,有以下几种基于Jackson或Spring特性的实现方式:

1. 利用Jackson ObjectNode手动包装

直接通过Jackson的ObjectNode构造顶层对象,将Home实例作为"output"字段的值:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HomeController {

    @GetMapping("/home")
    public ResponseEntity<ObjectNode> getHome() {
        // 初始化已赋值的Home实例
        Home home = new Home();
        home.setNumber(1);
        home.setAddress("chennai");

        ObjectMapper mapper = new ObjectMapper();
        ObjectNode rootNode = mapper.createObjectNode();
        // 将Home对象转换为JsonNode并设置到顶层的output字段
        rootNode.set("output", mapper.valueToTree(home));

        return ResponseEntity.ok(rootNode);
    }
}

2. 结合@JsonRootName与Jackson序列化配置

给Home类添加@JsonRootName注解指定根节点名称,临时开启Jackson的WRAP_ROOT_VALUE特性实现自动包装:

import com.fasterxml.jackson.annotation.JsonRootName;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

// 给Home类添加JsonRootName注解
@JsonRootName("output")
public class Home {
    private int number;
    private String address;

    // getter、setter方法
    public int getNumber() { return number; }
    public void setNumber(int number) { this.number = number; }
    public String getAddress() { return address; }
    public void setAddress(String address) { this.address = address; }
}

@RestController
public class HomeController {

    @GetMapping("/home")
    public ResponseEntity<String> getHome() throws Exception {
        Home home = new Home();
        home.setNumber(1);
        home.setAddress("chennai");

        ObjectMapper mapper = new ObjectMapper();
        // 临时开启包装根节点的特性
        mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
        String wrappedJson = mapper.writeValueAsString(home);

        return ResponseEntity.ok(wrappedJson);
    }
}

注意:如果全局开启WRAP_ROOT_VALUE会影响所有接口的序列化结果,建议只在需要的接口中临时配置。

3. 使用匿名内部类包装

通过Spring直接返回包含output字段的匿名对象,无需额外创建POJO类文件:

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HomeController {

    @GetMapping("/home")
    public ResponseEntity<?> getHome() {
        Home home = new Home();
        home.setNumber(1);
        home.setAddress("chennai");

        // 返回包含output字段的匿名对象
        return ResponseEntity.ok(new Object() {
            public final Home output = home;
        });
    }
}

这种方式简单直接,匿名类仅在当前方法中生效,不会产生额外的类文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 13:43:04