0

I'm trying to use the api-stackexchange with java but when I do the request and try to parse the response with a json parser I have an error.

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", "stackoverflow")
    .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();
    }

}

And the error is:

com.google.gson.stream.MalformedJsonException: Expected literal value at line 1 column 19

Here is an example of the 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://stackoverflow.com/questions/10842231/how-to-push-oath-token-to-localstorage-or-localsession-and-listen-to-the-storage",
              "is_answered": false
            },...

Here is the URL of the request:

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

So what's the problem? Is the Json really malformed? Or did I do something not right?

Thanks, Anthony

Edit:

I'm now sure that the problem come to the request, I paste the response of the request via a browser in a text file that I host in a server Apache and it works fine. I am abble to parse the Json of the response.

2 Answers 2

2

Change this code:

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

to this code:

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

Otherwise you end up calling nextName() twice in a row, which is invalid.

Sign up to request clarification or add additional context in comments.

5 Comments

By the way, I'm one of the Gson maintainers and you caused me to panic quite a bit on this question. It took me a good ten minutes to figure out what the problem is!
Thanks, but this don't resolve my problem. I think the problem is on the http request. The response is maybe not a well formed Json. Why the reader.nextString() give me special characters and not the real next String.
How can I know if it's a BOM? I can't use the method in the link my inputStream is not mark supported.
Thank you @JesseWilson to bring me on the good way with the encoding thing.
2

The data in the response is compressed with the deflate algorithm. So, I encapsulated the InputStream with a GZIPInputStream:

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", "stackoverflow").
        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);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.