【问题标题】:How do I return a List<Object> from a JSON like this?如何从这样的 JSON 返回 List<Object>?
【发布时间】:2017-12-18 03:12:22
【问题描述】:

我正在使用 Giant Bomb API 制作网络应用。

我被卡住了,因为我需要从 GET 请求(使用 Unirest)获取搜索结果列表,然后方便地将其转换为称为建议的对象列表。

这就是我的问题所在:

private List<Suggestion> suggestions = new ArrayList<>();

public List<Suggestion> searchGames(){

    HttpResponse<String> request;
    try {
    request = Unirest.get("http://giantbomb.com/api/search/?api_key=xxxxxxxxxxxxxxxxxxxxxxxxx&format=json&resources=game&limit=10&field_list=name&query=creed")
                .header("Accept", "application/json")
                .asString();

    String requestString = request.toString(); //I can get my request as String, but that doesnt change much, I guess

    //>>> the problematic part <<<

    return suggestions;
}

我缺少一些可以让我将 JSON 响应从 Unirest 转换为列表的东西。这是我尝试过的:

  • GSON - JSON 格式问题(JSON 开头有一些数据,因为有 Limit、Offset 等字段)
  • Object Mapper (Unirest/Jackson) - 问题因为我得到的是 httpResponse 而不是 String/Object/JsonNode 等。
  • 使用 JSONObject、JSONArray 和 for 循环 - 也没有运气。

我来自 Unirest 调用的 JSON 看起来很像这样:

 {
        "error": "OK",
        "limit": 10,
        "offset": 0,
        "number_of_page_results": 1,
        "number_of_total_results": 3,
        "status_code": 1,
        "results": [
            {
                "name": "Assassin's Creed",
                "resource_type": "game"
            },
            {
                "name": "The Creed",
                "resource_type": "game"
            },
            {
                "name": "Assassin's Creed: Lost Legacy",
                "resource_type": "game"
            }
        ]
}

我有一个类似的 Game 类解决方案,我在其中显示名为游戏的列表。

private List<Game> games = new ArrayList<>();

public List<Game> getAllGames(){
    return games;
}

我使用输入 id 和标题的 GET 请求填充此列表。

来自 Giant Bomb API 的建议对我来说比较棘手,因为我使用外部 API 来获取对象列表,而不是输入我的输入数据。

我的 Suggestion.java 类如下所示:

package rest.library;


public class Suggestion {

    private long id;
    private String name;

    public Suggestion(){
    }

    public Suggestion(long id, String name) {
        this.id = id;
        this.name = name;
    }

    public long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

}

在我的控制器中我想这样做:

@RequestMapping("/search")
public List<Suggestion> searchGames() { return gameService.searchGames(); }

在 localhost:8080/search 下应该返回一个对象列表,其中包含从 JSON 请求获得的搜索结果。它应该看起来就像 localhost:8080/games 一样,它会返回我在 Postman 上使用 GET 发送的游戏列表。我知道我从 API 获得了字段“resource_type”并且没有“id”字段,但这是以后的问题,因为我认为填充选定的类字段并逐步添加 id 不会有那么大的问题。

【问题讨论】:

标签: java json spring unirest


【解决方案1】:

您需要一种将您从请求中收到的 String 对象映射到 HashMap 的方法,这样您就可以设置对象属性,并形成要返回的列表(即使有像 Jackson 这样的 API 可以实现REST 请求处理逻辑不那么痛苦)。

这意味着首先使用response.getEntity().getContent() 从HTTP 请求中获取InputStream,然后创建一个JSONParser,如here 所述。

这将使您能够从 JSON 字符串中获取属性,如 here 所示。

反过来,这将使您能够使用 setter 方法来创建自己的对象列表。

让我知道这是否有帮助。

【讨论】:

  • 这很好,我会尽快调查。和杰克逊在一起会更容易吗?我的意思是,我试过了,但也有问题。
  • 我在工作场所使用 Jackson,一旦设置好,就很容易了。您使用@GET 注释、@Path(PATH_HERE) 注释创建资源方法,并向方法添加参数(任何类型),这些参数表示方法主体和/或路径接受的内容。这应该足以自动将 JSON 请求正文转换为指定的 POJO。
  • 关于您的回答的另一个问题。为什么 request.getEntity().getContent() 提示我 getEntity() 无法解析?
  • 我不确定没有看到您当前的代码。使用您当前的代码创建另一个问题,我会看看是否可以解决。
  • 我遇到的问题也与我的 JSON 响应有关,如果结果超过 10 个,我的响应中没有包含 {} 括号。我使用了一个不同的外部 API 和一个更方便的 JSON 响应,然后通过 Jackson 映射就像一个魅力。
【解决方案2】:

我建议使用基于 apache http api 构建的 http-request。您可以创建类 ResponseData 来解析响应。

 private static final HttpRequest<ResponseData> HTTP_REQUEST = 
        HttpRequestBuilder.createGet("http://giantbomb.com/api/search", ResponseData.class)
        .addDefaultHeader("Accept", "application/json")
        .addDefaultRequestParameter("api_key", "xxxxxxxxxxxxxxxxxxxxxxxxx")
        .addDefaultRequestParameter("format", "json")
        .addDefaultRequestParameter("resources", "game")
        .addDefaultRequestParameter("limit", "10")
        .addDefaultRequestParameter("field_list", "name")
        .addDefaultRequestParameter("query", "creed")
        .build();

  List<Suggestion> searchGames() {
      ResponseHandler<ResponseData> responseHandler = HTTP_REQUEST.execute();
      ResponseData responseData = responseHandler.get();

      // Here create the List<Suggestion> from responseData   

      return suggestions
  }

private class ResponseData{
    private String error;
    private int limit;
    private int offset;
    private int number_of_page_results;
    private int number_of_total_results;
    private int status_code;
    private List<Result> results;

    //getters and setters
}

private class Result{
    private String name;
    private String resource_type;

    //getters and setters
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-21
    • 2022-07-11
    • 1970-01-01
    • 2012-01-27
    • 2016-06-13
    • 2022-09-24
    相关资源
    最近更新 更多