JSON普通旧java对象的对象数组

时间:2017-03-30 12:28:53

标签: java json gson pojo

这是我第一次用Java进行外部api调用,所以请耐心等待,因为我不是很有经验。我得到了http请求,并得到了响应,但现在我需要解析它。

我正在尝试将json数组转换为java对象。我理解它的要点,但我见过的所有例子都不适用于我的问题。

我需要json字符串中的'entities'对象。细节(也是一个数组)可以包含任何键/值对,所以我想把它放在每个Entity对象的hashmap中。我已经尝试了gson库,但我找不到任何比单维json数组更深的gson示例。

我意识到这是一个广泛的问题,我不希望任何人向我提供有效的解决方案,但是一些提示或指向相关指南的链接将会有很长的路要走。 :)

{
   "return": {
      "entities": [
         {
            "id": 2385,
            "details": [
               {
                  "name": "Other Known Name",
                  "value": "John Wick",
                  "match": false
               }
            ],
            "proofs": [],
            "link": "http://domain.gg/users?id=2385"
         },
         {
            "id": 2384,
            "details": [
               {
                  "name": "Discord ID",
                  "value": "159985870458322944",
                  "match": false
               },
               {
                  "name": "SteamID64",
                  "value": "76561197991558078",
                  "match": true
               },
               {
                  "name": "SteamVanity",
                  "value": "test",
                  "match": false
               },
               {
                  "name": "PS4",
                  "value": "John_S",
                  "match": false
               },
               {
                  "name": "XBox",
                  "value": "John S",
                  "match": false
               },
               {
                  "name": "Email",
                  "value": "john_smith@gmail.com",
                  "match": true
               },
               {
                  "name": "Comment",
                  "value": "Test user",
                  "match": false
               },
               {
                  "name": "Other Known Name",
                  "value": "Jonathan",
                  "match": false
               },
               {
                  "name": "Reddit",
                  "value": "/u/johns",
                  "match": true
               }
            ],
            "proofs": [],
            "link": "http://domain.gg/users?id=2384"
         },
         {
            "id": 1680,
            "details": [
               {
                  "name": "Other Known Name",
                  "value": "Johny",
                  "match": false
               },
               {
                  "name": "SteamID64",
                  "value": "76561198213003675",
                  "match": true
               }
            ],
            "proofs": [],
            "link": "http://domain.gg/users?id=1680"
         },
         {
            "id": 1689,
            "details": [
               {
                  "name": "Other Known Name",
                  "value": "JohnnyPeto",
                  "match": false
               },
               {
                  "name": "SteamID64",
                  "value": "76561198094228192",
                  "match": true
               }
            ],
            "proofs": [],
            "link": "http://domain.gg/users?id=1689"
         }
      ],
      "notice": "Showing 4 out of 4 matches."
   }
}

4 个答案:

答案 0 :(得分:1)

有许多json序列化/反序列化框架可用。我建议您查看Jackson

基本上,您必须创建与json模式对应的模型,并将json反序列化为对象。根据问题中的示例,模型将如下所示:

@JsonIgnoreProperties(ignoreUnknown = true)
class Response {

    @JsonProperty("return")
    private ResponseObject responseObject;

    public ResponseObject getResponseObject() {
        return responseObject;
    }

    public void setResponseObject(ResponseObject responseObject) {
        this.responseObject = responseObject;
    }
}

@JsonIgnoreProperties(ignoreUnknown = true)
class ResponseObject {
    private List<Entity> entities;

    public List<Entity> getEntities() {
        return entities;
    }

    public void setEntities(List<Entity> entities) {
        this.entities = entities;
    }


}   

@JsonIgnoreProperties(ignoreUnknown = true)
class Entity {
    private String id;
    private List<Details> details;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public List<Details> getDetails() {
        return details;
    }

    public void setDetails(List<Details> details) {
        this.details = details;
    }

}

