Closed fabiolados closed 8 years ago
Ok, I will try to reproduce the issue. Thank you for the report!
I can not reproduce this the way understand problem from the description unfortunately. So I think I need a unit test showing how problem occurs.
Thanks for the quick reply. Here's my unit test (sorry I don't have a public repo I can add this to)
Incoming json (deserialization works fine)
{ "SomeResponse" : { "ID" : "12345", "Roles": { "Role": [{ "Name": "User", "ID": "333" }] } } }
Incoming json (deserialization fails)
{ "SomeResponse" : { "ID" : "12345", "Roles": { "Role": { "Name": "User", "ID": "333" } } } }
// --- Unit test
// private static final String PATH = "/com/soap-response-as-json.json"; // points to one of the json files from above
@Test
public void testDeserializeResponse() throws IOException {
String json = IOUtils.toString(ObjectMapperFactoryTest.class.getResourceAsStream(PATH));
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MyModel response = objectMapper.readValue(json, MyModel.class);
Assert.assertEquals("12345", response.getId());
}
// --- Models
@JsonRootName(value = "SomeResponse")
public class MyModel {
@JsonProperty(value = "ID")
@NotNull
private String id;
@JsonProperty(value = "Roles")
@NotNull
private Roles roles;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Roles getRoles() {
return roles;
}
public void setRoles(Roles roles) {
this.roles = roles;
}
@Override
public String toString() {
return ReflectionToStringBuilder.toString(this);
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class Roles {
@NotNull
@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
@JsonProperty(value = "Role")
private List<Role> roles;
// @JsonGetter(value = "Role")
public List<Role> getRoles() {
return roles;
}
// @JsonSetter(value = "Role")
public void setRoles(List<Role> roles) {
this.roles = roles;
}
@Override
public String toString() {
return ReflectionToStringBuilder.toString(this);
}
}
public class Role {
@JsonProperty(value = "ID")
@NotNull
private String identifier;
@JsonProperty(value = "Name")
@NotNull
private String name;
public String getIdentifier() {
return identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return ReflectionToStringBuilder.toString(this);
}
}
Note: this should really be filed against jackson-databind
, as annotations package only includes anotation type declarations, but none of the handling.
I can reproduce this now. It looks like problem is not directly due to @JsonProperty
, but I think test passes without it due to other reasons (basically, without it the setter/getter/field are not linked, and due to mismatch value is basically ignored).
But there is definitely a problem of some kind.
Hmmh. It may be as simple as feature not actually being full implemented, unlike its writer-side counterpart.
Adding
@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
to a class or field works fine, however, if the field also has@JsonProperty(value = "Something")
the jsonformat feature no longer works.