Comment annoter les champs enum pour la désérialisation en utilisant Jackson json
Jackson 1.6.2 Service web REST/Apache Clin d'oeil
Comment puis-je annoter un champ enum pour que Jackson le désérialise?
classe interne
public enum BooleanField
{
BOOLEAN_TRUE { public String value() { return "1";} },
BOOLEAN_FALSE { public String value() { return "0";} },
Java Bean/objet de Requête
BooleanField locked;
public BooleanField getLocked() {return locked;}
Le Jackson docs de l'état qu'il peut le faire via @JsonValue
/@JsonCreator
mais ne donne aucun exemple (combien utile!). Je suis sûr qu'ils ne veulent pas que trop de gens utilisent leur cadre alors ils gardent ce secret.
Quiconque est prêt à renverser le (java)de haricots, comme il a été?
5 réponses
si vous utilisez Jackson 1.9, la sérialisation sera faite par:
public enum BooleanField {
BOOLEAN_TRUE("1")
;
// either add @JsonValue here (if you don't need getter)
private final String value;
private BooleanField(String value) { this.value = value; }
// or here
@JsonValue public String value() { return value; }
ainsi, le changement dont vous avez besoin est d'ajouter la méthode au type Enum lui-même, donc toutes les valeurs l'ont. Je ne suis pas sûr que ça marcherait sur le sous-type.
@JsonCreator
, avoir une méthode d'usine statique le ferait; donc ajouter quelque chose comme:
@JsonCreator
public static BooleanField forValue(String v) { ... }
Jackson 2.0 va en fait soutenir l'utilisation de just @JsonValue
pour les deux, y compris la désérialisation.
Jackson 2.7.2 ou plus récent
public enum BooleanField
{
@JsonProperty("1")
BOOLEAN_TRUE,
@JsonProperty("0")
BOOLEAN_FALSE
}
ne les annotez pas, configurez simplement votre instance ObjectMapper:
private ObjectMapper createObjectMapper() {
final ObjectMapper mapper = new ObjectMapper();
// enable toString method of enums to return the value to be mapped
mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
return mapper;
}
et dans votre enum surcharger la méthode toString ():
public enum SectionType {
START("start"),
MORE("more");
// the value which is used for matching
// the json node value with this enum
private final String value;
SectionType(final String type) {
value = type;
}
@Override
public String toString() {
return value;
}
}
vous n'avez pas besoin d'annotations ou de désérialiseurs personnalisés.
en fait, selon les docs pour JsonValue (Jackson 2.3.3):
NOTE: when use for Java enums, one additional feature is
* that value returned by annotated method is also considered to be the
* value to deserialize from, not just JSON String to serialize as.
* This is possible since set of Enum values is constant and it is possible
* to define mapping, but can not be done in general for POJO types; as such,
* this is not used for POJO deserialization.
donc pour enums, votre deserialisation ne fonctionnera pas en utilisant JsonCreator car JsonValue sera utilisé à la fois pour la sérialisation et la deserialisation. Une façon de le faire pour enums est d'utiliser JsonSetter et JsonGetter.
ce qui suit peut fonctionner si l'énumération est un tableau ou non. (Uniquement pour la désérialisation)
package com.stack.model;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import lombok.Data;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonPropertyOrder({ "success", "my-enums" })
public class MyObjectJSON {
@JsonProperty("sucess")
private boolean success;
@JsonProperty("my-enums")
private MyEnum[] myEnums;
static enum MyEnum {
Enum1, Enum2, Enum3, Enum4, EnumN;
private static Map<String, MyEnum> myEnumsMap = new HashMap<String, MyEnum>(5);
static {
myEnumsMap.put("enum1-val", Enum1);
myEnumsMap.put("enum2-val", Enum2);
myEnumsMap.put("enum3-val", Enum3);
myEnumsMap.put("enum4-val", Enum4);
myEnumsMap.put("enumn-val", EnumN);
}
@JsonCreator
public static MyEnum forValue(String value) {
return myEnumsMap.get(value.toLowerCase());
}
}
}
À prendre en compte:
- l'annotation @Data génère setters, getters, toString, etc.
@JsonProperty("mon-enums") privé MyEnum[] myEnums, c'est la façon de les annoter avec jackson le champ de type Enum ( Il fonctionne si c'est un tableau ou pas).
MyEnum est l'énumération des valeurs de mappés de l'objet JSON, supposons que l'objet suivant:
{ "succès": vrai, "mon-enums": ["enum1-val", "enum3-val"] }
la fonction forValue permet de cartographier les valeurs des chaînes de caractères du tableau à Enum, elle est annotée avec @JsonCreator pour indiquer une usine de construction utilisée dans la désérialisation.