我有一个包含数百个属性的复杂Java DTO(数据传输对象模式)类。出于说明目的,仅考虑两个
class PointlessExample {
private int x;
private int y;
public ... // getters/setters
}
将此重构为两个类的最佳方法是什么,以便某些属性子集(' x')可以与完整类分开保存,并单独或与完整类一起序列化?
我的简单想法是:
@Entity
class PointlessBase {
private int x;
...
}
class PointlessExample extends PointlessBase {
private int y;
...
}
然而问题是,对象可以作为完整的类(PointlessExample
)开始它们的生命周期,虽然它们总是被保存为PointlessBase
,但我有用例来序列化和反序列化为完整或部分对象(包括从完整序列化对象反序列化部分对象)。没有简单的方法可以序列化(通过Jackson)或持久化(通过Hibernate)只有属于PointlessBase
对象的PointlessExample
字段。或者有吗?
答案 0 :(得分:0)
DTO通常为painful concept 你使用继承分离属性的想法听起来很好 如果我理解你的要求,你需要这样的东西:
--------------------------------------- | Class | JSON | Hibernate | --------------------------------------- | PointlessBase | YES | YES | --------------------------------------- | PointlessExample | YES | NO | ---------------------------------------
在Jackson
中,您可以自定义反序列化的序列化过程,并且通常忽略来自给定类型或其他过滤器的属性。例如,请参阅我的简单类过滤器:
class ClassIgnoranceIntrospector extends JacksonAnnotationIntrospector {
private final Class<?> clazz;
ClassIgnoranceIntrospector(Class<?> clazz) {
this.clazz = clazz;
}
public boolean hasIgnoreMarker(AnnotatedMember m) {
return m.getDeclaringClass() != clazz;
}
}
您可以在下面找到如何使用它:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
ObjectMapper baseMapper = new ObjectMapper();
baseMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
baseMapper.setAnnotationIntrospector(new ClassIgnoranceIntrospector(PointlessBase.class));
ObjectMapper extendedMapper = new ObjectMapper();
extendedMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
extendedMapper.setAnnotationIntrospector(new ClassIgnoranceIntrospector(PointlessExample.class));
List<PointlessBase> list = Arrays.asList(new PointlessBase(), new PointlessExample());
for (PointlessBase item : list) {
System.out.println("Base only mapper for class " + item.getClass().getSimpleName() + " " + baseMapper.writeValueAsString(item));
System.out.println("Extended only mapper for class " + item.getClass().getSimpleName() + " " + extendedMapper.writeValueAsString(item));
}
}
}
以上印刷品:
Base only mapper for class PointlessBase {"x":10}
Extended only mapper for class PointlessBase {}
Base only mapper for class PointlessExample {"x":10}
Extended only mapper for class PointlessExample {"y":11}
您可以使用ObjectMapper
的不同实例来序列化特定的属性集。如果您不想序列化/反序列化所有属性,请使用默认ObjectMapper
。
另一个想法是使用Jackson JSON Views。有关如何使用Jackson
读取Inheritance with Jackson处理正确继承的更多信息。