Search code examples
spring-bootnullintegerwrapperpath-variables

Wrapper type Path variable won't accept null value - Spring Boot


This is our Controller

@GetMapping(path = "/getUsersForHierarchy/{entity}/{hierId}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<UserInfo>> getUsersForHierarchy(@PathVariable(name = "entity", required = true) int entity,
            @PathVariable(name = "hierId", required = true) Integer hierId) {

    ..................

    ..................

}

We are expecting two Path variables, one is of int type (entity) and the other is Integer type (hierId). hierId can be null or any numeric value and thats why its kept as Wrapper. But its gives error while firing the request like this

http://localhost:5010/v1/accountholder/userinfo/getUsersForHierarchy/5/null

Now a Wrapper is meant to accept null values, but we are getting error like this

Failed to convert value of type 'java.lang.String' to required type 'java.lang.Integer'; nested exception is java.lang.NumberFormatException: For input string: "null"

If we change Integer to String the call is getting inside the controller, but for further proceedings we need to use Integer.

We looked into this Spring MVC @Path variable with null value, and tried invoking the API with change in URL like this

http://localhost:5010/v1/accountholder/userinfo/getUsersForHierarchy/5/blaaa/null, but the error is still the same.

What should be done?


Solution

  • If you want it to be nullable you can achieve it with the following. First of all, if it's nullable the required property should be false. Also, considering required = true is the default, there's no need to specify it and if the name of the path variable matches the name of the corresponding variable you don't have to specify the name either.

    @GetMapping(value = {
            "/getUsersForHierarchy/{entity}/", 
            "/getUsersForHierarchy/{entity}/{hierId}"
        },
        produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<UserInfo>> getUsersForHierarchy(
        @PathVariable int entity,
        @PathVariable(required = false) Integer hierId) {
    
    }
    

    Considering I don't like to deliberately allow a null value into the application, another nice to have could be having the hierId required with type Optional, so the following will give you a Optional.empty when just /getUsersForHierarchy/123/ is invoked and hierId is null. Otherwise it will populate the optional when hierId is provided invoking /getUsersForHierarchy/123/321:

    @GetMapping(value = {
            "/getUsersForHierarchy/{entity}/", 
            "/getUsersForHierarchy/{entity}/{hierId}"
        },
        produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<UserInfo>> getUsersForHierarchy(
        @PathVariable int entity,
        @PathVariable Optional<Integer> hierId) {
    
    }