@JsonIgnoreProperties(ignoreUnknown = true)
class Details {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

定义模型后,您可以使用ObjectMapper类来执行序列化/反序列化,例如:

ObjectMapper mapper = new ObjectMapper();
Response response = mapper.readValue("{\"return\": {\"entities\": [{\"id\": 2385,\"details\": [{\"name\": \"Other Known Name\",\"value\": \"John Wick\",\"match\": false}],\"proofs\": [],\"link\": \"http://domain.gg/users?id=2385\"},{\"id\": 2384,\"details\": [{\"name\": \"Discord ID\",\"value\": \"159985870458322944\",\"match\": false},{\"name\": \"SteamID64\",\"value\": \"76561197991558078\",\"match\": true},{\"name\": \"SteamVanity\",\"value\": \"test\",\"match\": false},{\"name\": \"PS4\",\"value\": \"John_S\",\"match\": false},{\"name\": \"XBox\",\"value\": \"John S\",\"match\": false},{\"name\": \"Email\",\"value\": \"john_smith@gmail.com\",\"match\": true},{\"name\": \"Comment\",\"value\": \"Test user\",\"match\": false},{\"name\": \"Other Known Name\",\"value\": \"Jonathan\",\"match\": false},{\"name\": \"Reddit\",\"value\": \"/u/johns\",\"match\": true}],\"proofs\": [],\"link\": \"http://domain.gg/users?id=2384\"},{\"id\": 1680,\"details\": [{\"name\": \"Other Known Name\",\"value\": \"Johny\",\"match\": false},{\"name\": \"SteamID64\",\"value\": \"76561198213003675\",\"match\": true}],\"proofs\": [],\"link\": \"http://domain.gg/users?id=1680\"},{\"id\": 1689,\"details\": [{\"name\": \"Other Known Name\",\"value\": \"JohnnyPeto\",\"match\": false},{\"name\": \"SteamID64\",\"value\": \"76561198094228192\",\"match\": true}],\"proofs\": [],\"link\": \"http://domain.gg/users?id=1689\"}],\"notice\": \"Showing 4 out of 4 matches.\"}}", Response.class);
System.out.println(response.getResponseObject().getEntities().get(0).getId());

这里是Javadoc

答案 1 :(得分:0)

如果我是你,我会使用Jackson,而不是GSON。它专门研究JavaBeans风格的映射。写下这样的课程:

public class Detail{
    private String name;
    private String value;
    private boolean match;
    // + getters / setters
}

public class Entity{
    private int id;
    private List<Detail> details;
    private String link;
    private List<String> proofs;
    // you don't have any example data for this, so I'm assuming strings
    // + getters / setters
}

public class Result{
    private List<Entity> entities;
    private String notice;
    // + getters / setters
}

并使用

之类的内容进行转换
Result result = new ObjectMapper().readValue(json, Result.class);

答案 2 :(得分:0)

正如我的同事stackoverflow用户之前发布的那样,对于这种启动,Jackson API会更好。然而,我已经为Gson发布了你的问题的解决方案。

我注意到您希望将您的详细信息存储为ID为key的HashMap。但是,似乎这个id实际上与实体有关,而与细节无关。

免责声明,我懒得使用在线POJO生成器,因为我不想为所有Json元素创建对象;)它仍然展示了它应该如何完成:

class Main{

public static void main(String[] args) throws FileNotFoundException {
//this is just to load the json file
    String input = new Scanner(new File("test.txt")).useDelimiter("\\Z").next();

    System.out.println(input);
    Gson gson = new Gson();
    Example arr = gson.fromJson(input, Example.class);

    System.out.println(arr);
}

public class Detail {

    @SerializedName("name")
    @Expose
    public String name;
    @SerializedName("value")
    @Expose
    public String value;
    @SerializedName("match")
    @Expose
    public Boolean match;
    @Override
    public String toString() {
        return "Detail [name=" + name + ", value=" + value + ", match=" + match + "]";
    }

    }

public class Entity {

    @SerializedName("id")
    @Expose
    public Integer id;
    @SerializedName("details")
    @Expose
    public List<Detail> details = null;
    @SerializedName("proofs")
    @Expose
    public List<Object> proofs = null;
    @SerializedName("link")
    @Expose
    public String link;
    @Override
    public String toString() {
        return "Entity [id=" + id + ", details=" + details + ", proofs=" + proofs + ", link=" + link + "]";
    }

    }

public class Example {

    @SerializedName("return")
    @Expose
    public Return _return;

    @Override
    public String toString() {
        return "Example [_return=" + _return + "]";
    }

    }
public class Return {

    @SerializedName("entities")
    @Expose
    public List<Entity> entities = null;
    @SerializedName("notice")
    @Expose
    public String notice;
    @Override
    public String toString() {
        return "Return [entities=" + entities + ", notice=" + notice + "]";
    }

    }
}

<强>输出

