由于输入结束 Jackson 解析器,没有要映射的内容

我从服务器 {"status":"true","msg":"success"}得到这个响应

我尝试使用 Jackson 解析器库来解析这个 json 字符串,但是不知怎么的,我遇到了映射-异常声明

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

为什么我们会有这种例外?

如何理解是什么导致了这个异常?

我尝试使用以下方法进行解析:

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 类

@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;
}
}
326987 次浏览

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;


}
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

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

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.