Swapnil Kadam
Swapnil Kadam

Reputation: 4293

No content to map due to end-of-input jackson parser

I am getting this response from the server {"status":"true","msg":"success"}

I am trying to parse this json string using Jackson parser library but somehow I am facing mapping-exception stating

com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input
 at [Source: java.io.StringReader@421ea4c0; line: 1, column: 1]

Why do we get this kind of exceptions?

How to understand what is causing this exception?

I am trying to parse using following way:

StatusResponses loginValidator = null;

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(Feature.AUTO_CLOSE_SOURCE, true);

try {
    String res = result.getResponseAsString();//{"status":"true","msg":"success"}
    loginValidator = objectMapper.readValue(result.getResponseAsString(), StatusResponses.class);
} catch (Exception e) {
    e.printStackTrace();
}

StatusResponse class

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({ "status","msg" })
public class StatusResponses {

    @JsonProperty("status")
    public String getStatus() {
        return status;
    }

    @JsonProperty("status")
    public void setStatus(String status) {
        this.status = status;
    }

    @JsonProperty("msg")
    public String getMessage() {
        return message;
    }

    @JsonProperty("msg")
    public void setMessage(String message) {
        this.message = message;
    }

    @JsonProperty("status")
    private String status;

    @JsonProperty("msg")
    private String message;

    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    @JsonGetter
    public Map<String, Object> getAdditionalProperties() {
        return additionalProperties;
    }

    @JsonSetter
    public void setAdditionalProperties(Map<String, Object> additionalProperties) {
        this.additionalProperties = additionalProperties;
    }
}

Upvotes: 123

Views: 437641

Answers (16)

theveriton
theveriton

Reputation: 21

If you see this in Jenkins, just restart your BuildSwarm (disable/enable).

Upvotes: 0

dobrivoje
dobrivoje

Reputation: 982

If input stream is already used before desired call, it can not be reused again. An example :

try (InputStream is = getClass().getClassLoader().getResourceAsStream("com/resources/attributes.json") ) {
        // We're using input stream !
        String jsonContent = IOUtils.toString(is, StandardCharsets.UTF_8);

        ObjectMapper om = new ObjectMapper();
        // We want to use input stream again
        // and it cases error : 
        // com.fasterxml.jackson.databind.JsonMappingException:
        //                No content to map due to end-of-input

        // We must delete or comment upper line : String jsonContent = IOUtils.toString...
        var result = om.readValue(is, new TypeReference<List<BehaviouralAttribute>>() {});
   
        

Upvotes: 0

user3008410
user3008410

Reputation: 848

I took your code to verify it and the only way you get the error is by sending it like this

String res = "";

Which is different than

String res = null;

So you can fix it by adding the following

if (res == null || res.length() < 1){
    //Handle however you want to handle it.
    System.out.println("RES CANNOT BE EMPTY or NULL.");
}

Naturally your res string must be a valid json string that can be mapped to the class you send in (in this case StatusResponses.class) but you need to encapsulate in a try/catch. Catch "com.fasterxml.jackson.databind.exc.MismatchedInputException: No content to map due to end-of-input" or in your case "com.fasterxml.jackson.databind.JsonMappingException". but if you just catch exception you can handle as you wish.

Upvotes: 0

Tushar
Tushar

Reputation: 15

Please Don't overthink this issue, simply handle the null pointer exception here as your response is received null and you will get your solution.

Upvotes: 0

Gilad Dahan
Gilad Dahan

Reputation: 566

In my case I had race condition between 2 threads trying to write and read the file simultaneously. I added the "synchronized" keyword on my methods which writes and reads to the file and the error is gone.

Upvotes: 0

Svend
Svend

Reputation: 7180

This error is sometimes (often?) hiding the real problem: a failure condition could be causing the content to be incorrect, which then fails to deserialize.

In my case, today, I was making HTTP calls and (foolishly) omitted to check the HTTP status code before trying to unmarshal the body of the response => my real problem was actualy that I had some authentication error, which caused a 401 Unauthorized to be sent back to me, with an empty body. Since I was unmarshalling that empty body directly without checking anything, I was getting this No content to map due to end-of-input, without getting any clue about the authentication issue.

Upvotes: 7

DS.
DS.

Reputation: 612

I got this error when sending a GET request with postman. The request required no parameters. My mistake was I had a blank line in the request body.

Upvotes: 4

simibac
simibac

Reputation: 8570

The problem for me was that I read the response twice as follows:

System.out.println(response.body().string());
getSucherResponse = objectMapper.readValue(response.body().string(), GetSucherResponse.class);

However, the response can only be read once as it is a stream.

Upvotes: 9

jd96
jd96

Reputation: 595

I had a similar error today and the issue was the content-type header of the post request. Make sure the content type is what you expect. In my case a multipart/form-data content-type header was being sent to the API instead of application/json.

Upvotes: 6

Ismail Yavuz
Ismail Yavuz

Reputation: 7045

I know this is weird but when I changed GetMapping to PostMapping for both client and server side the error disappeared.

Both client and server are Spring boot projects.

Upvotes: 1

Prakash Palnati
Prakash Palnati

Reputation: 3409

A simple fix could be Content-Type: application/json

You are probably making a REST API call to get the response.

Mostly you are not setting Content-Type: application/json when you the request. Content-Type: application/x-www-form-urlencoded will be chosen which might be causing this exception.

Upvotes: 1

Farrukh Najmi
Farrukh Najmi

Reputation: 5316

In my case the problem was caused by my passing a null InputStream to the ObjectMapper.readValue call:

ObjectMapper objectMapper = ...
InputStream is = null; // The code here was returning null.
Foo foo = objectMapper.readValue(is, Foo.class)

I am guessing that this is the most common reason for this exception.

Upvotes: 14

Omar Abdel Bari
Omar Abdel Bari

Reputation: 964

In my case I was reading the stream in a jersey RequestEventListener I created on the server side to log the request body prior to the request being processed. I then realized that this probably resulted in the subsequent read to yield no string (which is what is passed over when the business logic is run). I verified that to be the case.

So if you are using streams to read the JSON string be careful of that.

Upvotes: 1

Swapnil Kadam
Swapnil Kadam

Reputation: 4293

import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.databind.ObjectMapper;

StatusResponses loginValidator = null;

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(Feature.AUTO_CLOSE_SOURCE, true);

try {
    String res = result.getResponseAsString();//{"status":"true","msg":"success"}
    loginValidator = objectMapper.readValue(res, StatusResponses.class);//replaced result.getResponseAsString() with res
} catch (Exception e) {
    e.printStackTrace();
}

Don't know how it worked and why it worked? :( but it worked

Upvotes: 47

Virginia Woolf
Virginia Woolf

Reputation: 1268

For one, @JsonProperty("status") and @JsonProperty("msg") should only be there only when declaring the fields, not on the setters and geters.

In fact, the simplest way to parse this would be

@JsonAutoDetect  //if you don't want to have getters and setters for each JsonProperty
public class StatusResponses {

   @JsonProperty("status")
   private String status;

   @JsonProperty("msg")
   private String message;

}

Upvotes: -2

Amol
Amol

Reputation: 137

I could fix this error. In my case, the problem was at client side. By mistake I did not close the stream that I was writing to server. I closed stream and it worked fine. Even the error sounds like server was not able to identify the end-of-input.

OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
out.write(jsonstring.getBytes());
out.close() ; //This is what I did

Upvotes: 9

Related Questions