잭슨:각 값 에 대해 올바른 유형의 맵 으로 역직렬화
나는 다음과 같은 수업을 듣는다.
public class MyClass {
private String val1;
private String val2;
private Map<String,Object> context;
// Appropriate accessors removed for brevity.
...
}
오브젝트에서 JSON까지 잭슨과 왕복할 수 있기를 기대하고 있습니다.위의 오브젝트를 시리얼화하여 다음 출력을 수신할 수 있습니다.
{
"val1": "foo",
"val2": "bar",
"context": {
"key1": "enumValue1",
"key2": "stringValue1",
"key3": 3.0
}
}
여기서 문제가 발생하고 있는 것은 시리얼화된 맵의 값에 유형 정보가 없기 때문에 올바르게 역직렬화되지 않는다는 것입니다.예를 들어 위의 예에서는 enumValue1을 열거값으로 역직렬화해야 하지만 대신 문자열로 역직렬화해야 합니다.다양한 것에 근거한 타입의 예를 봐 왔지만, 제 시나리오에서는 타입을 알 수 없기 때문에(미리 알 수 없는 사용자 생성 오브젝트) 타입 정보를 키 값 쌍으로 시리얼화할 수 있어야 합니다.잭슨이랑 어떻게 해야 돼?
참고로 잭슨 버전 2.4.2를 사용하고 있습니다.왕복 테스트에 사용하는 코드는 다음과 같습니다.
@Test
@SuppressWarnings("unchecked")
public void testJsonSerialization() throws Exception {
// Get test object to serialize
T serializationValue = getSerializationValue();
// Serialize test object
String json = mapper.writeValueAsString(serializationValue);
// Test that object was serialized as expected
assertJson(json);
// Deserialize to complete round trip
T roundTrip = (T) mapper.readValue(json, serializationValue.getClass());
// Validate that the deserialized object matches the original one
assertObject(roundTrip);
}
이것은 스프링 기반 프로젝트이므로 다음과 같이 매퍼가 작성됩니다.
@Configuration
public static class SerializationConfiguration {
@Bean
public ObjectMapper mapper() {
Map<Class<?>, Class<?>> mixins = new HashMap<Class<?>, Class<?>>();
// Add unrelated MixIns
..
return new Jackson2ObjectMapperBuilder()
.featuresToDisable(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS)
.dateFormat(new ISO8601DateFormatWithMilliSeconds())
.mixIns(mixins)
.build();
}
}
원하는 것을 달성하는 가장 간단한 방법은 다음을 사용하는 것이라고 생각합니다.
ObjectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
그러면 직렬화된 json에 유형 정보가 추가됩니다.
다음은 봄에 적응해야 하는 실행 예시입니다.
public class Main {
public enum MyEnum {
enumValue1
}
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
MyClass obj = new MyClass();
obj.setContext(new HashMap<String, Object>());
obj.setVal1("foo");
obj.setVal2("var");
obj.getContext().put("key1", "stringValue1");
obj.getContext().put("key2", MyEnum.enumValue1);
obj.getContext().put("key3", 3.0);
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
System.out.println(json);
MyClass readValue = mapper.readValue(json, MyClass.class);
//Check the enum value was correctly deserialized
Assert.assertEquals(readValue.getContext().get("key2"), MyEnum.enumValue1);
}
}
오브젝트는 다음과 같은 것으로 시리얼화 됩니다.
[ "so_27871226.MyClass", {
"val1" : "foo",
"val2" : "var",
"context" : [ "java.util.HashMap", {
"key3" : 3.0,
"key2" : [ "so_27871226.Main$MyEnum", "enumValue1" ],
"key1" : "stringValue1"
} ]
} ]
그리고 올바르게 역직렬화 될 것이고, 주장은 통과될 것이다.
덧붙여서, 자세한 것은, https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization 를 참조해 주세요.
도움이 되었으면 좋겠어요.
언급URL : https://stackoverflow.com/questions/27871226/jackson-deserialize-to-a-mapstring-object-with-correct-type-for-each-value
'programing' 카테고리의 다른 글
T-SQL을 사용하여 하위 문자열의 마지막 항목 색인 찾기 (0) | 2023.04.07 |
---|---|
SQL Server에서 실행 중인 쿼리 나열 (0) | 2023.04.07 |
사용자 정의 유효성 검사 angularjs 지시문을 테스트하려면 (0) | 2023.04.02 |
H2-콘솔이 브라우저에 표시되지 않음 (0) | 2023.04.02 |
JSON 및 이스케이프 문자 (0) | 2023.04.02 |