jackson-databind icon indicating copy to clipboard operation
jackson-databind copied to clipboard

Allow 'JsonAnySetter' to flow through JsonCreator.

Open bimargulies opened this issue 9 years ago • 10 comments

I could speed up some code if I could write:

@JsonCreator
public MyClass(@JsonProperty("a") String a, @JsonAnySetter Map<String, Object> leftovers) {}

bimargulies avatar Sep 29 '14 16:09 bimargulies

:+1: Is this something that you already considered putting in?

whiskeysierra avatar Jul 08 '15 07:07 whiskeysierra

Considered, yes, had time to try to tackle, no. Would definitely be nice thing to support.

cowtowncoder avatar Jul 08 '15 16:07 cowtowncoder

Any likelihood this will land in 3.x?

huhlig avatar Dec 03 '18 19:12 huhlig

Hi, I would also really like this (allows for immutable beans, and validation of data in constructor method).

davide-imbriaco avatar Jan 28 '19 08:01 davide-imbriaco

@huhlig It would be nice to get it there, but I can not predict whether it will or not. I do think it would be great to get it to work but there are so many things to work on...

I will keep this in mind as one of "more/most wanted" issues.

cowtowncoder avatar Feb 05 '19 06:02 cowtowncoder

I'd also like to see this feature. As a workaround for the immutability enthusiasts, here's an example of using JsonAnySetter in an immutable class (swap out the Map/HashMap for an immutable equivalent as you like). The trick is that the JsonAnySetter method can be made private.

@JsonAutoDetect(fieldVisibility = Visibility.ANY, creatorVisibility = Visibility.ANY, setterVisibility = Visibility.ANY)
public static final class WithMap {

    @JsonProperty("name")
    private String name;

    @JsonAnyGetter
    private Map<String, String> map;

    @JsonCreator
    public WithMap(@JsonProperty("name") String name) {
        this.name = name;
        this.map = new HashMap<>();
    }
    
    public WithMap(String name, Map<String, String> map) {
        this.name = name;
        this.map = map;
    }
    
    @JsonAnySetter
    private void put(String key, String value) {
        map.put(key, value);
    }
    
    public String name() {
        return name;
    }

    public Map<String, String> map() {
        return Collections.unmodifiableMap(map);
    }
}

davidmoten avatar May 12 '23 06:05 davidmoten

@JooHyukKim I think we could use a "failing" test case for this, as pre-cursor to #3439.

Note, too, that this is definitely one of Most-Wanted issues open.

cowtowncoder avatar Jan 27 '24 05:01 cowtowncoder

Added a failing test, as a minor help for anyone considering to try to implement.

Also, made @JsonAnySetter applicable to (constructor) parameters in jackson-annotations 2.17 (was not previously).

cowtowncoder avatar Jan 28 '24 02:01 cowtowncoder

Also, made @JsonAnySetter applicable to (constructor) parameters in jackson-annotations 2.17 (was not previously).

This is great. Thank you for taking care of things in advance.

JooHyukKim avatar Jan 28 '24 03:01 JooHyukKim

Np. Needed that already for reproduction :)

cowtowncoder avatar Jan 28 '24 21:01 cowtowncoder