7

我正在尝试创建一个使用 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));
        }

    }

我有两个关于这个实现的问题。

首先是我将类类型传递给方法,以便对象映射器知道应该反序列化的类型。有没有更好的方法使用泛型?

同样在 get 方法中,我将从 objectMapper 返回的对象转换为 T。这似乎特别讨厌这样做,因为我必须在这里转换 T,然后我还必须从调用它的方法转换对象类型。

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

4

2 回答 2

5

首先是我将类类型传递给方法,以便对象映射器知道应该反序列化的类型。有没有更好的方法使用泛型?

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

同样在 get 方法中,我将从 objectMapper 返回的对象转换为 T。这似乎特别讨厌这样做,因为我必须在这里转换 T,然后我还必须从调用它的方法转换对象类型。

改为这样做:

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

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

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

于 2012-10-29T09:52:59.313 回答
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 对象中使用,这种模式也可以很好地工作

这篇文章帮助了我

于 2012-10-29T12:41:29.687 回答