JSON Post request for boolean field sends false by default
Asked Answered
B

4

58

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;
}   
}
Bois answered 20/2, 2014 at 16:34 Comment(14)
Can we see your full class, getters/setters as well?Breastbeating
need more informations about the model and DAOIla
Are your firstName and lastName variables being set correctly?Krahmer
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.Wolf
Can you please try with the Boolean wrapper to see if that works?Delinquent
Ok, I will try that and see.. I have added more details in my post. ThanksBois
What do you see when you simply read it as a Map and dump the Map?Mcmanus
(Most likely you need to change your property to Boolean.)Mcmanus
@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.Bois
And what the Map dumps looks correct?Mcmanus
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.)Mcmanus
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.Bois
This is why I was asking about the dump.Mcmanus
@Bois 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.Fanjet
B
151

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;
Breastbeating answered 20/2, 2014 at 20:41 Comment(5)
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 ?Bois
@Bois You want it to be true by default? Just initialize the field in your class in its declaration private boolean isActive = true;Breastbeating
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.Bois
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 !!Bois
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.Gibraltar
S
19

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

Scone answered 8/4, 2019 at 7:10 Comment(1)
so clear and pretty solution! Thanks, body!Unmanly
C
2

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.

Cornaceous answered 9/1, 2020 at 14:15 Comment(0)
S
0

You should use Boolean instead of boolean.

Sulfapyridine answered 27/1, 2023 at 21:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.