Java 使用Jackson反序列化泛型类型

Java 使用Jackson反序列化泛型类型,java,android,jackson,guice,roboguice,Java,Android,Jackson,Guice,Roboguice,我正在尝试创建一个使用Jackson来反序列化POJO的类 看起来像这样 public class DeserialiserImp<T> implements Deserialiser<T> { protected ObjectMapper objectMapper = new ObjectMapper(); @Override public T get(String content, Class clazz) thro

我正在尝试创建一个使用Jackson来反序列化POJO的类

看起来像这样

public class DeserialiserImp<T> implements Deserialiser<T> {

        protected ObjectMapper objectMapper = new ObjectMapper();

        @Override
        public T get(String content, Class clazz) throws IOException {
            return (T) objectMapper.readValue(content, clazz);
        }

        @Override
        public List<T> getList(String content, Class clazz) throws IOException {
            return objectMapper.readValue(content, TypeFactory.collectionType(ArrayList.class, clazz));
        }

    }
public class DeserialiserImp<T> implements Deserialiser<T> {

    private ObjectMapper objectMapper = new ObjectMapper();
    private final Class<T> klass;

    @Inject
    public DeserialiserImp(TypeLiteral<T> type){
        this.klass = (Class<T>) type.getRawType();
    }

    @Override
    public T get(String content) throws IOException {
        return objectMapper.readValue(content, klass);
    }

    @Override
    public List<T> getList(String content) throws IOException {
        return objectMapper.readValue(content, TypeFactory.collectionType(ArrayList.class, klass));
    }

}
public类反序列化器imp实现反序列化器{
受保护的ObjectMapper ObjectMapper=新的ObjectMapper();
@凌驾
公共T get(字符串内容,类clazz)引发IOException{
return(T)objectMapper.readValue(content,clazz);
}
@凌驾
公共列表getList(字符串内容,类clazz)引发IOException{
返回objectMapper.readValue(content,TypeFactory.collectionType(ArrayList.class,clazz));
}
}
关于这个实现,我有两个问题

首先,我将类类型传递到方法中,以便objectmapper知道应该反序列化的类型。有更好的方法使用泛型吗

同样在get方法中,我将一个从objectMapper返回的对象强制转换为T。这似乎是一种特别糟糕的方法,因为我必须在这里强制转换T,然后还要从调用它的方法强制转换对象类型

我在这个项目中使用Roboguice,所以如果我可以通过注入更改类型,然后注释我需要它返回的泛型类型的对象,那将是一件好事。我读到了,想知道它是否能解决这个问题

首先,我将类类型传递到方法中,以便 objectmapper知道应该反序列化的类型。有更好的方法吗 如何使用泛型

不幸的是,这是因为类型擦除

同样在get方法中,我正在强制转换从 objectMapper到T。这似乎是一种特别令人讨厌的方式,因为我 必须在这里强制转换T,然后我还必须从 调用它的方法

改为这样做:

@Override
public T get(String content, Class<T> clazz) throws IOException {
    return objectMapper.readValue(content, clazz);
}
@覆盖
公共T get(字符串内容,类clazz)引发IOException{
返回objectMapper.readValue(content,clazz);
}
我在这个项目中使用Roboguice,所以如果我能 通过注入更改类型,然后注释 我需要它返回的泛型类型。我读过关于TypeLiteral和 想知道它是否能解决这个问题


我真的不明白你想要达到什么目标,但既然你无论如何都要通过这门课,那还有可能吗?

所以我想我最终找到了答案。如果你看到我所做的有问题,请发表评论

接口的定义如下

public interface Deserialiser<T> {

    T get(String content) throws IOException;

    List<T> getList(String content) throws IOException;
}
公共接口反序列化程序{
T get(字符串内容)抛出IOException;
List getList(字符串内容)抛出IOException;
}
接口的实现是这样的

public class DeserialiserImp<T> implements Deserialiser<T> {

        protected ObjectMapper objectMapper = new ObjectMapper();

        @Override
        public T get(String content, Class clazz) throws IOException {
            return (T) objectMapper.readValue(content, clazz);
        }

        @Override
        public List<T> getList(String content, Class clazz) throws IOException {
            return objectMapper.readValue(content, TypeFactory.collectionType(ArrayList.class, clazz));
        }

    }
public class DeserialiserImp<T> implements Deserialiser<T> {

    private ObjectMapper objectMapper = new ObjectMapper();
    private final Class<T> klass;

    @Inject
    public DeserialiserImp(TypeLiteral<T> type){
        this.klass = (Class<T>) type.getRawType();
    }

    @Override
    public T get(String content) throws IOException {
        return objectMapper.readValue(content, klass);
    }

    @Override
    public List<T> getList(String content) throws IOException {
        return objectMapper.readValue(content, TypeFactory.collectionType(ArrayList.class, klass));
    }

}
public类反序列化器imp实现反序列化器{
私有ObjectMapper ObjectMapper=新ObjectMapper();
私人期末班;
@注入
公共反序列化映射(TypeLiteral类型){
this.klass=(类)type.getRawType();
}
@凌驾
公共T get(字符串内容)引发IOException{
返回objectMapper.readValue(内容,klass);
}
@凌驾
公共列表getList(字符串内容)引发IOException{
返回objectMapper.readValue(内容,类型工厂.collectionType(ArrayList.class,klass));
}
}
我把这两个像这样绑起来

    bind(new TypeLiteral<Deserialiser<User>>(){}).annotatedWith(Names.named("user")).to(new TypeLiteral<DeserialiserImp<User>>(){});
bind(new-TypeLiteral(){}).annotatedWith(Names.named(“user”)).to(new-TypeLiteral(){});
那么我需要做的就是使用它

@Inject
@Named("user")
private Deserialiser<User> deserialiserImp;

public void test(String userString) {
    User user = deserialiserImp.get(UserString);
}
@Inject
@命名(“用户”)
私有反序列化器反序列化器;
公共无效测试(字符串用户字符串){
User User=deserialisermp.get(UserString);
}
如果类作为抽象类在DAO对象中使用,这种模式也可以很好地工作


这篇文章帮助了我

我关于使用TypeLiteral的观点来自于这个问题,它说“这里使用的技巧是泛型超类型的签名存储在子类中,因此在删除后仍然有效。”我希望不要传入该类型。好的,我理解。我在这里看不到任何实际的解决方案,您需要将类型存储在某个地方(普通类对象作为字段,使用TypeLiteral等…),以便在运行时检索它。我不认为每次传递类型都是一个大问题,因为所有解组库都需要它。不过,我想看看其他的方法。我正在努力使代码更简洁。在实例化反序列化映射时,当我将类型作为泛型传入时,我必须将类传入方法,然后我还需要强制转换接收到的对象。这是我引用类型的3次。看起来我指的是别的东西,但我意识到我误解了什么。谢谢,我喜欢。我不知道TypeLiteral类型会自动注入。又好又干净,看到了吗