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

如何通过继承消除API响应类重复代码并兼容Jackson反序列化?

基于泛型+继承消除API响应类重复代码的最优方案

针对你描述的两个API响应类仅内部Data字段类型不同的场景,用泛型抽象父类+具体子类的方案是最简洁且适配Jackson反序列化要求的实现方式,具体步骤如下:

1. 抽象公共结构为泛型父类

将两个类的重复部分(响应码、消息、Data容器)抽离到一个泛型父类中,用泛型<T>表示不同的Data类型:

import com.fasterxml.jackson.annotation.JsonProperty;

// 抽象父类,定义公共响应结构
public abstract class BaseApiResponse<T> {
    @JsonProperty("code")
    private int responseCode;
    
    @JsonProperty("message")
    private String responseMessage;
    
    @JsonProperty("data")
    private T responseData;

    // 公共的Getter/Setter,无需重复编写
    public int getResponseCode() {
        return responseCode;
    }

    public void setResponseCode(int responseCode) {
        this.responseCode = responseCode;
    }

    public String getResponseMessage() {
        return responseMessage;
    }

    public void setResponseMessage(String responseMessage) {
        this.responseMessage = responseMessage;
    }

    public T getResponseData() {
        return responseData;
    }

    public void setResponseData(T responseData) {
        this.responseData = responseData;
    }
}

2. 定义具体的Data实体类

分别创建两个类对应的Data类型,仅保留各自独有的字段:

import java.math.BigDecimal;

// ClassA对应的Data实体
public class UserData {
    @JsonProperty("user_id")
    private Long userId;
    
    @JsonProperty("user_name")
    private String userName;

    // 该类的Getter/Setter
    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}

// ClassB对应的Data实体
public class OrderData {
    @JsonProperty("order_id")
    private String orderId;
    
    @JsonProperty("order_amount")
    private BigDecimal orderAmount;

    // 该类的Getter/Setter
    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    public BigDecimal getOrderAmount() {
        return orderAmount;
    }

    public void setOrderAmount(BigDecimal orderAmount) {
        this.orderAmount = orderAmount;
    }
}

3. 创建子类继承泛型父类

两个原响应类只需继承父类并指定泛型类型,无需编写任何重复代码:

// 原ClassA,指定泛型为UserData
public class ClassA extends BaseApiResponse<UserData> {
    // 空实现,所有公共属性和方法直接继承自父类
}

// 原ClassB,指定泛型为OrderData
public class ClassB extends BaseApiResponse<OrderData> {
    // 空实现,所有公共属性和方法直接继承自父类
}

4. Jackson反序列化用法

由于子类已经明确指定了泛型类型,直接使用子类的Class对象即可完成反序列化,无需额外复杂配置:

import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper objectMapper = new ObjectMapper();

// 反序列化ClassA
String classAJson = "{\"code\":200,\"message\":\"请求成功\",\"data\":{\"user_id\":1001,\"user_name\":\"张三\"}}";
ClassA classA = objectMapper.readValue(classAJson, ClassA.class);

// 反序列化ClassB
String classBJson = "{\"code\":200,\"message\":\"请求成功\",\"data\":{\"order_id\":\"ORD20240501\",\"order_amount\":99.9}}";
ClassB classB = objectMapper.readValue(classBJson, ClassB.class);

关键注意事项

  • 父类建议设为抽象类,避免直接实例化,更符合语义。
  • 所有与JSON字段映射的注解(如@JsonProperty)统一放在父类的公共字段上,子类无需重复配置。
  • 如果后续某个响应类需要新增独有的字段,直接在对应子类中添加即可,不会破坏公共结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 01:09:18