Optional Path Variable
In this tutorial I will show you how to work with Spring framework’s optional path variable (PathVariable
) in REST services. Here I will use Java 8’s java.util.Optional
or using attribute required=false
and at least Spring Boot 2.1.4 to support optional PathVariable
. The optional variable can be found in the URI resource path of the URL.
Prerequisites
Java 8/19, Spring Boot 2.1.4/3.1.0, Gradle 4.10.2, Maven 3.8.5
Project Setup
Create a gradle based or maven based project in your favorite IDE or tool.
If you are creating maven based project then you can use the following pom.xml file for your project:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.roytuts</groupId>
<artifactId>spring-rest-optional-path-variable</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>19</maven.compiler.source>
<maven.compiler.target>19</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.0</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Here in the below build.gradle file I have added the required dependencies such as Java, Spring Boot.
buildscript {
ext {
springBootVersion = '2.1.4.RELEASE'
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")
}
Spring REST Controller
Create below REST Controller class that will handle end-user’s request and response.
In the below method getHi()
I have passed an argument with attribute required=false
to make the parameter optional.
In the below method getHello()
I have passed an argument with Java 8’s new feature java.util.Optional
to make the parameter optional.
Notice there are two endpoints for GetMapping
because when you do not pass any value for PathVaribale
‘s name then simply putting URI /hi or /hello in http request will not work and you will get 404 – Resource Not Found in the browser.
So in order to let http request know that when you do not pass any value for PathVariable name then map URI to /hi instead of /hi/{name} and /hello instead of /hello/{name}.
Notice how I have passed spring optional path variable in the REST method for data type String.
@RestController
public class SpringRestController {
@GetMapping(value = { "/hi/{name}", "/hi" })
public ResponseEntity<String> getHi(@PathVariable(required = false) String name) {
return new ResponseEntity<String>(
"Hi " + (name == null || name.length() == 0 ? "Anonymous" : name) + ", Good Morning!", HttpStatus.OK);
}
@GetMapping(value = { "/hello/{name}", "/hello" })
public ResponseEntity<String> getHello(@PathVariable Optional<String> name) {
return new ResponseEntity<String>("Hello " + (name.isPresent() ? name.get() : "Anonymous") + ", Good Morning!",
HttpStatus.OK);
}
}
Spring Boot Main Class
As you know Spring Boot application with @SpringBootApplication
annotation and the main method takes care of deployment of the application into default embedded Tomcat server.
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
Testing Optional Path Variable
Check outputs in browsers for below URLs for the example spring optional path variable.
When you do not pass name into the path variable:
When you pass the name into the path variable: