【问题标题】:Unexpected end-of-input: expected close marker for OBJECT Map<String, Map<Object,Long>>意外的输入结束:OBJECT Map<String, Map<Object,Long>> 的预期关闭标记
【发布时间】:2020-05-14 11:45:54
【问题描述】:

我正在尝试在 Java 应用程序中创建 Map>,但是在尝试反序列化时出现下一个错误:

com.fasterxml.jackson.databind.JsonMappingException: Unexpected end-of-input: expected close marker for Object (start marker at [Source: (String)"{"number":10000000,"person":{"person1":{"{\"Name\":\"test\", \"userId\":\"test1\", \"requestDate\":null}":2222}}}"; line: 1, column: 106])


 at [Source: (String)"{"number":10000000,"person":{"test":{"{\"Name\":\"test\", \"userId\":\"test1\", \"requestDate\":null}":2222}}}"; line: 1, column: 191] (through reference chain: com.mycompany.mavenproject1.testClass["person"])

我创建了一个对象并向其中添加数据。之后我将它映射到字符串:

String personTest = map.writeValueAsString(myObject); 

这是它生成的字符串:

{"number":10000000,"person":{"test":{"{\"Name\":\"test\", \"userId\":\"test1\", \"requestDate\":null}":2222}}}

我正在尝试将其反序列化为:

testClass t2 = map.readValue(personTest , testClass.class);

TestClass 是下一个:

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class testClass implements Serializable{
    private final long number;

    @JsonDeserialize(contentUsing=ExampleClassJsonDeserializer.class)
    private Map<String, Map<Person, Long>> person;

    public testClass(){
        keepAliveTimeout = 10000000;
        person = new HashMap();
    }
}

【问题讨论】:

  • 我猜 JSON 字符串有问题 请验证一次 {"number":10000000, "person":{ "test":[ {"Name":"test", "userId ":"test1", "requestDate":null} ]}} 我做了一些改变,现在看起来很好
  • @AshishSharma 字符串取自 String personTest = map.writeValueAsString(t);

标签: java serialization jackson hashmap


【解决方案1】:

您的问题是因为您的地图键是 Person 对象,而不是简单的字符串。

没有足够的代码发布给我准确查明问题,但不知何故,Jackson 尝试从 Person 对象创建 JSON 字段名称,方法是编写 Person 对象 JSON,然后将其设为标签.结果是一场灾难:字段名称中的 Json 注入。

您要么必须自定义您的序列化程序以从您的人员对象中提取一个简单的字符串来创建一个字段名称,要么更改结构以替换:

Map<String, Map<Person, Long>> person;

Jackson 无需自定义即可处理的内容(因此,确保字段名称为简单标签):

class PersonWithLong { public Person; public Long value}
Map<String, Set<PersonWithLong>> person;

【讨论】:

    【解决方案2】:

    正如 amanin 所建议的,它可以通过自定义序列化器和反序列化器来完成。

    但最后最简单的解决方案是将 Object 序列化为 bytes[] 并将其编码为 Base64。所以没有必要编写自定义的 Serializer 或 Deserializer。

    以下代码适用于我:

    编码

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    oos = new ObjectOutputStream(bos);
    oos.writeObject(testObject);
    oos.flush();
    byte [] testObjectBytes = bos.toByteArray();
    String testObjectString = Base64.getEncoder().encodeToString(testObjectBytes);
    

    解码

    byte[] decoded = Base64.getDecoder().decode(testObjectString);
    ByteArrayInputStream in = new ByteArrayInputStream(decoded);
    is = new ObjectInputStream(in);
    testObject = (testClass)is.readObject();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-01
      相关资源
      最近更新 更多