FasterXML / jackson-annotations

Core annotations (annotations that only depend on jackson-core) for Jackson data processor
https://github.com/FasterXML/jackson
Apache License 2.0
1.03k stars 330 forks source link

@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY) does not work on fields having @JsonProperty(value = "Something") #67

Closed fabiolados closed 8 years ago

fabiolados commented 9 years ago

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.

cowtowncoder commented 9 years ago

Ok, I will try to reproduce the issue. Thank you for the report!

cowtowncoder commented 9 years ago

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.

fabiolados commented 9 years ago

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);
    }
}
cowtowncoder commented 8 years ago

Note: this should really be filed against jackson-databind, as annotations package only includes anotation type declarations, but none of the handling.

cowtowncoder commented 8 years ago

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.

cowtowncoder commented 8 years ago

Hmmh. It may be as simple as feature not actually being full implemented, unlike its writer-side counterpart.

cowtowncoder commented 8 years ago

Moved to: https://github.com/FasterXML/jackson-databind/issues/1043