Required attribute of `@JsonProperty` is ignored when deserializing from XML
See original GitHub issueWhen JSON is parsed, there is a check on properties that are annotated with JsonProperty with attibute required to true. If the required property is missing, a MismatchedInputException with message “Missing required creator property” is thrown.
When XML is parsed, there is no check on required properties/element. If the required property/element is missing, there is no exception. Adding DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES doesn’t make any difference.
There is constructor is annotated with JsonCreator and with the required property annotated with JsonProperty.
It worked when jackson-dataformat-xml version 2.11.4 was used, it doesn’t work since version 2.12.0
Do I need to use another annotation for a required XML element?
Example class:
@JsonRootName(value = "bar")
public class Bar
{
@JsonProperty(value = "foo", required = true)
private int foo;
public Bar()
{}
@JsonCreator
public Bar(@JsonProperty(value = "foo", required = true) final int foo)
{
this.foo = foo;
}
public int getFoo()
{
return this.foo;
}
@Override
public int hashCode()
{
return Objects.hash(this.foo);
}
@Override
public boolean equals(final Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof Bar))
{
return false;
}
final Bar other = (Bar) obj;
return this.foo == other.foo;
}
@Override
public String toString()
{
return "Bar: " + Objects.toString(this.foo);
}
}
Example of unit test on JSON, this unit test throws an exception as expected, because property foo is missing.
@Test(expected = JsonProcessingException.class)
public void deserializeJson() throws Exception
{
final ObjectMapper jsonMapper = new ObjectMapper();
final Bar expected = new Bar(123);
final Bar actual = jsonMapper.readValue("{}", Bar.class); // missing property foo in JSON string
}
Example of unit test on XML, this unit test does not throw an exception
@Test(expected = JsonProcessingException.class)
public void deserializeXml() throws Exception
{
final XmlMapper xmlMapper = new XmlMapper();
xmlMapper.configure(DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES, true);
final Bar expected = new Bar(123);
final Bar actual = xmlMapper.readValue("<bar></bar>", Bar.class); // missing element foo in XML string
Assert.fail("Expected com.fasterxml.jackson.databind.exc.MismatchedInputException: Missing required creator property 'foo' (index 0)");
}
Issue Analytics
- State:
- Created a year ago
- Comments:7 (6 by maintainers)
The parsing of an empty XML element(1 tag, no start and end tag) is correct, if the feature FromXmlParser.Feature.EMPTY_ELEMENT_AS_NULL is enabled. The result is a NULL.
The parsing of XML element with value empty string (start and end tag with empty string between), with feature FromXmlParser.Feature.EMPTY_ELEMENT_AS_NULL enabled, fails. The result is an object (Bar: 0) created by the default constructor, the required property foo is zero (= default value). There is no MismatchedInputException thrown for the missing foo property.
The parsing of XML element with value empty string (start and end tag with empty string between) is correct, if the coercion configuration is defined for type Bar in order to process an empty string input as null.
Ok, I was able to figure out a much simpler approach, essentially reverting some of the changes done in 2.12 for coercion root-element textual content. But without breaking what that change was initially added to fix.
So should work as expected in 2.14.0; hoping to release 2.14.0-rc1 within a week or so.