Reputation: 952
I'm using a subType property in Jackson, and I want to using this property when deserializing json.
package com.gaosoft.ai.kg.commons.sphinx.strategy;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.sankuai.ai.kg.commons.sphinx.model.FAQRecord;
import com.sankuai.ai.kg.commons.sphinx.model.FAQRequest;
import org.springframework.beans.factory.BeanFactory;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
property = "strategyType"
)
@JsonSubTypes({
@JsonSubTypes.Type(value = StrategyEmpty.class, name = "empty"),
@JsonSubTypes.Type(value = StrategyNormal.class, name = "normal"),
@JsonSubTypes.Type(value = StrategyDummy.class, name = "dummy")
}
)
public abstract class Strategy implements Serializable {
private String strategyName;
private String strategyType;
private Map<String, Object> args = new HashMap<>();
public String getStrategyType() {
return strategyType;
}
public void setStrategyType(String strategyType) {
this.strategyType = strategyType;
}
public Map<String, Object> getArgs() {
return args;
}
public void setArgs(Map<String, Object> args) {
this.args = args;
}
public String getStrategyName() {
return strategyName;
}
public void setStrategyName(String strategyName) {
this.strategyName = strategyName;
}
public abstract void init(BeanFactory beanFactory);
public abstract List<FAQRecord> fetchFAQ(FAQRequest request);
}
Like my code says, there are 3 subtype of abstract class Strategy, and I want to retain the subclass type name in strategyType property. Is there a way to fill strategyType when using jackson in this way?
(Sorry about my poor English)
Upvotes: 1
Views: 1479
Reputation: 81164
I think what you're asking for is the @JsonTypeInfo#visible
property:
Note on visibility of type identifier: by default, deserialization (use during reading of JSON) of type identifier is completely handled by Jackson, and is not passed to deserializers. However, if so desired, it is possible to define property visible = true in which case property will be passed as-is to deserializers (and set via setter or field) on deserialization.
So in your example,
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
property = "strategyType",
visible = true
)
That said, this seems like a design smell. Is it truly valid that you can set a StrategyEmpty
's strategyType
to dummy
? If not, and StrategyEmpty
should always have a strategyType
of empty
, then why not just have an abstract getStrategyType()
that each subclass implements with a hardcoded value?
Upvotes: 2