1

我在 REST API 中使用 Jackson + Spring。其中一个 API 调用具有如下所示的 JSON:

{
    "status": "Suspended"
}

其中“status”的值映射到 Java 枚举,如下所示:

public enum FeatureStatus {
    Activated(0),
    Inactivated(1),
    Suspended(2),
    Deleted(3);

    private FeatureStatus(int id) {
        this.id = id;
    }

    private int id;

    public int getId() {
        return id;
    }

    public FeatureStatus valueOf(int id) {
        switch(id) {
            case 1: return Inactivated;
            case 2: return Suspended;
            case 3: return Deleted;
            default: return Activated;
        }
    }

    @JsonCreator
    public static FeatureStatus fromValue(String status) {
        if(status != null) {
            for(FeatureStatus featureStatus : FeatureStatus.values()) {
                if(featureStatus.toString().equals(status)) {
                    return featureStatus;
                }
            }

            throw new IllegalArgumentException(status + " is an invalid value.");
        }

        throw new IllegalArgumentException("A value was not provided.");
    }
}

然而,这个异常被抛出:java.lang.IllegalArgumentException: { is an invalid value.看起来它根本没有反序列化 JSON。我的控制器方法有这个定义:

public @ResponseBody void updateFeatureStatusById(@PathVariable long featureId, @RequestBody FeatureStatus updated) {

任何其他控制器都会使用这种格式自动反序列化 JSON 格式。如何将此 JSON 反序列化到我的枚举中?

4

2 回答 2

4

把这个类放在你的控制器旁边:

final class FeatureStatusJsonObject {
     public FeatureStatus status;
}

然后在控制器方法中使用这个:

@RequestBody FeatureStatusJsonObject updated

并通过

updated.status

这使得从 JSON 对象到 Enum 文字的转换在您的代码中显式,并允许您在其他地方使用常规的 Enum <-> String(反)序列化(如有必要)。

在不相关的说明中,这看起来有点时髦:

@ResponseBody void

我只会让它无效。

于 2013-05-25T09:53:22.503 回答
2

您传递的确切JSON 是对象吗?枚举除了 JSON 字符串或数字,而不是对象。如果你需要给一个对象,你应该把它映射到类似的东西:

public class EnumWrapper {
  public FeatureStatus status;
}

它会起作用的。

于 2013-05-29T19:01:10.363 回答