Enterprise Java

Spring PathVariable and RequestParam

Spring PathVariable and RequestParam annotations offer distinct ways to extract data from URLs and query parameters for dynamic web applications.

1. @PathVariable annotation in Spring

The @PathVariable annotation in Spring is used to capture values from the URI (Uniform Resource Identifier) path. It allows you to extract dynamic parts of the URL and use them in your controller methods. This is especially useful when you want to handle different resource identifiers flexibly. The syntax of using @PathVariable is:

Syntax

@GetMapping("/users/{userId}")
public ResponseEntity<String> getUserById(@PathVariable Long userId) {
    // Implementation goes here
}

1.1 Benefits

  • Dynamic URL Handling: With @PathVariable, you can create flexible and dynamic mappings that handle varying resource identifiers.
  • Cleaner Code: It helps to keep your code organized by extracting URL segments into the method parameters.
  • Readable Mappings: Using @PathVariable makes your URL mappings more readable and self-explanatory.

2. @RequestParam annotation in Spring

The @RequestParam annotation in Spring is used to extract query parameters or form data from the HTTP request. It allows you to access data sent as part of the request URL or submitted through forms. This annotation makes it easy to retrieve user inputs and use them in your controller methods. The syntax of using @RequestParam is:

Syntax

@GetMapping("/search")
public ResponseEntity<String> searchUser(@RequestParam String query) {
    // Implementation goes here
}

2.1 Benefits

  • Request Data Extraction: @RequestParam simplifies the process of extracting query parameters and form data from the request.
  • Parameterized Queries: It enables you to create controller methods that accept dynamic input parameters.
  • Usability: Using @RequestParam allows you to create user-friendly URLs and forms that can be easily processed.

3. Difference between @RequestParam and @PathVariable

Both @RequestParam and @PathVariable are used in Spring to extract data from HTTP requests, but they serve different purposes and target different parts of the request. Here’s a comparison of the two annotations:

Aspect@RequestParam@PathVariable
UsageUsed to extract query parameters or form data from the request.Used to capture values from the URI path.
LocationExtracts data from the request URL’s query parameters or form data.Extracts data from the URI path segments.
Typical Use CaseFor scenarios where you need to retrieve inputs from query parameters or form fields.For scenarios where you want to extract dynamic values from the path, such as resource identifiers.

Both annotations play distinct roles in handling different types of data extraction.

4. Spring @PathVariable and @RequestParam

Below is an example of a Spring Boot application that demonstrates how to use @PathVariable and @RequestParam annotations.

4.1 Create a Spring Boot Project

You can use the Spring Initializr to generate a basic Spring Boot project with the necessary dependencies. Here’s a list of Maven dependencies you should add to your Spring Boot project (pom.xml) for this tutorial.

pom.xml

<dependencies>
    <!-- Spring Boot Starter Web for building web applications -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Spring Boot Starter Test for testing support -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

Please note that the provided Maven dependencies include spring-boot-starter-web for web application development and spring-boot-starter-test for testing. These dependencies will ensure that you have the necessary tools and libraries to build the example Spring Boot application using RestTemplate for consuming RESTful APIs.

4.2 Create a Controller

The given class is a Spring MVC controller named UserController. It is responsible for handling HTTP requests related to user information and search functionality. The class is annotated with @RestController, indicating that it’s designed to handle RESTful web services. Let’s break down the key components and functionality of the UserController class:

  • Class Annotations: @RestController: This annotation signifies that the class is a controller that handles requests and produces responses suitable for RESTful web services.
  • RequestMapping: @RequestMapping("/users"): This annotation at the class level establishes the base URL path for all endpoints defined within this controller. All the endpoints in this class will be under the /users path.
  • getUserById Method:
    • @GetMapping("/{userId}"): This annotation maps the getUserById method to a GET request with a path variable named userId. The path variable corresponds to the userId provided in the URL.
    • public ResponseEntity<String> getUserById(@PathVariable Long userId): This method takes the userId from the URL path and uses it to fetch user information. It responds with a message indicating the user’s information.
  • searchUser Method:
    • @GetMapping("/search"): This annotation maps the searchUser method to a GET request under the /users/search URL path. This method handles user search functionality.
    • public ResponseEntity<String> searchUser(@RequestParam(required = false, defaultValue = "default") String query): This method accepts a query parameter named query. The @RequestParam annotation indicates that this parameter is extracted from the query string. It’s marked as optional and has a default value of “default”.
    • Inside the method, the provided query parameter is checked. If the query is “default”, a message indicating a default search is performed is returned. Otherwise, a message indicating a search for the provided query is returned.

UserController.java

package com.example.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/users")
public class UserController {

    // curl -X GET "http://localhost:9300/users/<user_id>"
    @GetMapping("/{userId}")
    public ResponseEntity<String> getUserById(@PathVariable Long userId) {
        // Fetch user information using userId
        return ResponseEntity.ok("User information for ID: " + userId);
    }

