Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Jackson-3] Address #493, disable DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES by default. #4625

Merged
merged 3 commits into from
Jul 20, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@ public enum DeserializationFeature implements ConfigFeature
* This setting only takes effect after all other handling
* methods for unknown properties have been tried, and
* property remains unhandled.
* Enabling this feature means that a {@link DatabindException}
* will be thrown if an unknown property is encountered.
*<p>
* Feature is enabled by default (meaning that a
* {@link DatabindException} will be thrown if an unknown property
* is encountered).
* Feature is disabled by default.
cowtowncoder marked this conversation as resolved.
Show resolved Hide resolved
*/
FAIL_ON_UNKNOWN_PROPERTIES(true),
FAIL_ON_UNKNOWN_PROPERTIES(false),

/**
* Feature that determines whether encountering of JSON null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public String getValue() {
public String accessValueForTest() { return value; }
}

private final ObjectMapper MAPPER = newJsonMapper();
private final ObjectMapper MAPPER = jsonMapperBuilder().enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).build();

/*
/**********************************************************************
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;

import tools.jackson.databind.DatabindException;
import tools.jackson.databind.DeserializationFeature;
import tools.jackson.databind.MapperFeature;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.exc.InvalidDefinitionException;
Expand Down Expand Up @@ -106,6 +107,7 @@ public static RecordWithExplicitFactoryMethod valueOf(String value) {

private final ObjectMapper MAPPER = jsonMapperBuilder()
.disable(MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS) // So that test cases don't have to assert weird error messages
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.build();

/*
Expand Down
5 changes: 3 additions & 2 deletions src/test/java/tools/jackson/databind/deser/AnySetterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,9 @@ public void testSimpleMapImitation() throws Exception
public void testAnySetterDisable() throws Exception
{
try {
MAPPER.readValue(a2q("{'value':3}"),
MapImitatorDisabled.class);
MAPPER.readerFor(MapImitatorDisabled.class)
.with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readValue(a2q("{'value':3}"));
fail("Should not pass");
} catch (UnrecognizedPropertyException e) {
verifyException(e, "Unrecognized property \"value\"");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public void testSimpleInclude() throws Exception
@Test
public void testIncludeIgnoredAndUnrecognizedField() throws Exception
{
ObjectReader r = MAPPER.readerFor(OnlyY.class);
ObjectReader r = MAPPER.readerFor(OnlyY.class).with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

// First, fine to get "y" only:
OnlyY result = r.readValue(a2q("{'x':3, 'y': 4}"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public void testSimpleSetterlessCollectionOk() throws Exception
@Test
public void testSimpleSetterlessCollectionFailure() throws Exception
{
ObjectMapper m = new ObjectMapper();
ObjectMapper m = jsonMapperBuilder().enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).build();
assertFalse(m.isEnabled(MapperFeature.USE_GETTERS_AS_SETTERS));

// and now this should fail
Expand Down Expand Up @@ -108,6 +108,7 @@ public void testSimpleSetterlessMapFailure() throws Exception
{
ObjectMapper m = jsonMapperBuilder()
.disable(MapperFeature.USE_GETTERS_AS_SETTERS)
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.build();
// so this should fail now without a setter
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@
import tools.jackson.databind.exc.UnrecognizedPropertyException;

import static org.junit.jupiter.api.Assertions.fail;

import static tools.jackson.databind.testutil.DatabindTestUtil.a2q;
import static tools.jackson.databind.testutil.DatabindTestUtil.verifyException;
import static tools.jackson.databind.testutil.DatabindTestUtil.*;

public class BuilderFailTest
{
Expand Down Expand Up @@ -68,7 +66,8 @@ public ValueClassXY build() {
/**********************************************************
*/

private final ObjectMapper MAPPER = new ObjectMapper();
private final ObjectMapper MAPPER = jsonMapperBuilder()
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).build();

@Test
public void testBuilderMethodReturnInvalidType() throws Exception
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,8 @@ private Value2354 build() {
/**********************************************************
*/

private final ObjectMapper MAPPER = newJsonMapper();
private final ObjectMapper MAPPER = jsonMapperBuilder()
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).build();

