Paul Taylor
Paul Taylor

Reputation: 13210

jackson failing to map empty array with No content to map to Object due to end of input

I send a query to an api and map the json results to my classes using Jackson. When I get some results it works fine, but when there are no results it fails with

java.io.EOFException: No content to map to Object due to end of input
at org.codehaus.jackson.map.ObjectMapper._initForReading(ObjectMapper.java:2766)
at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2709)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1854)
at com.jthink.discogs.query.DiscogsServerQuery.mapQuery(DiscogsServerQuery.java:382)
at com.jthink.discogs.query.SearchQuery.mapQuery(SearchQuery.java:37)*

But the thing is the api isn't returning nothing at all, so I dont see why it is failing.

Here is the query:

http://api.discogs.com/database/search?page=1&type=release&release_title=nude+and+rude+the+best+of+iggy+pop

this is what I get back

{
    "pagination": {
        "per_page": 50,
        "pages": 1,
        "page": 1,
        "urls": {},
        "items": 0
    },
    "results": []
}

and here is the top level object Im trying to map to

public class Search
{
    private Pagination pagination;
    private Result[] results;

    public Pagination getPagination() {
        return pagination;
    }

    public void setPagination(Pagination pagination) {
        this.pagination = pagination;
    }

    public Result[] getResults() {
        return results;
    }

    public void setResults(Result[] results) {
        this.results = results;
    }
}

Im guessing the problem is something to do with the results array being returned being blank, but cant see what Im doing wrong

EDIT: The comment below was correct, although I usually receive

{
    "pagination": {
        "per_page": 50,
        "pages": 1,
        "page": 1,
        "urls": {},
        "items": 0
    },
    "results": []
}

and in these cases there is no problem but sometimes I seem to just get an empty String. Now Im wondering if the problem is how I read from the inputstream

 if (responseCode == HttpURLConnection.HTTP_OK)
        InputStreamReader in= new InputStreamReader(uc.getInputStream());
        BufferedReader    br= new BufferedReader(in);
        while(br.ready())
        {
            String next = br.readLine();
            sb.append(next);
        }
        return sb.toString();
  }

although I dont read until I get the response code, is it possible that the first time I call br.ready() that I call it before it is ready, and therefore I don't read the input

EDIT 2:

Changing above code to simply

        String line;
        while ((line = br.readLine()) != null)
        {
            sb.append(line);
        }

resolved the issue.

Upvotes: 1

Views: 16784

Answers (2)

StaxMan
StaxMan

Reputation: 116512

Although there is one solution already, I would suggest alternative where you first create JsonParser and then see if there is any input, and if so, use data bind. This is much faster than reading input line by line, constructing a String, and then handing it to parser.

JsonParser jp = jsonFactory.createJsonParser(uc.getInputStream());
Search result = null;
if (jp.nextToken() != null) { // end-of-input
  result = jp.readValueAs(Search.class);
}
jp.close();
return result;

Upvotes: 1

Paul Taylor
Paul Taylor

Reputation: 13210

Changing above code to simply

        String line;
        while ((line = br.readLine()) != null)
        {
            sb.append(line);
        }

resolved the issue.

Upvotes: 0

Related Questions