Getting around Json jackson and lombok constructor

2019-08-20 21:41发布

问题:

Using json to save and load data requires a constructor for json to load the object, and I'm having trouble getting lombok annotations to work with this. What should I do?

This is what my class looked like before and after attempting to use an annotation to construct my item:

@Data
public class Item { //before

    private int id;

    private int amount;

    public Item(@JsonProperty("id") int id, @JsonProperty("amount") int amount) {
        this.id = id;
        this.amount = amount;
    }

}
@Data
@AllArgsConstructor 
@NoArgsConstructor //I don't want this here as it could cause complications in other places.  But json requires I have this...
public class Item { //after

    private int id;

    private int amount;

}

I don't want to use the NoArgsConstructor annotation by lombok as I don't want a no args constructor for this class. I realise that I could do this:

private Item() {
}

But was hoping there is a better way...

回答1:

try adding this to your lombok config file:

lombok.anyConstructor.addConstructorProperties=true
config.stopBubbling = true


回答2:

Since lombok 1.18.4, you can configure what annotations are copied to the constructor parameters. Insert this into your lombok.config:

lombok.copyableAnnotations += com.fasterxml.jackson.annotation.JsonProperty

Then just add @JsonProperty to your fields:

@Data
@AllArgsConstructor 
public class Item {
    @JsonProperty("id")
    private int id;

    @JsonProperty("amount")
    private int amount;
}

Although the annotation parameters may seem unnecessary, they are in fact required, because at runtime the names of the constructor parameters are not available.



回答3:

So what you're saying is that Jackson requires no-args constructor for deserialization, and you don't want to add no-args constructors to your classes because that doesn't play well with your model.

Lombok is completely irrelevant here - it makes zero difference whether no-args constructor would be written manually or generated by Lombok, it'll still be just a no-args constructor.

Your real question is - can I make Jackson work without no-argument constructors on target classes. There are multiple answers to that already, you have almost done it. Here's what has to be done:

  1. Add @JsonCreator annotation to your constructor
  2. Add @JsonProperty("propName") to constructor parameters

You did the #2 but not #1. Add that and this should fix your problem.