@Test
public void testSimple() throws Exception
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,9 @@ public void testAnySetterViaCreator562Disabled() throws Exception
{
// With 3.0 different fail type, message since we do we get parameter name info
try {
MAPPER.readValue(a2q("{'a':'value', 'b':42, 'c': 111}"),
PojoWithDisabled.class);
MAPPER.readerFor(PojoWithDisabled.class)
.with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readValue(a2q("{'a':'value', 'b':42, 'c': 111}"));
fail("Should not pass");
} catch (UnrecognizedPropertyException e) {
verifyException(e, "Unrecognized property \"b\"");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,9 @@ public void test1ArgDefaultsToPropsMultipleCtors() throws Exception
// 23-May-2024, tatu: Will fail differently with [databind#4515]; default
// constructor available, implicit ones ignored
try {
MAPPER_PROPS.readValue(a2q("{'value' : 137 }"),
SingleArg2CtorsNotAnnotated.class);
MAPPER_PROPS.readerFor(SingleArg2CtorsNotAnnotated.class)
.with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readValue(a2q("{'value' : 137 }"));
fail("Should not pass");
} catch (UnrecognizedPropertyException e) {
verifyException(e, "\"value\"");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ public void testCreatorWithRename4545() throws Exception
String jsonPayload = a2q("{ 'key1': 'val1', 'key2': 'val2'}");

try {
MAPPER.readValue(jsonPayload, Payload4545.class);
MAPPER.readerFor(Payload4545.class)
.with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readValue(jsonPayload);
fail("Should not pass");
} catch (UnrecognizedPropertyException e) {
verifyException(e, "Unrecognized");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

import tools.jackson.databind.DeserializationFeature;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.exc.UnrecognizedPropertyException;

Expand Down Expand Up @@ -151,7 +152,9 @@ public void testIgnoreUnknownViaConfigOverride() throws Exception

// First, fail without overrides
try {
MAPPER.readValue(DOC, Point.class);
MAPPER.readerFor(Point.class)
.with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readValue(DOC);
fail("Should not pass");
} catch (UnrecognizedPropertyException e) {
verifyException(e, "foobar"); // message varies between 2.x and 3.x
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,9 @@ static class Bean987 {
public void testUnknownHandlingDefault() throws Exception
{
try {
MAPPER.readValue(JSON_UNKNOWN_FIELD, TestBean.class);
MAPPER.readerFor(TestBean.class)
.with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readValue(JSON_UNKNOWN_FIELD);
fail("Should not pass");
} catch (UnrecognizedPropertyException jex) {
verifyException(jex, "Unrecognized property \"foo\"");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ static class VoidBean {
/**********************************************************************
*/

private final ObjectMapper VOID_MAPPER = sharedMapper();
private final ObjectMapper VOID_MAPPER = jsonMapperBuilder()
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.build();

private final ObjectMapper NO_VOID_MAPPER = jsonMapperBuilder()
.disable(MapperFeature.ALLOW_VOID_VALUED_PROPERTIES)
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.build();

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,8 @@ public void testBeanAsArrayMerging() throws Exception
// and finally with extra, failing
try {
MAPPER.readerForUpdating(input)
.readValue("[9, 8, 14]");
.with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readValue("[9, 8, 14]");
fail("Should not pass");
} catch (MismatchedInputException e) {
verifyException(e, "expected at most 2 properties");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ public void testHandlingOfUnrecognized() throws Exception
{
UnrecognizedPropertyException exc = null;
try {
MAPPER.readValue("{\"bar\":3}", Bean.class);
MAPPER.readerFor(Bean.class)
.with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readValue("{\"bar\":3}");
} catch (UnrecognizedPropertyException e) {
exc = e;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ public ValueClassXY build() {
public void testAccessorCustomWithMethod() throws Exception
{
final String json = a2q("{'x':28,'y':72}");
final ObjectMapper vanillaMapper = newJsonMapper();
final ObjectMapper vanillaMapper = jsonMapperBuilder()
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).build();

// First: without custom strategy, will fail:
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.junit.jupiter.api.Test;

import tools.jackson.databind.DeserializationFeature;
import tools.jackson.databind.MapperFeature;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.exc.UnrecognizedPropertyException;
Expand Down Expand Up @@ -35,6 +36,7 @@ public static class FixedPoint {
public void testFinalFieldIgnoral() throws Exception
{
ObjectMapper mapper = jsonMapperBuilder()
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.disable(MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS)
.build();
try {
Expand All @@ -49,14 +51,15 @@ public void testFinalFieldIgnoral() throws Exception
public void testDeserializationInference() throws Exception
{
final String JSON = "{\"x\":2}";
ObjectMapper mapper = new ObjectMapper();
ObjectMapper mapper = jsonMapperBuilder().enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).build();
// First: default case, inference enabled:
assertTrue(mapper.isEnabled(MapperFeature.INFER_PROPERTY_MUTATORS));
Point p = mapper.readValue(JSON, Point.class);
assertEquals(2, p.x);

// but without it, should fail:
mapper = jsonMapperBuilder()
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.disable(MapperFeature.INFER_PROPERTY_MUTATORS)
.build();
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,9 @@ public void testOverridingTransient() throws Exception
public void testTransientToPrune() throws Exception
{
try {
TransientToPrune result = MAPPER.readValue("{\"a\":3}",
TransientToPrune.class);
TransientToPrune result = MAPPER.readerFor(TransientToPrune.class)
.with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readValue("{\"a\":3}");
fail("Should not pass, got: "+result);
} catch (UnrecognizedPropertyException e) {
verifyException(e, "Unrecognized", "\"a\"");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

import tools.jackson.databind.DeserializationFeature;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.exc.InvalidDefinitionException;
import tools.jackson.databind.exc.UnrecognizedPropertyException;
Expand All @@ -17,7 +18,8 @@
// Tests for [databind#2761] (and [annotations#171]
public class TestMultipleTypeNames extends DatabindTestUtil
{
private final ObjectMapper MAPPER = newJsonMapper();
private final ObjectMapper MAPPER = jsonMapperBuilder()
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).build();

// common classes
static class MultiTypeName { }
Expand Down Expand Up @@ -156,7 +158,9 @@ public void testNameAndNames() throws Exception
// TC 2 : incorrect serialisation
json = "{\"data\": [{\"type\":\"a\", \"data\": {\"x\": 2.2}}, {\"type\":\"b\", \"data\": {\"y\": 5.3}}, {\"type\":\"c\", \"data\": {\"y\": 9.8}}]}";
try {
MAPPER.readValue(json, WrapperForNameAndNamesTest.class);
MAPPER.readerFor(WrapperForNameAndNamesTest.class)
.with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readValue(json);
fail("This serialisation should fail 'coz of x being float");
} catch (UnrecognizedPropertyException e) {
verifyException(e, "Unrecognized property \"data\"");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ public void testCaseInsensitiveDeserialization() throws Exception
final String JSON = "{\"Value1\" : {\"nAme\" : \"fruit\", \"vALUe\" : \"apple\"}, \"valUE2\" : {\"NAME\" : \"color\", \"value\" : \"red\"}}";

// first, verify default settings which do not accept improper case
ObjectMapper mapper = new ObjectMapper();
ObjectMapper mapper = jsonMapperBuilder()
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).build();
assertFalse(mapper.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES));
try {
mapper.readValue(JSON, Issue476Bean.class);
Expand Down Expand Up @@ -233,8 +234,9 @@ public void testCaseInsensitiveViaClassAnnotation() throws Exception

// and finally, more complicated; should be possible to force sensitivity:
try {
/*CaseSensitiveRoleContainer r =*/ MAPPER.readValue(CONTAINED,
CaseSensitiveRoleContainer.class);
/*CaseSensitiveRoleContainer r =*/ jsonMapperBuilder()
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).build()
.readValue(CONTAINED, CaseSensitiveRoleContainer.class);
fail("Should not pass");
} catch (UnrecognizedPropertyException e) {
verifyException(e, "Unrecognized ");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ public void serialize(Test3787Bean value, JsonGenerator gen, SerializerProvider
@Test
public void testWithoutModule()
{
ObjectMapper mapper = new ObjectMapper();
ObjectMapper mapper = jsonMapperBuilder().enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).build();
// first: serialization failure:
try {
mapper.writeValueAsString(new CustomBean("foo", 3));
Expand Down
12 changes: 9 additions & 3 deletions src/test/java/tools/jackson/databind/seq/ReadRecoveryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ static class Bean {
public void testRootBeans() throws Exception
{
final String JSON = a2q("{'a':3} {'x':5}");
MappingIterator<Bean> it = MAPPER.readerFor(Bean.class).readValues(JSON);
MappingIterator<Bean> it = MAPPER.readerFor(Bean.class)
.with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readValues(JSON);
// First one should be fine
assertTrue(it.hasNextValue());
Bean bean = it.nextValue();
Expand All @@ -58,7 +60,9 @@ public void testSimpleRootRecovery() throws Exception
{
final String JSON = a2q("{'a':3}{'a':27,'foo':[1,2],'b':{'x':3}} {'a':1,'b':2} ");

MappingIterator<Bean> it = MAPPER.readerFor(Bean.class).readValues(JSON);
MappingIterator<Bean> it = MAPPER.readerFor(Bean.class)
.with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readValues(JSON);
Bean bean = it.nextValue();

assertNotNull(bean);
Expand Down Expand Up @@ -88,7 +92,9 @@ public void testSimpleArrayRecovery() throws Exception
{
final String JSON = a2q("[{'a':3},{'a':27,'foo':[1,2],'b':{'x':3}} ,{'a':1,'b':2} ]");

MappingIterator<Bean> it = MAPPER.readerFor(Bean.class).readValues(JSON);
MappingIterator<Bean> it = MAPPER.readerFor(Bean.class)
.with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readValues(JSON);
Bean bean = it.nextValue();

assertNotNull(bean);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,9 @@ public void testUnknownExtraProp() throws Exception
{
String json = "{\"value\":[true,\"Foobar\",42,13, false]}";
try {
MAPPER.readValue(json, PojoAsArrayWrapper.class);
MAPPER.readerFor(PojoAsArrayWrapper.class)
.with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readValue(json);
fail("should not pass with extra element");
} catch (MismatchedInputException e) {
verifyException(e, "Unexpected JSON values");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,9 @@ public void testUnknownExtraProp() throws Exception
{
String json = "[1, 2, 3, 4]";
try {
MAPPER.readValue(json, ValueClassXY.class);
MAPPER.readerFor(ValueClassXY.class)
.with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readValue(json);
fail("should not pass with extra element");
} catch (MismatchedInputException e) {
verifyException(e, "Unexpected JSON values");
Expand Down