我需要为具有泛型的类编写自定义反序列化器。我找不到办法做到这一点,但是我无法想象我是唯一一个遇到这个问题的人。据我所知,有两种方法可以实现这一点,但它们都无法实现:
例如:
public class Foo<T> {}
public class FooDeserializer<T> {
public FooDeserializer(Class<T> type) { ... }
...
}
// Boilerplate code...
module.addDeserializer(Foo.class, new FooDeserializer<Bar1>(Bar1.class));
module.addDeserializer(Foo.class, new FooDeserializer<Bar2>(Bar2.class));
Run Code Online (Sandbox Code Playgroud)
这不起作用,当 ObjectMapper 实例获取 Foo 的实例时,没有可用的泛型参数的类型信息(类型擦除),因此它只是选择最后注册的反序列化器。
例如:
String json = "...";
ObjectMapper mapper = ...;
Foo<Bar1> foo = new Foo<>(Bar1.class);
foo = mapper.readValue(json, Foo.class); // Can't pass empty foo instance with Class<?> field containing Bar1.class
Run Code Online (Sandbox Code Playgroud)
需要这样的东西:
mapper.readValue(json, Foo.class, Bar1.class); // Doesn't exist in jackson
Run Code Online (Sandbox Code Playgroud)
任何建议如何做到这一点?
编辑:我找到了解决问题的方法,但这不是一个干净的解决方案:
我使用 Class 字段扩展 FooDeserializer …
我有一个 Java spring 项目,使用 hibernate 将其数据存储到 postgresql 数据库中。手动将数据写入数据库并使用休眠读取它工作正常。但是,使用 hibernate 将新创建的对象保存到数据库失败,因为 hibernate 尝试将 null 写入相应表(声明为主键)的 id 列中。
这里是 POJO 的开头:
@Entity
@Table(name="recipes")
public class Recipe implements Serializable {
private static final long serialVersionUID = 3239162951065313443L; // generated by eclipse
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
@Column(name="title")
private String title;
@Column(name="description")
private String description;
// and so on ...
Run Code Online (Sandbox Code Playgroud)
这是我在服务类中的方法:
public void add(String title, String description, String content,
int preparationEndurance, int totalEndurance, Date creation) {
logger.debug("Adding new recipe");
// Retrieve session from …Run Code Online (Sandbox Code Playgroud)