【问题标题】:Calling external API and parsing JSON Object调用外部 API 并解析 JSON 对象
【发布时间】:2019-09-18 00:28:38
【问题描述】:

我正在尝试从外部 API 获取 JSON 并对其进行解析,以便我可以访问 JSON 对象值以避免我不需要的值(字段)。

我对 JSONOBject 库进行了一些研究并解析了对象,但是,感觉我编写了太多的硬编码并且根本没有正确执行,非常感谢反馈。

用户输入后的输出结果:

发送'GET'请求到URL:https://api.coindesk.com/v1/bpi/currentprice/(user输入货币)

在 UTC 时间/日期获取的数据:2019 年 9 月 17 日 22:51:00 UTC 说明:乌克兰格里夫纳 浮动利率:253737.6633

import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class App {

    public static void main(String[] args) throws IOException {

        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

        System.out.println("Please enter the currency you would like to get BTC current rate for");
        String userInput = in.readLine();


        try {

            String url = "https://api.coindesk.com/v1/bpi/currentprice/" + userInput;
            URL obj = new URL(url);

            // HttpURLConnection instance is making a request
            //openConnection() method of URL class opens the connection to specified URL
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();

            // saving the response code from the request
            int responseCode = con.getResponseCode();

            System.out.println("\nSending 'GET' request to URL : " + url);
            System.out.println("---------------------------------------------");
            System.out.println("Response Code from the HTTP request : " + responseCode);
            System.out.println("---------------------------------------------");

            //creating reader instance to reade the response from the HTTP GET request
            BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));

            String userInputLine;
            StringBuilder response = new StringBuilder();

            //if there is still something to read from -> then read and append to String builder -> can be mutable
            while ((userInputLine = reader.readLine()) != null) {
                response.append(userInputLine);
            }

            //closing reader
            reader.close();

            //Converting response to JSON object
            JSONObject myresponse = new JSONObject(response.toString());


            JSONObject bpiObject = new JSONObject(myresponse.getJSONObject("bpi").toString());
            JSONObject currencyObjects = new JSONObject(bpiObject.getJSONObject(userInput).toString());

            // since response got a objects within objects, we need to dig dipper in order to access field values
            JSONObject timeObject = new JSONObject(myresponse.getJSONObject("time").toString());
            System.out.println("Data fetched at UTC time/date : " + timeObject.getString("updated"));

            System.out.println("Description : " + currencyObjects.getString("description") + "\nRate float : " + currencyObjects.getString("rate_float"));


        } catch (Exception e) {
            System.out.println(e);

        }

    }
}

【问题讨论】:

  • 您可以使用ObjectMapper将json字符串转换为Java对象进行操作。
  • @LHCHIN 嘿,谢谢,我知道我可以使用字段(对象)创建一个 POJO 类,但是之后我将如何挖掘这些 JSON 对象 -> 例如,如果有 JSON 对象 {time } 和时间有一个名为“更新”的字段我如何访问该字段。

标签: java json api


【解决方案1】:

我编写了一个示例代码来演示我在评论中所说的内容,方法是使用ObjectMapper 将响应 json 字符串转换为 POJO。

首先,创建一个类,CoinDeskResponse 来存储转换结果。

public class CoinDeskResponse {
    private TimeInfo time;
    private String disclaimer;
    private BpiInfo bpi;
    //general getters and setters
}

class TimeInfo {
    private String updated;
    private String updatedISO;
    //general getters and setters
}

class BpiInfo {
    private String code;
    private String symbol;
    private String rate;
    private String description;

    @JsonProperty("rate_float")
    private String rateFloat;
    //general getters and setters
}

接下来,创建ObjectMapper 并将响应转换为CoinDeskResponse POJO。然后你就可以通过操作对象来得到想要的数据了。

    String responseStr = "{\"time\":{\"updated\":\"Sep 18, 2013 17:27:00 UTC\",\"updatedISO\":\"2013-09-18T17:27:00+00:00\"},\"disclaimer\":\"This data was produced from the CoinDesk Bitcoin Price Index. Non-USD currency data converted using hourly conversion rate from openexchangerates.org\",\"bpi\":{\"code\":\"USD\",\"symbol\":\"$\",\"rate\":\"126.5235\",\"description\":\"United States Dollar\",\"rate_float\":126.5235}}";
    ObjectMapper mapper = new ObjectMapper();
    try {
        CoinDeskResponse coinDeskResponse = mapper.readValue(responseStr, CoinDeskResponse.class);

        System.out.println(coinDeskResponse.getTime().getUpdated());
        System.out.println(coinDeskResponse.getBpi().getDescription());
        System.out.println(coinDeskResponse.getBpi().getRateFloat());
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

控制台输出:

在 UTC 时间/日期获取的数据:2013 年 9 月 18 日 17:27:00 UTC
说明 : 美元
浮动汇率:126.5235

【讨论】:

  • 当然字符串 responseStr 我可以用我的 API 端点来替换 @LHCHIN
  • @Tim Prozorov 当然,您可以将其替换为response.toString()。
  • 我已经添加了所有 POJO 类并将上面的 String 更改为 response.toString() > 我收到了 Time 对象,但其他两个对象为 null
  • @Tim Prozorov 你检查response.toString() 的结果了吗?它是否包含那些 json 对象(例如免责声明或 bpi)?
  • 我不得不为 BPI 对象创建另一个包装类,因为 USD 总是默认存在的,所以它提供了两个对象 Map bpi;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多