通过类名反序列化json

时间:2018-08-20 15:47:12

标签: java json serialization deserialization

如果我只有我的类的字符串名称,通过规范名称调用和对象的json字符串表示形式,如何从json字符串反序列化对象?

换句话说,我需要这样的方法:

public <T> T deserialize(String json, String className) {
 // some code
}

我们有类名和json字符串-我们需要将json反序列化为java对象。

如果我知道对象的类,我知道如何反序列化json到对象,例如,我们可以使用Jackson

String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }";
Car car = objectMapper.readValue(json, Car.class);  

但是在我的任务中,有一个不同的类-可能是Cat.classDog.classCar.class等,并且每个类的状态都不同。而且我需要 universal 方法来反序列化。

我写这样的东西:

public final class Utils implements Serializable {
    private Utils () {
        throw new AssertionError();
    }

    private static ObjectMapper objectMapper = new ObjectMapper();

    public static String toJson(Object obj) {
        String objectToJson;
        try {
            objectToJson = objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            throw new UncheckedIOException(String.format("Can't serialize object %s to JSON string", obj), e);
        }

        return objectToJson;
    }

    public static <T> T fromJson(String json, String className) throws ClassNotFoundException, IOException {
        Class<?> clz = Class.forName(className);
        return (T) objectMapper.readValue(json, clz);
    }
}

它适用于上面的汽车示例,但带有警告cast exception。 但是也许有更好的方法吗?

哦,并不是所有的对象都这么简单。其中一些会封装集合和其他对象。

1 个答案:

答案 0 :(得分:1)

问题源于编译器想要(实际上)为使用该方法的每种类型T创建此方法的不同实例。但是,论点中没有什么可以保留的。

如果调用者不知道期望的类,除了该类的String表示形式(我假设它也已经保存在JSON中?),他将如何处理的结果这个电话吗?由于他不知道,因此他必须仅将其用作Object,在这种情况下,该方法也可以简单地返回Object。

如果呼叫者确实知道该类,那么他可以传入一个类作为参数,这样您就不会有任何问题。

在撰写本文时,我想到ObectMapper的某些readValue方法必须有类似的问题,例如接受ResolvedType而不是Class的方法。我注意到,在该类的源代码中,它在该类之前包含/unchecked/。我不确定是否可以解决此问题,但这是有道理的。