【问题标题】:Reading API and GSON Class读取 API 和 GSON 类
【发布时间】:2018-09-22 10:44:48
【问题描述】:

我是 JSON 数据格式和 java 编程语言的新手;因此,我找不到有效的答案。实际上,我必须阅读这个APIhttps://www.doviz.com/api/v1/currencies/all/latest,并从这个API中获取一些重要的内容。因此,我决定使用 google 的 GSON 类,并编写了这段代码。

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Scanner;
import com.google.gson.Gson;


public class Main {

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

        String line = "";
        String jsonString = "";
        URL myUrl = new   URL("https://www.doviz.com/api/v1/currencies/all/latest");
        BufferedReader reader = new BufferedReader( new InputStreamReader(myUrl.openStream()) );

        while( (line = reader.readLine()) != null ){
            System.out.println(line);
            jsonString += line;
        }
        reader.close();

        jsonString = jsonString.substring(1, jsonString.length() - 1);

        Gson gson = new Gson();
        Currency json = gson.fromJson(jsonString, Currency.class);
   }
}


public class Currency {

    public double getSelling(){
        return selling;
    }

    public double getBuyiing(){
        return buying;
    }

    public String getCode(){
        return code;
    }

    private double selling;
    private transient long update_date;
    private transient int currency;
    private double buying;
    private transient double change_rate;
    private transient String name;
    private transient String full_name;
    private String code;
}

此代码会导致错误,据我猜测,错误的主要原因是我没有像这样在子字符串中放置反斜杠:"{\"brand\":\"Jeep\", \"门\": 3}"

What I am wondering is why we need to put these backslash ?

【问题讨论】:

  • 错误是什么?
  • "此代码导致错误" 任何原因您不能在问题中包含错误消息?它是否包含一些敏感信息,如密码或其他?在这种情况下,您可以将它们替换为 PASSWORD 而不是真实内容。
  • BTW jsonString += line; 对于较长的字符串来说效率非常低,因为对于每个新行,它需要复制所有以前的内容,然后添加新行。看看Why StringBuilder when there is String?

标签: java json gson json-deserialization


【解决方案1】:

有两件事要提。

  1. " 字符是字符串分隔符。字符串从" 标记开始,到下一个标记结束。 (当显式初始化它时,不使用其他变量)如果你想在你的字符串中包含"字符,你需要像\"一样转义它——所以Java知道它不是字符串的结尾,只是一部分内容。

  2. 在 JSON 中你应该使用单引号 ' - 许多库也接受双引号,但实际上它是不正确的,如果任何 api 抱怨它们,API 是正确的。 所以你的有效载荷应该看起来像{'brand': 'Jeep', 'doors': 3}我的意思当然是相反的。

【讨论】:

  • 感谢您的帮助和解释。
  • 呃,在阅读 Yug 的回答后,我注意到单双引号 json 语法严重混淆了......
【解决方案2】:

当你收到来自 api 的 JSON 输出时,你可以直接使用输出并且可以反序列化它。您不需要在 json 字符串中包含转义字符。当您自己定义 json 字符串时,它们是必需的。例如String s = "{\"current_user_url\"}";,因为是编译器强制你转义它。但是您作为 API 响应获得的 json 输出是在一个变量中,如果变量的类型和您分配给它的内容相同,那么编译器就无法解决这个问题。

现在,我只使用了您的代码,但使用了 Github 公共 API,并且我能够反序列化输出 json,而无需对输出字符串进行任何操作,例如转义 "" 或更改 "" to ''

class Github {
    private String current_user_url;
    private String authorizations_url;

    public String getCurrent_user_url() {
        return current_user_url;
    }
    public void setCurrent_user_url(String current_user_url) {
        this.current_user_url = current_user_url;
    }
    public String getAuthorizations_url() {
        return authorizations_url;
    }
    public void setAuthorizations_url(String authorizations_url) {
        this.authorizations_url = authorizations_url;
    }
}

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

        String line = "";
        String jsonString = "";
        URL myUrl = new   URL("https://api.github.com");
        BufferedReader reader = new BufferedReader( new InputStreamReader(myUrl.openStream()) );

        while( (line = reader.readLine()) != null ){
            //System.out.println(line);
            jsonString += line;
        }
        reader.close();

        System.out.println(jsonString);


        Gson g = new Gson();
        Github gi = g.fromJson(jsonString, Github.class);
        System.out.println(gi.getAuthorizations_url());
        System.out.println(gi.getCurrent_user_url());
}

我还自己定义了 json 字符串并使用 GSON 对其进行反序列化。在这种情况下,在定义 json 字符串时,我需要转义双引号,如下所示:

String s = "{\"current_user_url\":\"http://test.com/user\"}";

Gson g = new Gson();
Github gi = g.fromJson(s, Github.class);
System.out.println(gi.getCurrent_user_url());

此外,JSON 字符串应仅包含 double quotes,如果您使用 single quotes,则可能会出错。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 2017-10-12
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多