Java Jackson:反序列化枚举
我正在RESTAPI中使用Jackson+Spring。其中一个API调用的JSON如下所示:Java Jackson:反序列化枚举,java,spring,jackson,Java,Spring,Jackson,我正在RESTAPI中使用Jackson+Spring。其中一个API调用的JSON如下所示: { "status": "Suspended" } 其中status的值映射到Java枚举,如下所示: public enum FeatureStatus { Activated(0), Inactivated(1), Suspended(2), Deleted(3); private FeatureStatus(int id) {
{
"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:{是一个无效值。它看起来根本没有反序列化JSON。我的控制器方法具有以下定义:
public @ResponseBody void updateFeatureStatusById(@PathVariable long featureId, @RequestBody FeatureStatus updated) {
任何其他控制器都会按预期使用此格式自动反序列化JSON。如何将此JSON反序列化到我的枚举中?将此类放在控制器旁边:
final class FeatureStatusJsonObject {
public FeatureStatus status;
}
然后在控制器方法中使用以下内容:
@RequestBody FeatureStatusJsonObject updated
并通过
updated.status
这使得从JSON对象到枚举文本的转换在代码中是显式的,并允许您在必要时在其他地方使用常规的枚举字符串反序列化
另一方面,这看起来有点古怪:
@ResponseBody void
我会把它作废。把这个类放在你的控制器旁边:
final class FeatureStatusJsonObject {
public FeatureStatus status;
}
然后在控制器方法中使用以下内容:
@RequestBody FeatureStatusJsonObject updated
并通过
updated.status
这使得从JSON对象到枚举文本的转换在代码中是显式的,并允许您在必要时在其他地方使用常规的枚举字符串反序列化
另一方面,这看起来有点古怪:
@ResponseBody void
我只想将其作废。是您传递给对象的确切JSON吗?枚举除了JSON字符串或数字,而不是对象。
如果需要指定对象,应将其映射到以下对象:
public class EnumWrapper {
public FeatureStatus status;
}
它会工作。是您传递给对象的确切JSON吗?枚举除了JSON字符串或数字,而不是对象。
如果需要指定对象,应将其映射到以下对象:
public class EnumWrapper {
public FeatureStatus status;
}
这就行了。你说得对,我编辑了这个问题以添加缺少的引号。任何其他控制器都会自动反序列化相同的输入,输出如预期的那样?我的意思是它们都有@RequestBody接受上述枚举?我的意思是,如果任何其他对象用@RequestBody反序列化,它会如预期的那样工作。没有我建议进行调试,在fromValue方法上设置一个断点,并检查堆栈跟踪中的方法,看看为什么它只传递{作为status的参数。这似乎是调用JSON creator方法的一个错误。您可以创建一个包装类来解决这个问题。您是对的,我编辑了这个问题以添加缺少的引号。任何其他控制器都会自动反序列化JSON。相同的输入和输出符合预期?我的意思是还有@RequestBody接受如上所述的枚举吗?我的意思是,如果任何其他对象使用@RequestBody反序列化,它会按预期工作。到目前为止,还没有其他枚举。我建议进行调试,在fromValue方法上设置断点,并检查堆栈跟踪中的方法,以了解其仅传递的原因{作为status的参数。这似乎是调用JSON创建者方法的一个错误。您可以创建一个包装器类来解决这个问题。