【问题标题】:ObjectMapper doesn't fail on trailing charactersObjectMapper 在尾随字符上不会失败
【发布时间】:2020-05-19 09:43:31
【问题描述】:

我正在上以下课程:

public class Car{
private String id;
private String name;

public Car() {
}

public Car(String id, String name) {
    this.id = id;
    this.name = name;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

}

我是这样使用它的:

String json = "{\"id\":\"1\", \"name\":\"hh\"} {\"id\":\"2\", \"name\":\"ccc\"}";

    Car car;
    try {
        ObjectMapper mapper = new ObjectMapper();
        car = mapper.readValue(json, new TypeReference<Car>() {
        });
    } catch (IOException e) {
        car = null;
    }

我预计它会失败,但相反,我得到了输入中的第一个对象,即“第一个”汽车对象。

为什么会这样?

【问题讨论】:

  • 嘿,@YanKhonski 我知道我可以用数组来做到这一点。我的示例中的 json 参数实际上来自一个文件。我希望它有一个对象,但如果它有多个对象,我希望它失败。我更改了对象并删除了“,”仍然是第一个而不是失败
  • "{\"id\":\"1\", \"name\":\"hh\"} {\"id\":\"2\", \"name\":\"ccc\"}" json 无效,汽车对象之间缺少逗号 ,
  • 我知道并且我希望它会失败,但是 mapper.readValue 函数返回第一个对象并忽略第二个。在这个函数之后,汽车参数将保存 id = 1 & name -"hh"
  • 请检查我的答案。抱歉来晚了。

标签: java json jackson objectmapper


【解决方案1】:

这种情况下需要开启FAIL_ON_TRAILING_TOKENS功能抛出异常:

ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS);

或自版本2.10:

ObjectMapper mapper = JsonMapper.builder()
        .enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS)
        .build();

来自文档:

在绑定后确定数据绑定行为的功能 根值。如果启用了该功能,则再调用一次 JsonParser.nextToken() 是为了确保找不到更多的令牌 (如果找到,则抛出MismatchedInputException);如果 禁用,不进行进一步检查。功能也可以是 称为READ_FULL_STREAM,因为它有效地验证了输入 流仅包含绑定完整数据所需的数据 值,仅此而已(除了可能的可忽略空白或 cmets,如果数据格式支持)。

功能默认禁用(因此不会检查是否可能 出于向后兼容性的原因。

您可以启用FAIL_ON_* 系列的所有功能,使其尽可能严格。

【讨论】:

    【解决方案2】:

    另类。 请注意,您的类型引用不是Car,而是Cars 的List

    final ObjectMapper mapper = new ObjectMapper();
    final TypeReference<List<Car>> typeReference = new TypeReference<List<Car>>() {};
    
    
    final String json = "{\"id\":\"1\", \"name\":\"hh\"} {\"id\":\"2\", \"name\":\"ccc\"}";
    List<Car> cars = null;
    
    try {
        cars = mapper.readValue(json, typeReference);
    } catch (IOException e) {
        e.printStackTrace();   // TODO - Please, handle it
        cars = null;
    }
    
    System.out.println("Cars: " + cars);
    

    它将打印:

    com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.ArrayList<com.yk.training.backperssure.Car>` out of START_OBJECT token
     at [Source: (String)"{"id":"1", "name":"hh"} {"id":"2", "name":"ccc"}"; line: 1, column: 1]
        at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
        at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1464)
    
    // More stack trace.,..\
    
    Cars: null
    

    【讨论】:

      猜你喜欢
      • 2019-05-11
      • 1970-01-01
      • 2017-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-25
      相关资源
      最近更新 更多