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

Spring(Java 17)处理多类型Payload的DTO请求体最佳实践

Spring(Java 17)处理多类型Payload请求体列表的最佳实践

针对你提到的包含不同Payload类型的DTO列表请求,Spring结合Jackson的多态序列化/反序列化是最常用且规范的实现方案,以下是具体实践步骤:

1. 定义多态DTO结构

首先创建一个抽象基类,包含所有项的公共字段,并通过Jackson注解指定类型识别规则;然后为每种type创建对应的子类,各自封装专属的Payload类型:

抽象基类

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type" // 指定用来判断类型的字段
)
@JsonSubTypes({
    // 注册所有已知的子类型,name对应JSON中的type值
    @JsonSubTypes.Type(value = MessageItem.class, name = "message"),
    @JsonSubTypes.Type(value = IdItem.class, name = "id")
})
public abstract class BaseItem {
    private String common_data;

    // 生成getter、setter方法
    public String getCommon_data() {
        return common_data;
    }

    public void setCommon_data(String common_data) {
        this.common_data = common_data;
    }
}

Message类型子类

public class MessageItem extends BaseItem {
    private MessagePayload payload;

    // getter、setter
    public MessagePayload getPayload() {
        return payload;
    }

    public void setPayload(MessagePayload payload) {
        this.payload = payload;
    }

    // 嵌套的Message专属Payload类
    public static class MessagePayload {
        private String text;

        public String getText() {
            return text;
        }

        public void setText(String text) {
            this.text = text;
        }
    }
}

Id类型子类

public class IdItem extends BaseItem {
    private IdPayload payload;

    // getter、setter
    public IdPayload getPayload() {
        return payload;
    }

    public void setPayload(IdPayload payload) {
        this.payload = payload;
    }

    // 嵌套的Id专属Payload类
    public static class IdPayload {
        private Integer id;

        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }
    }
}

2. Controller接收并处理请求

在Spring Controller中直接接收List<BaseItem>类型的请求体,利用Java 17的模式匹配instanceof简化类型判断与处理:

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RestController
public class ItemController {

    @PostMapping("/process-items")
    public void processItems(@RequestBody List<BaseItem> items) {
        for (BaseItem item : items) {
            // Java 17模式匹配,直接转换并赋值
            if (item instanceof MessageItem messageItem) {
                String textContent = messageItem.getPayload().getText();
                // 处理message类型业务逻辑
                System.out.println("Received message: " + textContent);
            } else if (item instanceof IdItem idItem) {
                Integer targetId = idItem.getPayload().getId();
                // 处理id类型业务逻辑
                System.out.println("Received id: " + targetId);
            }
            // 可扩展其他类型的判断
        }
    }
}

关键注意事项

  • 所有子类型必须在基类的@JsonSubTypes中注册,否则Jackson无法识别对应的type值,会抛出反序列化异常
  • 优先使用强类型的Payload类而非Map<String, Object>,避免运行时类型转换错误,同时提升代码可读性与可维护性
  • 如果需要支持更多类型,只需新增子类并在@JsonSubTypes中补充注册即可,符合开闭原则

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 23:27:43