Example [_return=Return [entities=[Entity [id=2385, details=[Detail [name=Other Known Name, value=John Wick, match=false]], proofs=[], link=http://domain.gg/users?id=2385], Entity [id=2384, details=[Detail [name=Discord ID, value=159985870458322944, match=false], Detail [name=SteamID64, value=76561197991558078, match=true], Detail [name=SteamVanity, value=test, match=false], Detail [name=PS4, value=John_S, match=false], Detail [name=XBox, value=John S, match=false], Detail [name=Email, value=john_smith@gmail.com, match=true], Detail [name=Comment, value=Test user, match=false], Detail [name=Other Known Name, value=Jonathan, match=false], Detail [name=Reddit, value=/u/johns, match=true]], proofs=[], link=http://domain.gg/users?id=2384], Entity [id=1680, details=[Detail [name=Other Known Name, value=Johny, match=false], Detail [name=SteamID64, value=76561198213003675, match=true]], proofs=[], link=http://domain.gg/users?id=1680], Entity [id=1689, details=[Detail [name=Other Known Name, value=JohnnyPeto, match=false], Detail [name=SteamID64, value=76561198094228192, match=true]], proofs=[], link=http://domain.gg/users?id=1689]], notice=Showing 4 out of 4 matches.]]

答案 3 :(得分:0)

尽管有答案建议您使用Jackson,但您仍然可以使用Gson轻松完成其默认配置,只需在映射之间创建正确的关系:

// A generic response, parameterized with <T>, can hold any type except of primitives
final class Response<T> {

    @SerializedName("return")
    final T ret = null;

}

final class EntitiesAndNotice {

    final List<Entity> entities = null;
    final String notice = null;

}

final class Entity {

    // Unlike Object and any its subclasses, `int` being a primitive cannot be nulled
    // Simple 0 won't work either, because the compiler will inline it
    // So it's a sort of cheating javac to return a value that holds 0 already
    final int id = Integer.valueOf(0);
    final List<Detail> details = null;
    // Your JSON document does not provide enough info on the elements type
    // So it depends on how Gson parses JSON tokens
    final List<Object> proofs = null;
    final URL link = null;

}

final class Detail {

    final String name = null;
    final String value = null;
    // The same for primitive booleans, or Boolean.FALSE
    final boolean match = Boolean.valueOf(false);

}

使用示例:

private static final String JSON = "{\"return\":{\"entities\":[{\"id\":2385,\"details\":[{\"name\":\"Other Known Name\",\"value\":\"John Wick\",\"match\":false}],\"proofs\":[],\"link\":\"http://domain.gg/users?id=2385\"},{\"id\":2384,\"details\":[{\"name\":\"Discord ID\",\"value\":\"159985870458322944\",\"match\":false},{\"name\":\"SteamID64\",\"value\":\"76561197991558078\",\"match\":true},{\"name\":\"SteamVanity\",\"value\":\"test\",\"match\":false},{\"name\":\"PS4\",\"value\":\"John_S\",\"match\":false},{\"name\":\"XBox\",\"value\":\"John S\",\"match\":false},{\"name\":\"Email\",\"value\":\"john_smith@gmail.com\",\"match\":true},{\"name\":\"Comment\",\"value\":\"Test user\",\"match\":false},{\"name\":\"Other Known Name\",\"value\":\"Jonathan\",\"match\":false},{\"name\":\"Reddit\",\"value\":\"/u/johns\",\"match\":true}],\"proofs\":[],\"link\":\"http://domain.gg/users?id=2384\"},{\"id\":1680,\"details\":[{\"name\":\"Other Known Name\",\"value\":\"Johny\",\"match\":false},{\"name\":\"SteamID64\",\"value\":\"76561198213003675\",\"match\":true}],\"proofs\":[],\"link\":\"http://domain.gg/users?id=1680\"},{\"id\":1689,\"details\":[{\"name\":\"Other Known Name\",\"value\":\"JohnnyPeto\",\"match\":false},{\"name\":\"SteamID64\",\"value\":\"76561198094228192\",\"match\":true}],\"proofs\":[],\"link\":\"http://domain.gg/users?id=1689\"}],\"notice\":\"Showing 4 out of 4 matches.\"}}";

private static final Gson gson = new Gson();

private static final TypeToken<Response<EntitiesAndNotice>> responseTypeToken = new TypeToken<Response<EntitiesAndNotice>>() {
};

public static void main(final String... args) {
    final Response<EntitiesAndNotice> response = gson.fromJson(JSON, responseTypeToken.getType());
    final String value = response.ret.entities.get(1).details.get(3).value;
    System.out.println(value);
}

输出:

  

John_S