[SPRING] Jackson : 각 값에 대해 올바른 유형의 Map <String, Object>에 비순환
SPRINGJackson : 각 값에 대해 올바른 유형의 Map 에 비순환
다음과 같은 클래스가 있습니다.
public class MyClass {
private String val1;
private String val2;
private Map<String,Object> context;
// Appropriate accessors removed for brevity.
...
}
JSON에서 뒤로 JSON으로 Jackson과 왕복 여행을 할 수 있기를 기대하고 있습니다. 위의 객체를 직렬화하여 다음 출력을받을 수 있습니다.
{
"val1": "foo",
"val2": "bar",
"context": {
"key1": "enumValue1",
"key2": "stringValue1",
"key3": 3.0
}
}
내가 겪고있는 문제는 직렬화 된 맵의 값에 유형 정보가 없으므로 올바르게 직렬화되지 않는다는 것입니다. 예를 들어, 위의 예제에서 enumValue1은 열거 형 값으로 deserialize되어야하지만 String 대신 deserialize됩니다. 다양한 유형에 어떤 유형을 사용하는지에 대한 예제를 보았습니다. 그러나 시나리오에서는 유형이 무엇인지 (내가 미리 알지 못하는 사용자 생성 객체가 될 것임) 알 수 없으므로 필요할 수 있습니다. 키 값 쌍으로 유형 정보를 직렬화 할 수 있습니다. 잭슨과 어떻게이 일을 성취 할 수 있습니까?
기록을 위해 Jackson 버전 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();
}
}
해결법
-
==============================
1.나는 당신이 원하는 것을 성취하는 가장 간단한 방법이 다음을 사용한다고 생각합니다 :
나는 당신이 원하는 것을 성취하는 가장 간단한 방법이 다음을 사용한다고 생각합니다 :
ObjectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
직렬화 된 JSON에 유형 정보가 추가됩니다.
다음은 Spring에 적응해야 할 실행 예제입니다.
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" } ] } ]
그리고 올바르게 다시 deserialize 될 것이며, 주장이 통과 할 것입니다.
여기에 더 많은 방법이 있습니다. 자세한 내용은 https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization을 참조하십시오.
나는 그것이 도움이되기를 바랍니다.
from https://stackoverflow.com/questions/27871226/jackson-deserialize-to-a-mapstring-object-with-correct-type-for-each-value by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 엔터티를 필터링하기 위해 Querydsl 및 Spring Data로 'REST API 쿼리 언어'를 쉽게 구현하는 방법은 무엇입니까? (0) | 2019.06.09 |
---|---|
[SPRING] Spring Batch 메타 데이터 테이블에서 동시에 교착 상태가 발생하는 여러 Spring Batch 작업 (0) | 2019.06.08 |
[SPRING] maven-spring-boot-plugin을 사용할 때 Spring Boot 명령 행에 classpath 추가 시작 (0) | 2019.06.07 |
[SPRING] 모든 BeanPostProcessors가 처리 할 수없는 클래스 (0) | 2019.06.07 |
[SPRING] Servlet 또는 @Controller를 사용해야하는 경우 (0) | 2019.06.06 |