Add MapperFeature.REQUIRE_TYPE_ID_FOR_SUBTYPES
to enable/disable strict subtype Type Id handling · Issue #3853 · FasterXML/jackson-databind (original) (raw)
Describe the bug
In 2.14, if you setup @JsonTypeInfo(use = Id.NAME)
then all JSON passed to readValue
must include the @type
information, but that's no longer true in 2.15, which will now unmarshall JSON with missing type information (as long as no other constraints fail). Although I guess it's possibly something to consider as an improvement, but personally I would like to ensure that clients must pass the type information, not least so that one cannot accidentally send the wrong JSON, but have it pass because it's close enough to the intended type.
Version information
2.15.0-rc2
To Reproduce
Unit test:
import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.exc.InvalidTypeIdException;
public class RegressionTest {
@Test
public void testTypeRequired() throws Exception {
ObjectMapper om = new ObjectMapper();
DoSomethingCommand cmd = om.readValue("{\"@type\":\"do-something\"}", DoSomethingCommand.class);
assertThat(cmd).isNotNull();
// Prove that we can't load the command _without_ the type information
// This assertion passes in 2.14, but fails in 2.15 as nothing is thrown and the instance
// is unmarshalled anyway
assertThrows(InvalidTypeIdException.class, () -> om.readValue("{}", DoSomethingCommand.class));
}
}
@JsonTypeInfo(use = Id.NAME) interface Command { }
@JsonTypeName("do-something") class DoSomethingCommand implements Command { }
/*
- This highlights why I think it's dangerous to accept the JSON with no type information. A
- client might accidentally send this structure, but without the type information, which would
- be rejected in 2.14, but with 2.15 it would be accepted (incorrectly IMHO) */ @JsonTypeName("do-something-else") class DoSomethingElseCommand extends DoSomethingCommand { }
Expected behavior
The unit test passes, as an InvalidTypeIdException
is thrown when no type information is present in the incoming JSON, as was the case in 2.14