【问题标题】:Java - How to handle dynamic JSON category name?Java - 如何处理动态 JSON 类别名称?
【发布时间】:2017-05-31 13:23:48
【问题描述】:

我正在尝试学习 JSON 解析,并且出现了一个关于如何解析 JSON 的快速问题,其中“类别”名称可以根据来自外部 API(特别是我正在玩的视频游戏 API)的请求而更改与)。

作为一个随机示例,使用“laofuthetiger”作为 URI 发送 API 请求会返回如下所示的 JSON:

{ "laofuthetiger": {
   "id": 51044840,
   "name": "Lao Fu the Tiger",
   "profileIconId": 664,
   "revisionDate": 1484537981000,
   "summonerLevel": 30
}}

将 URI 更改为“sloverlord”会产生以下结果:

{ "sloverlord": {
   "id": 39943538,
   "name": "sloverlord",
   "profileIconId": 712,
   "revisionDate": 1484537981000,
   "summonerLevel": 30
}}

根据我对使用 GSON 解析 JSON 的基本理解,我可以通过一个如下所示的类从第一个 JSON 示例中收集数据:

public class Player{
   private SummonerDto laofuthetiger;
...

其中 SummonerDto 包含单个元素 id、名称等。但是,我不知道如何处理 API 调用之间的实际“类别”(或无论如何调用)变化。使用此解决方案,使用 laofuthetiger 的调用可以正常工作,但 sloverlord 会由于显而易见的原因返回内部错误。

编辑:有关更多信息,URI 如下所示:dev.host.com/get_player_by_name/laofuthetiger?api_key=XXXXX 其中“laofuthetiger”可以是任何玩家名称。

【问题讨论】:

  • 可以更改 API 响应吗?
  • 如果更改 API 响应是指重新格式化它,那么不; API 完全是外部的,不受我的控制:/
  • 如果您使用的是 Jackson:stackoverflow.com/questions/17685508/…

标签: java json parsing dynamic


【解决方案1】:

使用GSON

import java.util.Map; 

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

JsonParser parser = new JsonParser();
//e.getKey() is actual 'category' name
//e.getValue() is raw JsonObject
Map.Entry<String, JsonElement> e = ((JsonObject)parser.parse(jsonString)).entrySet().iterator().next();
Gson g = new Gson();
SummonerDto dto = g.fromJson(e.getValue(), SummonerDto.class);

使用Jackson

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper om = new ObjectMapper();
JsonNode tree = om.readTree(jsonString);
JsonNode dtoNode = tree.get(0);
SummonerDto dto = om.readValue(om.treeAsTokens(dtoNode), SummonerDto.class);

更新

添加了 GSON 的完整代码

import java.io.IOException;
import java.util.Map;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class Test {

    private static final String JSON = "{ \"laofuthetiger\": {" + "\"id\": 51044840,"
            + "\"name\": \"Lao Fu the Tiger\"," + "\"profileIconId\": 664," + "\"revisionDate\": 1484537981000, "
            + "\"summonerLevel\": 30" + "}}";

    public static void main(String[] args) throws IOException {
        JsonParser parser = new JsonParser();
        Map.Entry<String, JsonElement> e = ((JsonObject) parser.parse(JSON)).entrySet().iterator().next();
        Gson g = new Gson();
        SummonerDto dto = g.fromJson(e.getValue(), SummonerDto.class);

        System.out.println(dto);
        }

    class SummonerDto {
        int id;
        String name;
        int profileIconId;
        long revisionDate;
        int summonerLevel;

        @Override
        public String toString() {
            return "SummonerDto [id=" + id + ", name=" + name + ", profileIconId=" + profileIconId + ", revisionDate="
                    + revisionDate + ", summonerLevel=" + summonerLevel + "]";
        }

    }

输出

SummonerDto [id=51044840, name=Lao Fu the Tiger, profileIconId=664, revisionDate=1484537981000, summonerLevel=30]

【讨论】:

  • Entry 是一个独立的类吗?
  • 我问的原因是因为 entrySet 在这种用法中似乎是未定义的。
  • 谢谢!这确实有帮助。
  • @zeBugMan :很高兴为您提供帮助。如果您觉得我的回答有用,请点赞/接受。
【解决方案2】:

有一个选项:

你总是知道你的播放器的名字吧?

当你可以使用你的 API 时,它是这样的:

    mPlayer = "laofuthetiger";

    Repository mRepo = new Repo();
    mRepo.requestPlayerByName(player)

[when you get your response]

 private void getMyResponseFromAPI(Json jsonResponse){
     JsonObject jSummoner jsonResponse.get(mPlayer).getAsJsonObject()
     SummonerDto summoner = new Gson().fromJson(jPlayer, Summoner.class)

     Player player = new Player(summoner)
 }

这样,无论玩家(或召唤者)的姓名如何,您总能得到回应。

为什么有效?

您的 API 响应中唯一改变的部分是 Summoner 名称...响应的其余部分始终遵循相同的模式。所以,如果你得到正确名称的 Json 对象,你将永远拥有这个:

{
   "id": 51044840,
   "name": "Lao Fu the Tiger",
   "profileIconId": 664,
   "revisionDate": 1484537981000,
   "summonerLevel": 30
}

这真的是用 Gson(或 Jackson)解析。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-22
    • 2019-09-11
    • 1970-01-01
    • 2015-05-11
    • 1970-01-01
    相关资源
    最近更新 更多