[英]How to deserialize JSON string to enum
I have the JSON looks like the following:我的 JSON 如下所示:
{
"name": "john",
"options": {
"test": 1,
"operation": "op1", // I need to deserialize this option to enum.
...
// any number of options
}
}
and I have the class looks like the following:我的课程如下所示:
public class Info {
public String name;
@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
public Map<String, Object> options;
}
public enum OperationEnum {OP1, OP2, OP3}
How can I deserialize to options
map operation
like enum
and test
to Integer
如何反序列化为options
映射operation
如enum
和test
到Integer
You should be able to use @JsonAnySetter
to help you out here:您应该可以使用@JsonAnySetter
来帮助您:
public class Info {
public static class Options {
public int test;
public OperationEnum operation;
}
public String name;
public Options options;
private final Map<String, Object> properties = new HashMap<>();
@JsonAnySetter
public void add(String key, String value) {
properties.put(key, value);
}
}
public enum OperationEnum {OP1, OP2, OP3}
There's a good write-up here: https://www.concretepage.com/jackson-api/jackson-jsonanygetter-and-jsonanysetter-example这里有一篇很好的文章: https : //www.concretepage.com/jackson-api/jackson-jsonanygetter-and-jsonanysetter-example
Why not do it like this:为什么不这样做:
public class Info {
public static class Options {
public int test;
public OperationEnum operation;
}
public String name;
public Options options;
}
public enum OperationEnum {OP1, OP2, OP3}
Then it should JustWork!那么它应该是 JustWork!
JSON structure, where all options (of different kinds) are stored like Map<String, Object> options;
JSON 结构,其中所有选项(不同类型)都像Map<String, Object> options;
一样存储Map<String, Object> options;
enforces extra parsing, because value type is identified based on the label (like "operation"
and OperationEnum
class) Here are 2 approaches with ObjectMapper.readValue
and Enum.valueOf
强制执行额外的解析,因为值类型是基于标签识别的(如"operation"
和OperationEnum
类)这里有 2 种使用ObjectMapper.readValue
和Enum.valueOf
If it's possible, consider more flexible solutions like those from @Matthew如果可能,请考虑更灵活的解决方案,例如来自@Matthew 的解决方案
class Demo {
public static void main(String[] args) throws Exception {
ObjectMapper om = new ObjectMapper();
Info info = om.readValue(jsonValue, Info.class);
OperationEnum operationM = om.readValue("\"" + info.options.get("operation") + "\"", OperationEnum.class);
System.out.println(operationM);
OperationEnum operationE = OperationEnum.valueOf(info.options.get("operation").toString());
System.out.println(operationE);
}
static String jsonValue = "{\n" +
" \"name\": \"john\",\n" +
" \"options\": {\n" +
" \"test\": 1,\n" +
" \"operation\": \"OP1\" \n" +
" }\n" +
"}";
}
Simple solution is to wrap Map
instance with a class and implement extra methods for each non-regular property.简单的解决方案是用一个类包装Map
实例,并为每个非常规属性实现额外的方法。 You can use @JsonAnySetter
annotation to store all key-value
pairs.您可以使用@JsonAnySetter
注释来存储所有key-value
对。
See below example:见下面的例子:
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
public class JsonOptionsWithCustomEnumApp {
public static void main(String[] args) throws IOException {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
Info info = mapper.readValue(jsonFile, Info.class);
Options options = info.getOptions();
System.out.println(options.toMap());
System.out.println(options.getOperation());
}
}
class Info {
private String name;
private Options options;
//getters, setters
}
class Options {
private Map<String, Object> values = new LinkedHashMap<>();
@JsonAnySetter
private void setValues(String key, Object value) {
values.put(key, value);
}
public OperationEnum getOperation() {
Object operation = values.get("operation");
if (operation == null) {
return null;
}
return Arrays.stream(OperationEnum.values())
.filter(op -> op.name().equalsIgnoreCase(operation.toString()))
.findFirst()
.orElse(null);
}
public Map<String, Object> toMap() {
return values;
}
}
enum OperationEnum {OP1, OP2, OP3}
Above code prints:上面的代码打印:
{test=1, operation=op1}
OP1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.