如何将json字符串反序列化为枚举

bxgwgixi  于 2021-07-08  发布在  Java
关注(0)|答案(4)|浏览(504)

json如下所示:

{
  "name": "john",
  "options": {
    "test": 1,
    "operation": "op1",     // I need to deserialize this option to enum.
    ...
    // any number of options
  }
}

我的课看起来是这样的:

public class Info {
    public String name;
    @JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
    public Map<String, Object> options;
}

public enum OperationEnum {OP1, OP2, OP3}

如何反序列化到 options Map operation 就像 enum 以及 testInteger

xienkqul

xienkqul1#

为什么不这样做:

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}

那就行了!

im9ewurl

im9ewurl2#

简单的解决方法是 Package Map 示例,并为每个非正则属性实现额外的方法。你可以用 @JsonAnySetter 用于存储所有 key-value 对。
参见以下示例:

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}

以上代码打印:

{test=1, operation=op1}
OP1
11dmarpk

11dmarpk3#

json结构,其中所有选项(不同类型)的存储方式如下 Map<String, Object> options; 强制额外的解析,因为值类型是基于标签标识的(如 "operation" 以及 OperationEnum 类)这里有两种方法 ObjectMapper.readValue 以及 Enum.valueOf 如果可能的话,考虑像@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" +
            "}";
}
e5njpo68

e5njpo684#

你应该可以使用 @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}

这里有一篇很好的文章:https://www.concretepage.com/jackson-api/jackson-jsonanygetter-and-jsonanysetter-example

相关问题