Spring supports JDK 1.8's java.util.Optional as a method parameter type as an alternative to using 'required' element of some of the annotations. Let's explore this with an example.
Without java.util.Optional
In this example, we are going to use @RequestParam:
@Controller
public class EmployeeController {
@RequestMapping("/employee")
@ResponseBody
public String getEmployeeByDept(@RequestParam("dept") String deptName) {
return "test response for dept: " + deptName;
}
.............
}
To try examples, run embedded Jetty (configured in pom.xml of example project below):
mvn jetty:run
If we make the request without 'dept' query param, 400 Bad Request error will be returned:
One way to avoid the above error (given that dept is really an optional param from a business logic perspective) is to use 'required=false' of @RequestParam.
@Controller
public class EmployeeController {
.............
@RequestMapping("/employee2")
@ResponseBody
public String getEmployeeByDept2(@RequestParam(value = "dept", required = false)
String deptName) {
return "test response for dept: " + deptName;
}
.............
}
$ curl -s http://localhost:8080/employee2 test response for dept: null
Using java.util.Optional
As Spring always tries to align the framework with standard JSE/JEE API, java.util.Optional has been supported since 4.3 as an alternative to using 'required' element:
@Controller
public class EmployeeController {
.............
@RequestMapping("/employee3")
@ResponseBody
public String getEmployeeByDept3(@RequestParam("dept") Optional<String> deptName) {
return "test response for dept: " + deptName.orElse("default dept");
}
}
$ curl -s http://localhost:8080/employee3 test response for dept: default dept
Other supported annotations
In addition to @RequestParam, @RequestHeader and @MatrixVariable can be used with java.util.Optional.
Example ProjectDependencies and Technologies Used: - spring-webmvc 7.0.6 (Spring Web MVC)
Version Compatibility: 4.3.0.RELEASE - 7.0.6 Version compatibilities of spring-webmvc with this example: Versions in green have been tested.
- jakarta.servlet-api 6.1.0 (Jakarta Servlet API documentation)
- spring-test 7.0.6 (Spring TestContext Framework)
- junit-jupiter-engine 6.0.3 (Module "junit-jupiter-engine" of JUnit)
- JDK 25
- Maven 3.9.11
|