57

Hi I am sending a JSON Post request using the FireFox RestClient.

My JSON Request is as below:

 { "firstName": "Test", "lastName": "1", "isActive": 1 }

My POJO has isActive field as below

  private boolean isActive;

My Controller is define as below

@RequestMapping(method = {RequestMethod.POST, 
                                 RequestMethod.PUT}, value = "/save")
public ResponseEntity<RestResponse> save(
      @RequestBody POJOUserDetails userDetails, WebRequest request){

In my POJO, when I check the value of isActive, it is false no matter what I send. I tried below value in my JSON request

"isActive": 1
"isActive": true 
"isActive": "true"
"isActive": ""
"isActive": null
"isActive": false

All of above sends false in my controller. Please help. Thanks

Adding POJO details

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonSerialize(include=Inclusion.NON_EMPTY)
public class POJOUserDetails {
private String firstName;
private String lastName;
private boolean isActive;

public boolean isActive() {
    return isActive;
}
public void setActive(boolean isActive) {
    this.isActive = isActive;       
}

    public String getFirstName() {
    return firstName;
}
public void setFirstName(String firstName) {
    this.firstName = firstName;
}
public String getLastName() {
    return lastName;
}
public void setLastName(String lastName) {
    this.lastName = lastName;
}   
}
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
NewQueries
  • 4,841
  • 11
  • 33
  • 39
  • Can we see your full class, getters/setters as well? – Sotirios Delimanolis Feb 20 '14 at 16:35
  • need more informations about the model and DAO – Filipe Feb 20 '14 at 16:38
  • Are your firstName and lastName variables being set correctly? – Jake Haller-Roby Feb 20 '14 at 16:50
  • I always get messi with boolean var over a spring rest, My solution is to send it as a string "t" or "f" and check it in the client side. – Ben Diamant Feb 20 '14 at 16:58
  • Can you please try with the `Boolean` wrapper to see if that works? – Raul Rene Feb 20 '14 at 17:28
  • Ok, I will try that and see.. I have added more details in my post. Thanks – NewQueries Feb 20 '14 at 17:33
  • What do you see when you simply read it as a Map and dump the Map? – Hot Licks Feb 20 '14 at 17:46
  • (Most likely you need to change your property to Boolean.) – Hot Licks Feb 20 '14 at 17:47
  • @HotLicks It worked when I read it as a MAP. Changing to Boolean did not help though. Some of the other classes are reading as POJOObjects but it seems to work fine for those with no issues. – NewQueries Feb 20 '14 at 19:15
  • And what the Map dumps looks correct? – Hot Licks Feb 20 '14 at 19:22
  • 2
    It's vaguely possible it's being confused by the name. Maybe it would like setIsActive, eg. (It seems like each of these APIs has a slightly different naming convention.) – Hot Licks Feb 20 '14 at 19:25
  • Noticed something weird. I added a contructor in which i initialized this.isActive to true. This time i passed false from the JSON. And when I read the Object, it shows the value as true. I think that isActive value is just not sent across. – NewQueries Feb 20 '14 at 19:41
  • This is why I was asking about the dump. – Hot Licks Feb 20 '14 at 21:38
  • 1
    @NewQueries I know its an old question and you already have a solution for it. This is for other readers who are facing similar issue. You could set the isActive field as required field in your json as that will always mandate a true/false value from the caller directly so you won't get false if the field is missing in the request as in your case. – Harish Nov 16 '18 at 16:50

4 Answers4

146

Remember that Jackson, by default, determines the property name from either the getter or setter (the first that matches).

To deserialize an object of type POJOUserDetails, Jackson will look for three properties

public void setFirstName(String firstName) {

public void setLastName(String lastName) {

public void setActive(boolean isActive) {

in the JSON. These are basically firstName, lastName, active.

You get the following JSON

{ "firstName": "Test", "lastName": "1", "isActive": 1 }

So firstName and lastName are mapped, but you don't have a property named isActive.

Jackson depends on Java Bean naming conventions with their accessors (getters) and mutators (setters). For a field like

private boolean isActive;

the appropriate setter/getter names are

public boolean getIsActive() {
    return isActive;
}

public void setIsActive(boolean isActive) {
    this.isActive = isActive;
}

So you have two possible solutions. Change your getter/setter as shown above or annotate your field with @JsonProperty so that Jackson uses the field name to determine the property name

@JsonProperty
private boolean isActive;
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • Both the solutions worked. (@JsonProperty and changing get and set method names). It is recognizing true and false correctly now. But for null and "" (blank), it send default value false. Can this be changed ? – NewQueries Feb 20 '14 at 21:31
  • 1
    @NewQueries You want it to be `true` by default? Just initialize the field in your class in its declaration `private boolean isActive = true;` – Sotirios Delimanolis Feb 20 '14 at 21:33
  • 1
    I am doing that in contructor. public POJOUserDetails(){ this.isActive = true; } I do not want it to be true necessarily. Was just wondering if I can read exact value that was passed whether blank or null or boolean. – NewQueries Feb 20 '14 at 21:35
  • Looks like it takes the default value from contructor/initialization only if that field is not passed at all. It changes null / blank to false. That's fine. Thanks a Lot Everyone for your help !! – NewQueries Feb 20 '14 at 21:52
  • If you add a @JsonProperty, it works, but the response json will have two properties. One "isActive" and other is "Active". This behavior having boolean property with lombok.@Getter and lombok.@Setter. Best solution is have the property in the postman/RESTClient as "active". Don't change anything in the code. – Yoga Gowda Oct 24 '19 at 00:24
12

When you are using libraries like lombok to generate getters and setters, don't add 'is' with the field name if the field type is boolean. Because Jackson uses default naming bean convention of java and adds 'is' while setting fields. so adding 'is' makes the field mapping wrong

Chinmay Biswal
  • 303
  • 5
  • 9
1

In the other hand, we can use Boolean wrapper to handle it, this way the IDE generates the getter/setter by adding the prefix get/set to the whole Boolean field's name.

Omar
  • 1,430
  • 1
  • 14
  • 31
0

You should use Boolean instead of boolean.

Alptekin T.
  • 91
  • 1
  • 3