【问题标题】:Java Http request on api.stackexchange with json response带有 json 响应的 api.stackexchange 上的 Java Http 请求
【发布时间】:2012-06-04 16:29:08
【问题描述】:

我正在尝试将 api-stackexchange 与 java 一起使用,但是当我执行请求并尝试使用 json 解析器解析响应时出现错误。

public ArrayList<Question> readJsonStream(InputStream in) throws IOException {
    JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
    reader.setLenient(true);
    try {
        System.out.println(reader.nextString()); // � special character
                    return readItem(reader);
    } finally {
        reader.close();
    }
}

public ArrayList<Question> readItem(JsonReader reader) throws IOException {
    ArrayList<Question> questions = new ArrayList<Question>();

    reader.beginObject();

    while (reader.hasNext()) {
        System.out.println("here");//not print the error is before
        String name = reader.nextName();
        if (name.equals("items")) {
            questions = readQuestionsArray(reader);
        }
    }
    reader.endObject();
    return questions;
}

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

    URIBuilder builder = new URIBuilder();
    builder.setScheme("http").setHost("api.stackexchange.com").setPath("/2.0/search")
    .setParameter("site", "*")
    .setParameter("intitle" ,"workaround")
    .setParameter("tagged","javascript");
    URI uri = builder.build();

    String surl = fixEncoding(uri.toString()+"&filter=!)QWRa9I-CAn0PqgUwq7)DVTM");
    System.out.println(surl);
    Test t = new Test();
    try {
        URL url = new URL(surl);
        t.readJsonStream(url.openStream());

    } catch (IOException e) {
        e.printStackTrace();
    }

}

错误是:

com.google.gson.stream.MalformedJsonException:预期的文字值 在第 1 行第 19 列

以下是 Json 的示例:

        {
          "items": [
            {
              "question_id": 10842231,
              "score": 0,
              "title": "How to push oath token to LocalStorage or LocalSession and listen to the Storage Event? (SoundCloud Php/JS bug workaround)",
              "tags": [
                "javascript",
                "javascript-events",
                "local-storage",
                "soundcloud"
              ],
              "answers": [
                {
                  "question_id": 10842231,
                  "answer_id": 10857488,
                  "score": 0,
                  "is_accepted": false
                }
              ],
              "link": "http://*.com/questions/10842231/how-to-push-oath-token-to-localstorage-or-localsession-and-listen-to-the-storage",
              "is_answered": false
            },...

这里是请求的 URL:

https://api.stackexchange.com/2.0/search?tagged=javascript&intitle=workaround&site=*&filter=!)QWRa9I-CAn0PqgUwq7)DVTM

那么问题是什么? Json真的格式不正确吗?还是我做错了什么?

谢谢,安东尼

编辑:

我现在确定问题出在请求上,我通过浏览器将请求的响应粘贴到我在服务器 Apache 中托管的文本文件中,它工作正常。我能够解析响应的 Json。

【问题讨论】:

    标签: java json httprequest gson


    【解决方案1】:

    更改此代码:

        if (name.equals("items")) {
            questions = readQuestionsArray(reader);
        }
    

    到此代码:

        if (name.equals("items")) {
            questions = readQuestionsArray(reader);
        } else {
            reader.skipValue();
        }
    

    否则你最终会连续两次调用nextName(),这是无效的。

    【讨论】:

    • 顺便说一句,我是 Gson 的维护者之一,你让我对这个问题感到相当恐慌。我花了十分钟才弄清楚问题所在!
    • 谢谢,但这并不能解决我的问题。我认为问题出在http请求上。响应可能不是格式良好的 Json。为什么 reader.nextString() 给我特殊字符而不是真正的下一个字符串。
    • 我如何知道它是否是 BOM?我无法使用链接中的方法我的 inputStream 未被标记支持。
    • 感谢@JesseWilson 为我带来了编码方面的好方法。
    【解决方案2】:

    响应中的数据使用 deflate 算法进行压缩。所以,我用 GZIPInputStream 封装了 InputStream:

    public final static void main(String[] args) throws Exception {
        URIBuilder builder = new URIBuilder();
    builder.setScheme("http").setHost("api.stackexchange.com").
            setPath("/2.0/search").
            setParameter("site", "*").
            setParameter("intitle" ,"workaround").
            setParameter("tagged","javascript");
    URI uri = builder.build();
    ArrayList<Question> q =null;
    String result = "";
    String surl = fixEncoding(uri.toString()+"&filter=!)QWRa9I-CAn0PqgUwq7)DVTM");
    System.out.println(surl);
    Test t = new Test();
    
        try {
        URL url = new URL(surl);
        q = t.readJsonStream(new GZIPInputStream(url.openStream()));        
    } 
    
        catch (IOException e) {
            e.printStackTrace();
        }
    
        System.out.println(result);
    
        for (Question question : q) {
            System.out.println(question.title);
        }
    }
    

    【讨论】:

      最近更新 更多