JSON 문자열을 열거 형으로 역 직렬화하는 방법
Nov 23 2020
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
지도 operation
같은 enum
과 test
에Integer
답변
1 Matthew Nov 23 2020 at 23:30
당신은 사용할 수 있어야합니다 @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
Matthew Nov 23 2020 at 22:08
이렇게하지 않는 이유 :
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}
그렇다면 JustWork해야합니다!
Elzzz Nov 23 2020 at 22:16
JSON의 (다른 종류의) 모든 옵션과 같이 저장되어있는 구조 Map<String, Object> options;
(같은 값 유형이 레이블을 기반으로 식별하기 때문에, 시행한다 추가 분석 "operation"
및 OperationEnum
클래스) 여기에 2 접근이 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" +
"}";
}
MichałZiober Nov 25 2020 at 05:59
간단한 해결책은 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