    // curl -X GET "http://localhost:9300/users/search?query=<query_string>"
    // curl -X GET "http://localhost:9300/users/search"
    @GetMapping("/search")
    public ResponseEntity<String> searchUser(@RequestParam(required = false, defaultValue = "default") String query) {
        // Check if a specific query was provided
        if ("default".equals(query)) {
            // If no specific query is provided, perform default search
            return ResponseEntity.ok("No specific query provided. Performing default search.");
        } else {
            // Perform search operation using the provided query
            return ResponseEntity.ok("Searching for: " + query);
        }
    }
}

4.3 Update Application properties

The provided application.properties file contains configuration properties for a Spring Boot application. These properties control various aspects of the application’s behavior when it’s running.

  • spring.application.name=spring-pathvariable-vs-requestparam-annotations: This property sets the name of the Spring Boot application. It provides a unique identifier for the application within the Spring ecosystem. In this case, the application is named spring-pathvariable-vs-requestparam-annotations.
  • server.port=9300: This property configures the port on which the embedded web server (such as Tomcat) will listen for incoming HTTP requests. In this case, the application’s server will run on port 9300.

application.properties

spring.application.name=spring-pathvariable-vs-requestparam-annotations
server.port=9300

Overall, this application.properties file is used to define the name of the Spring Boot application and specify the port number for the embedded server. These properties help in identifying and configuring the application when it’s launched.

4.4 Creating Implementation Class

The DemoApplication class serves as the entry point for a Spring Boot application. It’s marked with the @SpringBootApplication annotation, which combines key Spring annotations like @Configuration, @EnableAutoConfiguration, and @ComponentScan, streamlining the configuration setup. The main method, designated as the application’s entry point, triggers the Spring Boot application by calling SpringApplication.run(DemoApplication.class, args). This initialization process encompasses auto-configuration, component scanning, and the startup of embedded web servers. As a result, the application becomes operational, handling incoming requests and executing its defined logic.

DemoApplication.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

4.5 Run the Application

Now you can run your Spring Boot application. You can test the different endpoints using tools like curl or a REST client like the Postman tool.

Here’s a brief overview of what each endpoint does:

Curl Requests

-- GET endpoint: Get user by id
-- Remember to replace the user_id
curl -X GET "http://localhost:9300/users/"

-- GET endpoint: Search user

-- Search user based on the query param and return response
curl -X GET "http://localhost:9300/users/search?query="

-- Search user. If not query param is provided default value will be used
curl -X GET "http://localhost:9300/users/search"

5. Passing Encoded vs. Exact Values to Parameters

When working with web applications, especially in scenarios involving URL parameters, there are considerations about whether to pass encoded or exact values to parameters. This decision has implications for data integrity, security, and user experience. Let’s explore the differences between passing encoded and exact values to parameters:

5.1 Encoded Values

Encoded values are used to safely include characters that might have special meanings in URLs, such as spaces, special characters, and non-ASCII characters. Values are encoded using techniques like URL encoding (replacing reserved characters with percent-encoded sequences) or Base64 encoding (converting binary data into ASCII characters).

5.1.1 Advantages

  • Data Integrity: Encoded values ensure that special characters are preserved during transmission and processing, preventing misinterpretation.
  • Security: Encoding can help protect against URL injection attacks, where malicious input can be used to manipulate URLs.

5.2 Exact Values

Exact values are the original values without any encoding or transformation.

5.2.1 Advantages

  • User Experience: Exact values are more human-readable and contribute to a more intuitive user experience.
  • Readability: Debugging and analysis become simpler since the values are straightforward.

In summary, the decision to pass encoded or exact values to parameters depends on the context, requirements, and potential risks. Encoded values are essential for data integrity and security, especially when dealing with user-generated input. On the other hand, exact values contribute to better user experience and ease of debugging. Striking a balance between data safety and user convenience is key to making the right choice based on the specific use case.

6. Conclusion

In conclusion, this project demonstrates the power and simplicity of building robust web applications using Spring Boot, a powerful framework for Java developers. By leveraging the fundamental concepts of Spring Boot, such as annotations, component scanning, and auto-configuration, we’ve created a well-structured and efficient application. The use of @PathVariable and @RequestParam annotations showcase how to handle dynamic URLs and query parameters seamlessly. The adherence to best practices like the Law of Demeter has resulted in a clean and maintainable codebase, promoting modularity and reducing coupling between classes. The project’s configuration, including the application.properties file, has highlighted the ease of customizing application properties for various needs. Overall, this project not only serves as a valuable learning resource for understanding Spring Boot’s core concepts but also underscores its effectiveness in rapidly developing and deploying feature-rich web applications.

7. Download the Project

This was a tutorial to understand the Spring @PathVariable and @RequestParam annotations.

Download
You can download the full source code of this example here: Spring PathVariable and RequestParam example

Yatin

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button