Spring @RequestParam Annotation with Examples

Examples of mapping 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 extract the parameter values manually from the HttpServletRequest and cast them to variables of the desired types.

Spring along with the annotation not only 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 to the @RequestParam in action, we will have a 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 for use in Spring Web as well as 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 it can be omitted if the method parameter and request parameters have same name. The required attribute denotes if the request parameter is mandatory, which is true by default. Lastly, the default attribute can be used to specify a fallback 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.


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

~ 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 parameters, 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 both of the 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 represent the variable to a specific datatype. Interestingly, Spring takes care of this type-casting internally.

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

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

If Spring is unable to cast the param value, it simply returns back 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 a multiple times in the URL or they have a 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 parameter of Set type ensures only unique values of the query string are read.

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 that are annotated with @RequestParam are mandatory. Thus in the previous examples, if we skip a query string parameter from a request, we get 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

In order 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. Using Java optional we can also provide a default value for a missing query string.

@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 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 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. This 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

To summarize 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.

For the complete source code of the examples used here, please refer to our Github Repository.