69 lines
2.5 KiB
Plaintext
69 lines
2.5 KiB
Plaintext
== 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
|
|
|
|
[source,java,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
@RequestMapping(value = {"/article", "/article/{id}"})
|
|
public Article getArticle(@PathVariable(required = false) int articleId) { // Noncompliant, null cannot be mapped to int
|
|
//...
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,java,diff-id=1,diff-type=compliant]
|
|
----
|
|
@RequestMapping(value = {"/article", "/article/{id}"})
|
|
public Article getArticle(@PathVariable(required = false) Integer articleId) { // Compliant
|
|
//...
|
|
}
|
|
----
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,java,diff-id=2,diff-type=noncompliant]
|
|
----
|
|
@RequestMapping(value = {"/article", "/article/{id}"})
|
|
public Article getArticle(@PathVariable(required = false) int articleId) { // Noncompliant, null cannot be mapped to int
|
|
//...
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,java,diff-id=2,diff-type=compliant]
|
|
----
|
|
@RequestMapping(value = {"/article", "/article/{id}"})
|
|
public Article getArticle(@PathVariable Optional<Integer> articleId) { // Compliant and preferred approach
|
|
//...
|
|
}
|
|
----
|
|
|
|
== Resources
|
|
|
|
=== Documentation
|
|
|
|
- https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/PathVariable.html[Spring Framework API - Annotation Interface PathVariable]
|
|
|
|
=== Articles & blog posts
|
|
|
|
- https://www.baeldung.com/spring-optional-path-variables[Baeldung - Spring Optional Path Variables]
|