0

We got this REST endpoint in which one of the field is mapped to a Boolean (The wrapper class) instance. We are using a Boolean instead of a boolean because design decision, so this is non-negotiable.

This Boolean value is mandatory and it must be specified by the sender ("whateverValue":"" should return a 400 error), but when arriving to the endpoint, the value is automatically converted to a correct false value.

So, the question is: Can this be done? Are we not understanding the contract of using a "Boolean" object instead of the primitive?

EDIT: Just to clarify, we are already validating "whateverValue":null, and the value can be either true or false, so, as far as I know, neither @NotNull or @AssertTrue/False can be used here.

Neuromante
  • 531
  • 2
  • 12
  • 29
  • can you provide the controller method signature and perhaps the validation logic? – SoftChili Jan 13 '20 at 15:16
  • @SiSi There's not much to provide, is just a standard @ RequestBody annotated class which has a "field":"value" pair, but it seems Spring auto converts "field":"" to "field:"false". I was expecting being able to find a way with the custom validator to do the validation, but when it arrrives to the validator class already has a "false" value. – Neuromante Jan 13 '20 at 15:34
  • I remember from my projects, where we determined the input type right at the signature like "Boolean" in your case for the desired parameter. Did you try something like that? – SoftChili Jan 13 '20 at 15:39
  • Afaik, we can't, because the type on the method declaration (the function that is mapped to /whatever endpoint) is a pojo, with the element declaration (Which seems Spring maps to a default value if the value itself is empty). – Neuromante Jan 13 '20 at 16:09
  • Maybe you can set Json to ignore nulls https://www.baeldung.com/jackson-ignore-null-fields and then build a constructor with @JsonCreator without the Boolean field that set it to null – Telcontar Jan 14 '20 at 09:09
  • But we are already validating nulls (i.e. "booleanField":null) through bean validation, what I'm trying to validate is "field":"" not mapping automatically to "field":"false." – Neuromante Jan 14 '20 at 11:01
  • Which Spring version do you use? I coded your scenario, I have DTO class that has a Boolean property,i sent a "field":"" for to the endpoint, the server received null value. (so it was correct!)) – Mehrdad HosseinNejad Yami Jan 14 '20 at 11:47
  • Huh, the example you listed as an answer its more or less what I have. We are using spring boot 2.1.4.RELEASE, I've talked with a coworker and it seems the issue is with the Spring version. I'm looking into it. – Neuromante Jan 14 '20 at 14:25

2 Answers2

0

If you want to validate the Object Type Boolean you should use @NotNull

Here is a question where this has been asked before. I use @NotNull if a boolean is mendatory to be set ans @AssertTrue/false to verify the incoming value has a specific state. Hope this helps

FishingIsLife
  • 1,972
  • 3
  • 28
  • 51
  • We are already using it, but it only works when the request is "value":null. The case I'm having trouble with is when the request is "value":"", which auto-converts to "value":"false." Also, it can be either true or false, so we can't use @AssertTrve/False – Neuromante Jan 14 '20 at 11:25
0

I coded your scenario as follows and it was ok!

Please correct me if my understanding (from your scenario) is incorrect.

Create DTO

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class TestDto {

@NotNull
Boolean testValue;

//getter and setter

}

Create Endpoint

@RestController
public class testController {

@RequestMapping(value = "/test", method = RequestMethod.POST)
public void accountTrades(@RequestBody @Valid TestDto testDto) {

    System.out.println(testDto.getTestValue());

  }

}

Using Postman, when I send testValue:"", it throws a notnull exception, that means the server has received null, and there is no null to false conversion. (It worked correctly!)

Server response is as follows

enter image description here