2

I'm having the following 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;
}

}

and I use it like this:

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

I'm expecting it to fail but instead, I get the first object in the input, the "first" car object.

why is that happening?

israel berko
  • 556
  • 1
  • 5
  • 18
  • Please, check [How to use Jackson to deserialise an array of objects](https://stackoverflow.com/questions/6349421/how-to-use-jackson-to-deserialise-an-array-of-objects) – Yan Khonski May 19 '20 at 09:46
  • hey, @YanKhonski I know I can do it with an array. the json parameter in my example actually comes from a file. I expect it to have one object but I want it to fail if it has more then one object. I changed the object and remove the "," is still takes the first one instead of failing – israel berko May 19 '20 at 12:27
  • `"{\"id\":\"1\", \"name\":\"hh\"} {\"id\":\"2\", \"name\":\"ccc\"}"` not valid json, missing comma **,** between cars objects. – Yan Khonski May 19 '20 at 12:37
  • 1
    I know and I expecting it to fail but the mapper.readValue functions return the first object and ignore the second. after this function, the car parameter will hold the id = 1 & name -"hh" – israel berko May 19 '20 at 12:53
  • Please, check my answer. Sorry for coming late. – Yan Khonski May 23 '20 at 12:38

2 Answers2

2

You need to enable FAIL_ON_TRAILING_TOKENS feature to throw an exception in this case:

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

or since version 2.10:

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

From documentation:

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.

You can enable all features from FAIL_ON_* family to be as strict as possible.

Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
0

Alternative. Note, your type reference is not a Car, but a List of Cars.

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

It will print:

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
Yan Khonski
  • 12,225
  • 15
  • 76
  • 114