【问题标题】:JSON to POJO as Object class using jackson javaJSON到POJO作为使用jackson java的对象类
【发布时间】:2020-03-18 01:45:00
【问题描述】:

我正在尝试使用 DTO 到 JSON(写入 Json 文件)和 JSON 到 DTO(从 JSON 文件读取)作为常用方法(不同 pojo 写入/读取操作使用的通用方法)

为了作为常用方法,我使用返回类型作为对象。

在我的代码下面

public String dtoToJSON(String appName, Object obj) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        String postJson = mapper.writeValueAsString(obj);
        System.out.println(postJson);

        // Save JSON string to file
        FileOutputStream fileOutputStream = new FileOutputStream("post.json");
        mapper.writeValue(fileOutputStream, obj);
        fileOutputStream.close();
        return appName;

    }

public Object jsonToDto() throws IOException {
         ObjectMapper mapper = new ObjectMapper();

            // Read JSON file and convert to java object
            InputStream fileInputStream = new FileInputStream("post.json");
            Object obj = mapper.readValue(fileInputStream, Object.class);
            fileInputStream.close();
        return obj;

    }

我能够成功地将 DTO 运行到 JSON(写入 Json 文件),但是当我尝试将 JSON 运行到 DTO(从 JSON 文件中读取)时,我得到 ClassCastException

我的例外: 线程“主”java.lang.ClassCastException:无法将 java.util.LinkedHashMap 转换为 com.me.dto.Post

我的主要方法

public static void main(String[] args) throws IOException {
          Transform ts=new Transform();

          Post post=(Post)ts.jsonToDto();

        // print post object
        System.out.println("Printing post details");
        System.out.println(post.getId());
        System.out.println(post.getTitle());
        System.out.println(post.getDescription());
        System.out.println(post.getContent());
        System.out.println(post.getLastUpdatedAt());
        System.out.println(post.getPostedAt());

    }
}

如果我错了,请告诉我。

提前致谢。

【问题讨论】:

标签: java json spring-boot java-8 jackson


【解决方案1】:

它说 thread "main" java.lang.ClassCastException: Cannot cast java.util.LinkedHashMap to com.me.dto.Post,这意味着您的 ts.jsonToDto() 返回一个 LinkedHashMap 并且不能转换为您的 DTO。

您可以参考here 了解更多信息。

问题来自杰克逊。当它没有足够的关于反序列化到哪个类的信息时,它使用 LinkedHashMap。

由于您没有通知 Jackson 您的 ArrayList 的元素类型,它不知道您想要反序列化为 Accounts 的 ArrayList。所以它会回退到默认值。

他们还在那里为您提供了解决方案。

【讨论】:

    【解决方案2】:

    如果你调试代码,你会在课堂上看到下面的代码 com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer

    ....
    switch (p.getCurrentTokenId()) {
                case JsonTokenId.ID_START_OBJECT:
                    {
                        JsonToken t = p.nextToken();
                        if (t == JsonToken.END_OBJECT) {
                            return new LinkedHashMap<String,Object>(2);
                        }
                    }
                case JsonTokenId.ID_FIELD_NAME:
                    return mapObject(p, ctxt);
    ....
    

    从上面我们可以看出,如果你的Class是java.lang.Object,它将执行JsonTokenId.ID_START_OBJECT的case,并返回一个LinkedHashMap作为结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多