按类名反序列化json

如果我只有我的类的字符串名称,通过规范名称调用和对象的 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.class,Dog.class,Car.class等等。每个类都有不同的状态。我需要通用的反序列化方法。


我写的是这样的:


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。但也许有更好的方法?


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


慕村9548890
浏览 178回答 1
1回答

九州编程

问题源于编译器想要(实际上)为使用它的每个类型 T 制作此方法的不同实例。然而,在争论中没有任何东西可以挂起它的帽子。如果调用者不知道期望什么类,除了该类的 String 表示(我假设它也已保存在 JSON 中?),他将如何处理此调用的结果?由于他不知道,他必须将它用作简单的 Object,在这种情况下,该方法还不如简单地返回 Object。如果调用者确实知道这个类,那么他可以传入一个 Class 作为参数,你不会有任何问题。我在写这篇文章时突然想到,ObectMapper 的某些 readValue 方法必须有类似的问题,例如接受 ResolvedType 而不是 Class 的方法。我注意到,在该类的源代码中,它包含/unchecked/在类之前。我不确定这是否可以解决这个问题,但这是有道理的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java