用Jackson反序列化泛型类型

时间:2012-10-29 09:23:23

标签: 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) 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));
        }

    }

我对此实施有2个问题。

第一个是我将类类型传递给方法,因此objectmapper知道应该反序列化的类型。使用泛型有更好的方法吗?

同样在get方法中,我将一个从objectMapper返回的对象转换为T.这似乎是特别讨厌的方式,因为我必须在这里强制转换T然后我还必须从方法中转换对象类型叫它。

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

2 个答案:

答案 0 :(得分:5)

  

首先是我将类类型传递给方法所以   objectmapper知道应该反序列化的类型。还有更好的吗?   使用泛型的方式?

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

  

同样在get方法中,我正在转换从中返回的对象   objectMapper to T.这看起来像我一样非常讨厌   必须在这里施放T然后我还必须从中投射对象类型   调用它的方法。

请改为:

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

我在这个项目中使用Roboguice所以如果可以的话我会很好   通过注入更改类型,然后注释对象   Generic类型我需要它返回。我读到了关于TypeLiteral和   想知道它是否可以解决这个问题?

我真的不明白你想要达到什么目标,但是既然你需要通过课程,那还有可能吗?

答案 1 :(得分:5)

所以我想我最终弄明白了。如果你看到我正在做的事情有问题,请发表评论。

接口的定义如下......

public interface Deserialiser<T> {

    T get(String content) throws IOException;

    List<T> getList(String content) throws IOException;
}

界面的实现就是这样......

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));
    }

}

我像这样绑定2 ..

    bind(new TypeLiteral<Deserialiser<User>>(){}).annotatedWith(Names.named("user")).to(new TypeLiteral<DeserialiserImp<User>>(){});

然后我需要做的就是使用它......

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

public void test(String userString) {
    User user = deserialiserImp.get(UserString);
}

如果将类作为要在DAO对象中使用的抽象类

,则此模式也可以正常工作

This文章帮助了我