5
@ResponseBody
@RequestMapping(value="/getUser")
public JSONObject getContent(@ReqeustBody User user) 

Up here is my Controller code.

@Data
public class User{
    private String username = "administrator";
    private String password = "123456";   
    private Integer age = 18;
}

Up here is my User class code.

{
    "username":"admin",
    "password":"000",
    "age":""
}

When I POST the JSON above, I get the age property to be null.

I want Jackson to deserialize the empty fields ("" or null) in JSON with default values.

Like this:

{
    "username":"admin",
    "password":"000",
    "age":18
}

What should I do?

hendrix
  • 3,364
  • 8
  • 31
  • 46
Michael
  • 115
  • 2
  • 2
  • 6

3 Answers3

5

You can define a custom getter property where setting your default value in case of null.

   public Integer getAge() {
        if (age == null) {
            return 18;
        } else {
            return this.age;
        }
    }

Note that you can't change the setAge method because it is not invoked in this case, infact there is no age field that will inform Jackson to call that method.


An alternative is to use a custom constructor and use the JsonSetter annotation with the value Nulls.SKIP

Value that indicates that an input null value should be skipped and no assignment is to be made; this usually means that the property will have its default value.

as follow:

 public class User {
    @JsonSetter(nulls = Nulls.SKIP)
    private Integer age;

    public User() {
        this.age = 18;
    }

    ...
}

The @JsonSetter is present in package com.fasterxml.jackson.annotation and can be imported as dependency in maven using

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>YOURVERSION</version>
</dependency>
Davide Lorenzo MARINO
  • 26,420
  • 4
  • 39
  • 56
  • I didn't find the `JsonSetter` annotation that I could write on the field, `com.fasterxml.jackson.annotation.JsonSetter` is only allowed on `class` and `method` . – Michael Jan 23 '19 at 11:39
  • @Michael it is present in the package com.fasterxml.jackson.annotation. Check the updated answer for details – Davide Lorenzo MARINO Jan 23 '19 at 11:44
  • Thank you Davide, my version is 2.8.0, it can't be written on a `field`. – Michael Jan 23 '19 at 11:50
  • @Michael correct, as the comment in the source code suggests `// ^^^ allowed on Fields, (constructor) parameters since 2.9` – kevinjom Jan 23 '19 at 14:57
1

Use the JsonSetter annotation with the value Nulls.SKIP

Value that indicates that an input null value should be skipped and the default assignment is to be made; this usually means that the property will have its default value.

As follows:

     public class User {
        @JsonSetter(nulls = Nulls.SKIP)
        private Integer Score = 1000;
        ...
    }

usually, if you don't use @JsonSetter(nulls = Nulls.SKIP) then the default value will be initialized if there is no value coming in JSON, but if someone explicitly put a null then it can lead to problem. Using @JsonSetter(nulls = Nulls.SKIP) will tell the Json de-searilizer to avoid null initialization.


Andrés Alcarraz
  • 1,570
  • 1
  • 12
  • 21
Sunil Garg
  • 484
  • 5
  • 9
0

One approach is to make you setAge to handle the null case, for example:

 void setAge(Integer age){
   if(age!=null) this.age = age;
 }

Or you can have a look at @JsonSetter(nulls=Nulls.SKIP), I just looked at the source code, I haven't tried :(

Hope that helps.

kevinjom
  • 343
  • 2
  • 15
  • The setAge doesn't work because there is no age field. If there was an age field with a null value it could work, but not in absence of the field age. – Davide Lorenzo MARINO Jan 23 '19 at 11:27
  • @DavideLorenzoMARINO Ah I just saw the `@Data` annotation from lombok ( I assume), so there is no setter there. This is actually a bit tricky, but its java's nature, even there is no setter, the client code can still change the object's field value by using reflection which I assume thats how jackson does it. I think your answer makes sense in the context that you still wanna use `@Data`. – kevinjom Jan 23 '19 at 15:00