Spring @RequestParam Annotation with Examples

This guide covers mapping the request query string parameters to Spring Controller method arguments using @RequestParam annotation.

Overview

Spring Web provides @RequestParam annotation for extracting and mapping query string parameters of a request into Spring Controller’s method arguments. Without that, we’ll have to pull the parameter values manually from the HttpServletRequest and cast them to variables of the desired types.

Spring, along with the annotation, saves us from the manual work. It also provides flexible ways of reading single value or multi-value or optional parameters and makes them available as method arguments.

Spring @RequestParam Annotation

Before we see the @RequestParam in action, we will look at the annotation itself.

Spring @RequestParam annotation maps request parameters to the arguments of a request handler method in Spring Controllers. We can use this annotation on method parameters to bound request parameters by their names.

Interestingly, this annotation is available in Spring Web and Spring WebFlux annotation-based controllers.

@Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RequestParam { @AliasFor("name") String value() default ""; @AliasFor("value") String name() default ""; boolean required() default true; String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n"; }
Code language: Java (java)


There are only three attributes in this annotation. The name attribute denotes the name of the request param, and we can omit it if the method parameter and request parameters have the same name. The required attribute represents if the request parameter is mandatory, which is true by default. Lastly, the default attribute can specify a fall-back value of a request parameter, which will be used only when the request parameter isn’t present.

Using @RequestParam

To see @RequestParam in action, we’ll write a @GetMapping method in a Spring @RestController and execute the endpoint with requests contenting query parameters.

Reading Single Query String Parameter

Let’s consider we want to read a single query string parameter from a request and map it to the controller method argument.

@GetMapping("/data1") public String singleParam(@RequestParam String id) { return "id: " + id; }
Code language: Java (java)

Behind the scenes, Spring looks for a query string parameter ‘id‘ and extracts its value from the request. Then it invokes the request handler singleParam(Id) and passes the param value as an argument.


We will execute a GET /data request and pass a query string parameter – id to test this controller.

~ curl 'http://localhost:8080/data1?id=112' -- id: 112
Code language: Bash (bash)

Reading Multiple Query String Parameters

Similarly, if the request has more than one query string parameter, we can use @RequestParam annotation individually on the respective method arguments.

@GetMapping("/data2") public String multiParam( @RequestParam String id, @RequestParam String name) { return "id: " + id + ", name: " + name; }
Code language: Java (java)

Our controller reads id and name parameters from the request.

~ curl 'http://localhost:8080/data2?id=112&name=Jon' -- id: 112, name: Jon
Code language: Bash (bash)

Executing the respective GET request, we see that both request parameters are mapped correctly.

Mapping Query String Parameters with Specific Type

Be default, all the request query string parameters are represented as String. However, our method argument can describe the variable to a specific datatype. Interestingly, Spring takes care of this type-casting internally.

For example, our Spring Controller reads a request parameter as a Long value.

@GetMapping("/data3") public String typedParam(@RequestParam Long id) { return "id: " + id; }
Code language: Java (java)

If Spring cannot cast the param value, it simply returns HTTP Status 400 (BAD_REQUEST), as shown.

~ curl -i 'http://localhost:8080/data3?id=abc' -- HTTP/1.1 400 ...
Code language: Bash (bash)

Reading Multi Value Query String Parameters

Any query string parameter in a request can have multiple values. That means they can appear multiple times in the URL or have comma-separated values. Spring @RequestParam annotation maps such request parameters to a collection- for example, List.

@GetMapping("/data4") public String multiValueParams(@RequestParam List<String> id) { return "id: " + id; }
Code language: Java (java)

Note: We can also use an Array type or a Set type. Using the parameter of Set type ensures that the query string has unique values.

Let’s execute a request with a comma-separated multi-value parameter.

~ curl 'http://localhost:8080/data4?id=12,13,15,16' -- id: [12, 13, 15, 16]
Code language: Bash (bash)

Or, we can specify the parameter multiple times with different values.

~ curl 'http://localhost:8080/data4?id=12&id=13&id=15' -- id: [12, 13, 15]
Code language: Bash (bash)

Making Query String Parameters Optional

By default, all the request parameters annotated with @RequestParam are mandatory. Thus in the previous examples, if we skip a query string parameter from a request, we get a Bad Request response.

~ curl -i 'http://localhost:8080/data4' -- HTTP/1.1 400 ...
Code language: Bash (bash)

Now, let’s see the three different ways of using @RequestParam annotation on optional request parameters.

Using @RequestParam required=false

To support optional query string parameters in a controller, we can use @RequestParam with required=false flag.

@GetMapping("/data5") public String optionalParams (@RequestParam(required = false) Long id) { return "id: " + id; }
Code language: Java (java)

Now, we can omit the id parameter from our request.

~ curl 'http://localhost:8080/data5' -- id: null
Code language: JavaScript (javascript)

Using @RequestParam with Java Optional

Alternatively, we can use Java Optional to make a particular query string parameter in a request optional. We can also provide a default value for a missing query string using Java Optional.

@GetMapping("/data6") public String javaOptionalParams (@RequestParam Optional<String> id) { return "id: " + id.orElseGet(() -> "Unknown"); }
Code language: Java (java)

We have used Java Optional to provide a fall-back value for a missing query string.

~ curl 'http://localhost:8080/data6' -- id: Unknown
Code language: Bash (bash)

Using @RequestParam defaultValue

Lastly, we can use the defaultValue attribute of @RequestParam annotation to specify a default value of a request parameter. Spring uses the provided defaultValue only when the actual parameter in the request is absent or is empty.

@GetMapping("/data7") public String defaultParams (@RequestParam(defaultValue = "Unknown") String id) { return "id: " + id; }
Code language: Java (java)

Let’s test this by executing a GET request without any parameters.

~ curl 'http://localhost:8080/data7' -- id: Unknown
Code language: Bash (bash)

Mapping Query String Parameters by Name

In the previous examples, the controller method argument and the respective query string parameter of a request had the same name. Thankfully, we can use the name attribute of Spring @RequestParam when the query string parameter name is different than that of the method argument.

@GetMapping("/data8") public String namedParams (@RequestParam(name = "id") String dataId) { return "dataId: " + dataId; }
Code language: Java (java)

Reading Query String Parameters as Java Map

With Spring @RequestParam annotation, we can collect all the request query string parameters as a HashMap. That is useful when we want to read all the query string parameters and their values together.

@GetMapping("/data9") public String mappedParams (@RequestParam Map<String, String> dataQuery) { return dataQuery.toString(); }
Code language: Java (java)
~ curl 'http://localhost:8080/data9?id=12&year=2034' -- {id=12, year=2034}
Code language: Bash (bash)

Summary

We have covered using Spring @RequestParam annotation to map query string parameters to controller method arguments. This annotation is available for both Spring MVC and Spring WebFlux.

In this tutorial, we had a detailed overview of the @RequestParam annotation and covered various scenarios of mapping request parameters to controller method arguments.

Please refer to our Github Repository for the complete source code of the examples used here.