ObjectMapper 不会在尾随字符上失败

ObjectMapper doesn't fail on trailing characters

我有以下 class:

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

我原以为它会失败,但我得到了输入中的第一个对象,"first" 汽车对象。

为什么会这样?

您需要启用 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();

来自文档:

Feature that determines behaviour for data-binding after binding the root value. If feature is enabled, one more call to JsonParser.nextToken() is made to ensure that no more tokens are found (and if any is found, MismatchedInputException is thrown); if disabled, no further checks are made. Feature could alternatively be called READ_FULL_STREAM, since it effectively verifies that input stream contains only as much data as is needed for binding the full value, and nothing more (except for possible ignorable white space or comments, if supported by data format).

Feature is disabled by default (so that no check is made for possible trailing token(s)) for backwards compatibility reasons.

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

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

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