解析枚举时出现JsonMappingException

时间:2018-05-23 13:03:29

标签: java json spring jackson

我的这个类带有一个标有@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
}

当Jackson尝试反序列化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 :(得分:0)

我认为问题是在java中你不能从除枚举值初始化列表之外的任何地方调用enum构造函数。
因此,jackson无法使用枚举构造函数,您可以创建静态方法,而不是从字符串中查找值。

@JsonCreator
public static MealEnum forValue(String value) {
    return MaelEnum.valueOf(value); //or any other way to lookup your enum value for given string
}

答案 1 :(得分:0)

将您的枚举json创建者更改为工厂方法

@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);

}

OR(如果json中的mealType与Enum常量匹配)

@JsonCreator
public static MealEnum fromString(String stringValue) {

     // for case insensitive use stringValue.toUpperCase()
     return MealEnum.valueOf(stringValue);
}