如何在请求与响应中避免出现type字段(附Jackson@JsonTypeInfo代码)
如何在请求和响应中避免出现
type字段? 刚好碰到过类似的场景——你现在用Jackson处理多态类型的序列化/反序列化,但不想让额外的type字段出现在请求响应里,而你的实体已经有itemtype这个业务字段了,完全可以复用它来做类型标识,这样就能去掉多余的type字段了。
步骤1:调整@JsonTypeInfo注解配置
首先修改你的ItemId接口上的注解,把类型标识的字段从type改成你已经存在的itemtype,同时配置Jackson用这个现有属性来判断类型:
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonSubTypes; @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, // 用名称标识类型,对应@JsonSubTypes里的name值 include = JsonTypeInfo.As.EXISTING_PROPERTY, // 使用对象已有的属性作为类型标识 visible = true, // 让Jackson正常将itemtype字段绑定到对象属性(你的实现类已有该属性) property = "itemtype" // 指定复用itemtype作为类型标识字段 ) @JsonSubTypes({ // 映射itemtype的值到对应的实现类,这里"fashion"对应ItemIdImpl @JsonSubTypes.Type(value = ItemIdImpl.class, name = "fashion") }) public interface ItemId { String getItemValue(); String getItemType(); }
步骤2:确保实现类的属性与方法匹配
你的ItemIdImpl已经有itemtype属性和对应的getter方法,这部分无需修改,Jackson会自动把JSON里的itemtype字段绑定到这个属性,同时用它来判断要实例化的类型:
public class ItemIdImpl implements ItemId { private final String itemvalue; private final String itemtype; // 提供Jackson可识别的构造函数(根据你的业务需求选择带参/无参) public ItemIdImpl(String itemvalue, String itemtype) { this.itemvalue = itemvalue; this.itemtype = itemtype; } @Override public String getItemValue() { return itemvalue; } @Override public String getItemType() { return itemtype; } }
为什么这样能去掉type字段?
原来的配置中property = "type",Jackson会额外生成一个type字段来存储类型信息。现在我们改成复用已有的itemtype作为类型标识字段,Jackson会直接用这个字段同时承担业务字段和类型标识的作用,不会再生成多余的type了。
测试效果
现在你的请求体可以简化为:
[ {"itemvalue":"inpound","itemtype":"fashion"} ]
Jackson能正确将其反序列化为ItemIdImpl实例;序列化时,响应里也只会包含itemvalue和itemtype,不会出现type字段。
扩展:如果有多个实现类
以后新增其他实现类(比如BookItemIdImpl对应itemtype="book"),只需在@JsonSubTypes里添加新的映射即可:
@JsonSubTypes({ @JsonSubTypes.Type(value = ItemIdImpl.class, name = "fashion"), @JsonSubTypes.Type(value = BookItemIdImpl.class, name = "book") })
内容的提问来源于stack exchange,提问作者Priyajit.Parida
相关产品推荐
相关产品推荐

