Reputation: 26004
Is it possible to have multiple @JsonCreator
methods, and for jackson to detect which one it should use depending on the method definiton?
@JsonCreator
public static StateOfComm factory(String id) {
return StateOfComm.valueOf(id);
}
@JsonCreator
public static StateOfComm factory(CustomType value) {
return StateOfComm.valueOf(value.getId());
}
The JSON that fails (because id=null), is the following:
{"comment":null, "processes":[{"stateOfComm":{"id":"CA"}}]}
The following works:
{"comment":null, "processes":[{"stateOfComm":"CA"}]}
Upvotes: 7
Views: 12950
Reputation: 26004
I solved this problem by getting rid of the @JsonCreator
annotations, and using a custom StdDeserializer
that did the trick.
Here is an example:
@JsonIgnoreProperties(
ignoreUnknown = true
)
@JsonDeserialize(
using = IdTextEntry.Deserializer.class
)
@Data
public class IdTextEntry implements IdAndText {
String id;
String text;
public IdTextEntry(Enum<?> val) {
if (val != null) {
this.id = val.name();
this.text = val.toString();
}
}
public static class Deserializer extends StdDeserializer<IdTextEntry> {
public Deserializer() {
this((Class)null);
}
Deserializer(Class<?> vc) {
super(vc);
}
public IdTextEntry deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
JsonNode node = (JsonNode)jp.getCodec().readTree(jp);
String id;
if (node.has("id") && node.has("text")) {
id = node.get("id").asText();
String text = node.get("text").asText();
return new IdTextEntry(id, text);
} else if (node.has("id")) {
id = node.get("id").asText();
return new IdTextEntry(id, id);
} else {
id = node.asText();
return new IdTextEntry(id, id);
}
}
}
}
Upvotes: 4
Reputation: 22234
I was able to parse both JSON examples in your question by:
jackson-modules-java8
version 2.9.1 dependency-parameters
argument@JsonProperty
on static creation methods and constructorsdefining a class:
class CustomType {
private final String id;
}
My understanding is that Jackson couldn't discern between multiple creators in older version. E.g. see answer here and github issue here. It seems that the option to have parameter names in compiled code in java 8 helps in this case.
Upvotes: 3
Reputation: 1895
You can have multiple @JsonCreator methods but it requires to use @JsonProperty for specifying which property you are initializing.
@JsonCreator
public static StateOfComm factory(@JsonProperty("id") String id) {
return StateOfComm.valueOf(id);
}
@JsonCreator
public static StateOfComm factory(@JsonProperty("value") CustomType value) {
return StateOfComm.valueOf(value.getId());
}
Upvotes: -1