Как мне вернуть List<Object> из JSON, как это?

Я делаю веб-приложение, используя 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 loop - тоже не повезло.

Мой JSON из Unirest call выглядит примерно так:

 {
        "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, где я отображаю список под названием games.

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

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

Я заполняю этот список, используя GET-запросы, где я ввожу id и title.

Предложения от 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, который возвращает мне список игр, которые я отправил, используя GET на Postman. Я знаю, что я получаю поле "resource_type" из API, и в нем нет поля "id", но это проблема на потом, так как я думаю, что заполнение выбранных полей класса и добавление id постепенно не будет такой большой проблемой.

2 ответа

Решение

Вам нужен способ отобразить объект String, полученный из вашего запроса, в HashMap, чтобы вы могли затем установить атрибуты вашего объекта и сформировать список для возврата (даже несмотря на то, что существуют такие API, как Jackson, которые реализуют обработку запросов REST логика гораздо менее болезненная).

Это значит сначала получить InputStream из HTTP-запроса, используя response.getEntity().getContent()и затем создайте JSONParser, как упомянуто здесь.

Это позволит вам получить атрибуты из строки JSON, как показано здесь.

В свою очередь, это позволит вам использовать методы установки для создания собственного списка объектов.

Дайте мне знать, помогло ли это вообще.

Я рекомендую использовать http-запрос, основанный на apache http api. Вы можете создать класс 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
}
Другие вопросы по тегам