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é?

29
demandé sur Roddy of the Frozen Peas 2012-02-15 23:45:20

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.

41
répondu StaxMan 2012-02-16 16:22:26

Jackson 2.7.2 ou plus récent

public enum BooleanField
{
    @JsonProperty("1")
    BOOLEAN_TRUE,
    @JsonProperty("0")
    BOOLEAN_FALSE
}
21
répondu softarn 2016-06-01 22:28:20

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.

11
répondu Nino Handler 2016-12-17 10:56:02

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.

3
répondu user2706588 2015-10-29 14:23:50

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:

  1. l'annotation @Data génère setters, getters, toString, etc.
  2. @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).

  3. 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"] }

  4. 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.

0
répondu Raymundo Toledo 2017-08-25 20:38:15