【问题标题】:How to convert JSON object from third party api into local POJO如何将第三方 api 中的 JSON 对象转换为本地 POJO
【发布时间】:2016-03-29 19:40:58
【问题描述】:

假设我调用第三方 API 以获取对象 Task,然后我得到以下 JSON 字符串作为回报:

 {
    "tasks": [
      {
        "id": 1,
        "code": "CODE",
        "description": "Dummy Task",
        "withConfirmation": false,
        "resource": {
          "id": "abcdef12-fe14-57c4-acb5-1234e7456d62",
          "group": "Doctor",
          "firstname": "Toto",
          "lastname": "Wallace",
      },
      {
        "id": 2,
        "code": "CODE",
        "description": "Dummyyy Taaask",
        "withConfirmation": false
      }
    ]
 }

在返回的 json 中,我们有一个 Task 可以与 Resource 连接。

在我们的系统中,任务如下:

@JsonAutoDetect
public class Task implements Serializable {

    private Integer id;
    private String code = "BASIC";
    private String description;
    private boolean withConfirmation = false;


    /**
     * CONSTRUCTOR
     */
    public Task() {
    }
    public Integer getId() {
        return id;
    }

    @JsonProperty
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }

    @JsonProperty
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

    @JsonProperty
    public boolean isWithConfirmation() {
        return withConfirmation;
    }
    public void setWithConfirmation(boolean withConfirmation) {
        this.withConfirmation = withConfirmation;
    }

    public String toString() {...
    }
}

资源看起来像这样:

public class Resource implements Serializable {
    ...

    private String firstname;
    private String lastname;
    private MedicalGroup group; // id + name + description
    private Set<Task> tasks = new HashSet<Task>(0);
    ...
    // getters and setters and toString etc.
    ...
}

因此,除了字段名称之外,主要区别在于 Task 不包含任何 Resource,但关系方向相反,这意味着 Task em>Resource 可以容纳 n Task

对于这种情况,序列化从第三方返回的 json 对象并将其转换/映射到我自己系统中的 pojo 的最佳方法是什么? 我目前正在阅读 Gson 文档以尝试它,但欢迎提出任何建议。 此代码必须易于重用,因为在多个项目中都需要它。

【问题讨论】:

  • 我们是否在资源和任务之间有一个连接字段,或者我们需要自省 json 响应以确定哪个任务拥有哪个资源?
  • 我们必须反省才能找到它
  • @Naruto 这是一个简单的例子。我的情况有点复杂,我认为需要更多的治疗......
  • 你有关系resource have many tasks,但你得到的json是task have resource,创建双向关系有什么问题?它会让你轻松。

标签: java json deserialization


【解决方案1】:

这不是完整的工作代码,因为我不知道你想如何使用Resource。 Json 应该创建新资源还是尝试找到已经存在的资源。你将如何从 json 创建MedicalGroup,因为它没有足够的数据。我打算在cmets中问这个,但是没有足够的空间。这是演示如何尝试解决除Resources to/from json 映射之外的大多数问题。

主要思想是在您的Task POJO 中添加@JsonAnyGetter public Map&lt;String, Object&gt; getAdditionalProperties()@JsonAnySetter public void setAdditionalProperty(String name, Resource value)

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {

        HashMap<String, Object> map= new HashMap<>();

        // IMPORTANT
        // here we can try to find resource that has this task
        // and export its info to json like this:


        // CHANGE THIS
        Resource res = new Resource();
        res.firstname = "Toto";
        res.lastname = "Wallace";

        // IMPORTANT END

        map.put("resource", res);

        return map;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Resource value) {
        // IMPORTANT
        // Here you have to create or find appropriate Resource in your code
        // and add current task to it
        System.out.println(name+" "+ value );
    }

完整演示:

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.io.Serializable;
import java.util.*;

public class Main3 {
private static String json = "{\n" +
        "    \"tasks\": [\n" +
        "      {\n" +
        "        \"id\": 1,\n" +
        "        \"code\": \"CODE\",\n" +
        "        \"description\": \"Dummy Task\",\n" +
        "        \"withConfirmation\": false,\n" +
        "        \"resource\": {\n" +
        "          \"id\": \"abcdef12-fe14-57c4-acb5-1234e7456d62\",\n" +
        "          \"group\": \"Doctor\",\n" +
        "          \"firstname\": \"Toto\",\n" +
        "          \"lastname\": \"Wallace\"\n" +
        "      }},\n" +
        "      {\n" +
        "        \"id\": 2,\n" +
        "        \"code\": \"CODE\",\n" +
        "        \"description\": \"Dummyyy Taaask\",\n" +
        "        \"withConfirmation\": false\n" +
        "      }\n" +
        "    ]\n" +
        " }";

public static void main(String[] args) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    TasksList tl = mapper.readValue(json, TasksList.class);
    String result = mapper.writeValueAsString(tl);
    System.out.println(result);
}

private static class TasksList {
    @JsonProperty(value = "tasks")
    private List<Task> tasks;
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Resource implements Serializable {
    @JsonProperty(value = "firstname")
    private String firstname;
    @JsonProperty(value = "lastname")
    private String lastname;

    // HAVE NO IDEA HOW YOU GONNA MAP THIS TO JSON
    // private MedicalGroup group; // id + name + description
    private Set<Task> tasks = new HashSet<Task>(0);

    @Override
    public String toString() {
        return "Resource{" +
                "firstname='" + firstname + '\'' +
                ", lastname='" + lastname + '\'' +
                ", tasks=" + tasks +
                '}';
    }
}

@JsonAutoDetect
public static class Task implements Serializable {

    private Integer id;
    private String code = "BASIC";
    private String description;
    private boolean withConfirmation = false;

    /**
     * CONSTRUCTOR
     */
    public Task() {
    }
    public Integer getId() {
        return id;
    }

    @JsonProperty
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }

    @JsonProperty
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

    @JsonProperty
    public boolean isWithConfirmation() {
        return withConfirmation;
    }
    public void setWithConfirmation(boolean withConfirmation) {
        this.withConfirmation = withConfirmation;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {

        HashMap<String, Object> map= new HashMap<>();

        // IMPORTANT
        // here we can try to find resource that has this task
        // and export its info to json like this:
        // CHANGE THIS

        Resource res = new Resource();
        res.firstname = "Toto";
        res.lastname = "Wallace";

        // IMPORTANT END

        map.put("resource", res);

        return map;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Resource value) {
        // IMPORTANT
        // Probably here you have to create or find appropriate Resource in your code
        // and add current task to it
        System.out.println(name+" "+ value );
    }

    @Override
    public String toString() {
        return "Task{" +
                "id=" + id +
                ", code='" + code + '\'' +
                ", description='" + description + '\'' +
                ", withConfirmation=" + withConfirmation +
                '}';
    }
}
}

【讨论】:

  • 只是为了让您知道我将尽快测试您的解决方案并在之后立即给您反馈。有时可能很难专注于一项任务......
【解决方案2】:

您可以使用 google 的Gson 库将Json 转换为Pojo Class

new Gson().fromJson(jsonString,Response.class);

【讨论】:

    猜你喜欢
    • 2015-09-13
    • 1970-01-01
    • 1970-01-01
    • 2015-02-17
    • 2017-06-28
    • 2020-09-17
    • 1970-01-01
    • 2019-07-06
    • 1970-01-01
    相关资源
    最近更新 更多