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

Posted

技术标签:

【中文标题】由于输入结束杰克逊解析器,没有要映射的内容【英文标题】:No content to map due to end-of-input jackson parser 【发布时间】:2015-01-11 13:16:44 【问题描述】:

我收到来自服务器"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;
    

【问题讨论】:

这也可能是由于连接超时造成的。如果客户端期望来自服务器的响应,但 HTTP 连接器的超时时间已超过 - 它将返回超时的“空白”响应 - 这可能会在尝试解析为 json 时导致此错误消息。对此的修复会有所不同 - 但增加超时时间是一种临时修复。 result 的类型是什么?会不会是因为result 的类型而在result 上调用getResponseAsString 两次?例如,许多语言的迭代器不能被遍历两次。 你应该把这行loginValidator = objectMapper.readValue(result.getResponseAsString(), StatusResponses.class);改成(res, ...) 【参考方案1】:
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();

不知道它是如何工作的以及为什么工作? :(但它有效

【讨论】:

认为这是因为当您调用 getResponseAsString() 时,它会从响应中读取所有字节并关闭连接。这就是为什么它可能会抛出异常 这是因为您替换的字符串 res 而不是因为 Feature.AUTO_CLOSE_SOURCE .... 我认为你应该为“不知道它是如何工作的以及为什么它工作?:(但它工作”诚实休闲......致敬...... 只是发布一段代码而不知道为什么它解决了这个问题值得我投反对票.. @Koloritnij 我认为你的评论是错误的:this method can be called several times yielding the same result each time【参考方案2】:

在我的情况下,问题是由于我将 null InputStream 传递给 ObjectMapper.readValue 调用引起的:

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

我猜这是这个异常最常见的原因。

【讨论】:

我的原因是一个空字符串。一样的 如何修复这个空输入流?【参考方案3】:

我可以修复这个错误。就我而言,问题出在客户端。错误地我没有关闭我正在写入服务器的流。我关闭了流,它工作正常。即使错误听起来像服务器无法识别输入结束。

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

【讨论】:

【参考方案4】:

对我来说问题是我阅读了两次回复如下:

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

但是,响应只能被读取一次,因为它是一个流。

【讨论】:

【参考方案5】:

我今天遇到了类似的错误,问题是发布请求的内容类型标头。确保内容类型符合您的预期。在我的情况下,multipart/form-data 内容类型标头被发送到 API,而不是 application/json

【讨论】:

【参考方案6】:

此错误有时(通常?)隐藏了真正的问题:失败条件可能导致内容不正确,然后无法反序列化。

就我而言,今天,我正在进行 HTTP 调用,并且(愚蠢地)在尝试解组响应正文之前省略了检查 HTTP 状态代码 => 我真正的问题实际上是我有一些身份验证错误,这导致一个401 Unauthorized 将被发回给我,但身体是空的。由于我没有检查任何东西就直接解组了那个空的身体,我得到了这个No content to map due to end-of-input,没有得到任何关于身份验证问题的线索。

【讨论】:

【参考方案7】:

我在使用邮递员发送 GET 请求时收到此错误。 该请求不需要任何参数。 我的错误是请求正文中有一个空行。

【讨论】:

【参考方案8】:

在我的例子中,我正在读取我在服务器端创建的球衣 RequestEventListener 中的流,以在处理请求之前记录请求正文。然后我意识到这可能导致后续读取不产生任何字符串(这是运行业务逻辑时传递的内容)。我证实确实如此。

因此,如果您使用流来读取 JSON 字符串,请注意这一点。

【讨论】:

【参考方案9】:

一个简单的修复方法是Content-Type: application/json

您可能正在调用 REST API 以获取响应。

大多数情况下,您在请求时没有设置Content-Type: application/jsonContent-Type: application/x-www-form-urlencoded 将被选中,这可能会导致此异常。

【讨论】:

【参考方案10】:

我知道这很奇怪,但是当我将客户端和服务器端的 GetMapping 更改为 PostMapping 时,错误消失了。

客户端和服务器都是 Spring boot 项目。

【讨论】:

【参考方案11】:

在我的例子中,我有 2 个线程试图同时写入和读取文件之间的竞争条件。我在写入和读取文件的方法上添加了“同步”关键字,错误消失了。

【讨论】:

【参考方案12】:

首先,@JsonProperty("status")@JsonProperty("msg") 应该只在声明字段时出现,而不是在 setter 和 getter 上。

事实上,解析这个最简单的方法是

@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;


【讨论】:

但这将如何解决映射异常?如果没有 getter 和 setter,我如何访问这些值以供进一步使用? 您仍然可以在没有注释的情况下添加 getter 和 setter。我认为您的注释使映射器感到困惑。

以上是关于由于输入结束杰克逊解析器,没有要映射的内容的主要内容,如果未能解决你的问题,请参考以下文章

DNS域名解析过程

DNS域名解析过程

DNS域名解析过程,DNS使用TCP还是UDP协议?

令人费解的 php 解析器错误

Appsync“批量创建”解析器给出“映射模板”错误

我可以在Aws AppSync解析器映射模板中对用户输入进行消毒吗?