JsonMappingException при разборе перечисления - PullRequest
0 голосов
/ 23 мая 2018

У меня есть этот класс с конструктором, помеченным @JsonCreator для десериализации моей строки JSON в мой класс Meal:

public class Meal {
    private int proteins;
    private int lipids;
    private int carbohydrates;
    private int totalKcal;
    private List<Dish> dishes;
    private int slot;
    private MealEnum mealType;

    @JsonCreator
    public Meal(@JsonProperty("mealType") MealEnum mealType, @JsonProperty("dishes") List<Dish> dishes,
                @JsonProperty("slot") int slot, @JsonProperty("totalKcal") int totalKcal,
                @JsonProperty("carbohydrates") int carbohydrates, @JsonProperty("proteins") int proteins,
                @JsonProperty("lipids") int lipids) {
        this.mealType = mealType;
        this.dishes = dishes;
        this.slot = slot;
        this.totalKcal = totalKcal;
        this.carbohydrates = carbohydrates;
        this.proteins = proteins;
        this.lipids = lipids;
    }

У меня также есть это перечисление с конструктором, помеченным @JsonCreator:

public enum MealEnum {
    BREAKFAST(0, "BREAKFAST"),
    LUNCH(1, "LUNCH"),
    SUPPER(2, "SUPPER");
    @JsonIgnore
    private final int intValue;
    private final String stringValue;

    MealEnum(int intValue, String stringValue) {
        this.intValue = intValue;
        this.stringValue = Objects.requireNonNull(stringValue);
    }

    @JsonCreator
    MealEnum(@JsonProperty("mealType") String stringValue) {
        this.intValue = DynamicDietistUtils.getMealEnumFromMealType(stringValue);
        this.stringValue = stringValue;
    }

    public int getIntValue() {
        return this.intValue;
    }

    public String getStringValue() {
        return this.stringValue;
    }
}

JSON для десериализации выглядит следующим образом:

{
    "mealType": "BREAKFAST",
    "proteins": 60,
    "lipids": 147,
    "carbohydrates": 461,
    "totalKcal": 664,
    "dishes": [{
        "id": 0,
        "description": "burro (10g)",
        "proteins": 0.0,
        "lipids": 72.0,
        "carbohydrates": 0.0,
        "kcal": 76
    }, {
        "id": 0,
        "description": "pane comune (100g)",
        "proteins": 32.0,
        "lipids": 0.0,
        "carbohydrates": 252.0,
        "kcal": 290
    }],
    "slot": 1
}

Когда Джексон пытается десериализовать JSON, появляется следующая ошибка:

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of mainpackage.data.model.Meal: no String-argument constructor/factory method to deserialize from String value ('mealType')

Гдея делаю не так?Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Измените ваш enum json creator как заводской метод

@JsonCreator
public static MealEnum fromString(String stringValue) {
    int value = DynamicDietistUtils.getMealEnumFromMealType(stringValue);
    for(MealEnum e : values()) {
        if(value == e.getIntValue()) {
            return e;
        }  
    }
    throw new IllegalArgumentException(stringValue);

}

ИЛИ (если foodType в json совпадает с константами Enum)

@JsonCreator
public static MealEnum fromString(String stringValue) {

     // for case insensitive use stringValue.toUpperCase()
     return MealEnum.valueOf(stringValue);
}
0 голосов
/ 23 мая 2018

Я считаю, что проблема в том, что в Java вы не могли вызвать конструктор enum из любого места, кроме списка инициализации значений enum.
Так что Джексон не мог использовать конструктор enum, вместо этого вы можете создать статический метод, который будет искать значение изСтрока для вас.

@JsonCreator
public static MealEnum forValue(String value) {
    return MaelEnum.valueOf(value); //or any other way to lookup your enum value for given string
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...