Подтвердить что ты не робот

Как аннотировать поля enum для десериализации с использованием Jackson json

Джексон 1.6.2 Веб-сервис REST/Apache Wink

Как аннотировать поле перечисления, чтобы Джексон десериализовал его?

Внутренний класс

public enum BooleanField
{
    BOOLEAN_TRUE        { public String value() { return "1";} },
    BOOLEAN_FALSE       { public String value() { return "0";} },

Java Bean/Объект запроса

BooleanField locked;
public BooleanField getLocked() {return locked;}

В документах Jackson указано, что он может сделать это через @JsonValue/@JsonCreator, но не дает примеров (насколько полезно!). Я уверен, что они просто не хотят, чтобы слишком много людей использовали свои рамки, чтобы сохранить эту тайну.

Любой, кто хочет разлить (java) beans, как бы?

4b9b3361

Ответ 1

Если вы используете Jackson 1.9, сериализация будет выполняться с помощью:

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; }

поэтому вам нужно добавить метод к типу Enum, так что все значения имеют его. Не уверен, будет ли он работать с подтипом.

Для @JsonCreator, используя статический метод factory; поэтому добавление чего-то вроде:

@JsonCreator
public static BooleanField forValue(String v) { ... }

Jackson 2.0 фактически поддерживает использование только @JsonValue для обоих, включая десериализацию.

Ответ 2

С Jackson 2.7.2 или новее

public enum BooleanField
{
    @JsonProperty("1")
    BOOLEAN_TRUE,
    @JsonProperty("0")
    BOOLEAN_FALSE
}

Ответ 3

не комментируйте их, просто настройте экземпляр 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;
}

и в вашем перечислении переопределите метод 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;
    }
}

Вам не нужны аннотации или пользовательские десериализаторы.

Ответ 4

Собственно, согласно документам для 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. 

Итак, для перечислений ваша десериализация не будет работать с использованием JsonCreator, потому что JsonValue будет использоваться как для сериализации, так и для десериализации. Один из способов сделать это для перечислений - использовать JsonSetter и JsonGetter.

Ответ 5

Если перечисление является массивом или нет, может работать следующее. (Только для десериализации)

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());
        }
    }
}

Считать:

  • Аннотации @Data генерируют сеттеры, getters, toString и т.д.
  • @JsonProperty ( "my-enums" ) private MyEnum [] myEnums, это способ аннотировать с джексоном поле, которое имеет тип Enum ( Он работает, если это массив или нет).

  • MyEnum - это перечисление значений, которые должны отображаться для объекта JSON, предположим, что следующий объект:

    {    "sucess": true,    "my-enums": [ "enum1-val", "enum3-val" ] }

  • Функция forValue позволяет сопоставлять строковые значения массива Enum, он аннотируется с помощью @JsonCreator, чтобы указать конструкцию factory, используемую при десериализации.