我需要将Entity
反序列化为EntityDTO
。问题在于Entity
类具有collection<KeyValue>
,其中:
class KeyValueDTO {
private String key;
private Object value;
}
并且
Entity
具有KeyValue
的集合:class KeyValue {
private String key;
private Object[] values;
}
因此,每种情况下数据的存储方式略有不同。所以,
KeyValueDTO dto1 = new KeyValueDTO("k1", "v1");
KeyValueDTO dto2 = new KeyValueDTO("k1", "v2");
KeyValueDTO dto3 = new KeyValueDTO("k1", "v3");
并使用
KeyValue
类:KeyValue values = new KeyValue("k1", new Object[] { "v1", "v2", "v3"});
然后,
Entity
类是class Entity {
List<KeyValue> values;
}
和,
class EntityDTO {
List<KeyValueDTO> values;
}
我需要像这样映射一个json:
[ {"k1": "v1"}, {"k1": "v2"}, {"k1": "v3"} ]
到
List<KeyValue>
。因此,values
属性必须具有一个元素KeyValue::key => "k1"
和KeyValue::values => {"v1", "v2", "v3"}
。我正在使用jackson来反序列化每个REST方法参数。因此,我需要从
Entity
映射到EntityDTO
,从EntityDTO
映射到Entity
。有任何想法吗?
最佳答案
杰克逊不会处理这样的转换,因此您需要自己进行转换。
您需要两个转换:
实体-> EntityDTO
EntityDTO->实体
这些不是普通的转换,但也不错。带有新Streams API的Java 8非常适合这些类型的转换。
干得好:
Entity entityToTransform = new Entity();
EntityDTO entityDtoToTransform = new EntityDTO();
// Entity -> EntityDTO
// transform the list of KeyValues to KeyValueDTOs
List<KeyValueDTO> keyValueDtos = entityToTransform.getValues().stream(
).flatMap(
keyValue -> Arrays.stream(
keyValue.getValues()
).map(
value -> new KeyValueDTO(keyValue.getKey(), value)
)
).collect(Collectors.toList());
// set the object
EntityDTO entityDto = new EntityDTO(keyValueDtos);
// EntityDTO -> Entity
// transforms the list of KeyValueDTOs to KeyValues
List<KeyValue> keyValues = entityDtoToTransform.getValues().stream(
).collect(
Collectors.collectingAndThen(
Collectors.groupingBy(keyValueDto -> keyValueDto.getKey()),
groupings -> groupings.entrySet().stream(
).map(
entry -> new KeyValue(
entry.getKey(),
entry.getValue().stream(
).map(
keyValueDto -> keyValueDto.getValue()
).collect(
Collectors.toList()
).toArray(
new Object[entry.getValue().size()]
)
)
).collect(Collectors.toList())
)
);
Entity entity = new Entity(keyValues);