Why is this an issue?

Spring provides two options to mark a REST parameter as optional:

  1. Use required = false in the @PathVariable or @RequestParam annotation of the respective method parameter or
  2. Use type java.util.Optional<T> for the method parameter

When using 1., the absence of the parameter, when the REST function is called, is encoded by null, which can only be used for object types. If required = false is used for a parameter with a primitive and the REST function is called without the parameter, a runtime exception occurs because the Spring data mapper cannot map the null value to the parameter.

How to fix it

Replace primitive types, such as boolean, char, int, with the corresponding wrapper type, such as Boolean, Character, Integer.

Alternatively, you might choose to remove required = false from the annotation and use an Optional<T> type for the parameter, such as Optional<Boolean> or Optional<String>, which automatically makes the REST parameter optional. This is the preferred approach because it enforces the proper handling of null in the method implementation.

Code examples

Noncompliant code example

@RequestMapping(value = {"/article", "/article/{id}"})
public Article getArticle(@PathVariable(required = false) int articleId) { // Noncompliant, null cannot be mapped to int
   //...
}

Compliant solution

@RequestMapping(value = {"/article", "/article/{id}"})
public Article getArticle(@PathVariable(required = false) Integer articleId) { // Compliant
   //...
}

Noncompliant code example

@RequestMapping(value = {"/article", "/article/{id}"})
public Article getArticle(@PathVariable(required = false) int articleId) { // Noncompliant, null cannot be mapped to int
   //...
}

Compliant solution

@RequestMapping(value = {"/article", "/article/{id}"})
public Article getArticle(@PathVariable Optional<Integer> articleId) { // Compliant and preferred approach
   //...
}

Resources

Documentation

Articles & blog posts