Spring Boot REST API MultiValueMap Example

MultiValueMap

In this example I am going to show you how to use Spring’s MultiValueMap in REST API. This MultiValueMap is similar to the Jersey’s MultivaluedMap. A MultiValueMap<K, V> or MultivaluedMap<K, V> is a map of key-values pairs. Each key can have zero or more values, where K – the type of keys maintained by this map and V – the type of mapped values.

This type of multi-value map is mainly used for storing header values in the request. Your REST API endpoint may take several parameters with multiple values. So, for the same key you can add multiple values in the multi-valued map.

For example, let’s say you want to pass different values for the same key in the HTTP header and the code for this would be similar to the following snippets:

MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("Accept-Encoding", "compress;q=0.5");
map.add("Accept-Encoding", "gzip;q=1.0");

Related Post:

Prerequisites

Java 11/19, Maven 3.8.5, Spring Boot 2.7.0/3.1.3

Project Setup

The following pom.xml file can be used for the maven based 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>springboot-rest-api-multivaluemap</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.3</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>

REST Controller

I am creating a simple REST endpoint to receive the request in the MultiValueMap and sending those values after extraction as a response to the client.

@RestController
public class AppRestController {

	@PostMapping("/multiValueMap")
	public ResponseEntity<String> multiValueMap(@RequestBody MultiValueMap<String, String> multiValueMap) {
		String encoding = multiValueMap.get("Accept-Encoding").stream().map(String::toString)
				.collect(Collectors.joining(","));

		String contentType = multiValueMap.get("Content-Type").get(0);

		return new ResponseEntity<String>(encoding + "," + contentType, HttpStatus.OK);
	}

}

In the above code snippets, I am joining the values for the same key or if I am sure that I have only one value then I am extracting the 0th value from the List.

Spring Boot Main Class

Here the main class will deploy the app into the embedded Tomcat server.

@SpringBootApplication
public class App {

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

}

Testing using REST Client

Either you can write a client program using any programming language or you can use any REST client tool to test the REST API. I will show you both ways of testing the service API.

REST Client – Spring Boot Program

I am writing Spring Boot Java program to test the REST service.

REST Template Config

In order use the RestTemplate from Spring framework you need to configure RestTemplate bean. RestTemplate bean provides number of useful methods to invoke REST APIs seamlessly.

@Configuration
public class RestClientConfig {

	@Bean
	public RestTemplate restTemplate() {
		return new RestTemplate();
	}

}

Invoking REST API

Here is the code snippets that invoke the REST API using the MultiValueMap parameter.

@SpringBootApplication
public class App implements CommandLineRunner {

	@Autowired
	private RestTemplate restTemplate;

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

	@Override
	public void run(String... args) throws Exception {
		MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
		map.add("Accept-Encoding", "compress;q=0.5");
		map.add("Accept-Encoding", "gzip;q=1.0");
		map.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);

		String response = restTemplate.postForObject("http://localhost:8080/multiValueMap", map, String.class);

		System.out.println("Response: " + response);
	}

}

Notice how I have created MultiValueMap instance and how I have stored key/values pairs.

Make sure you have already started the REST service application. Now, when you execute the above main class, you will see the following response from the REST service:

Response: compress;q=0.5,gzip;q=1.0,application/json

REST Client – Postman

Next I am using REST client tool Postman to test the REST service. You will also learn how to form the request body in Postman tool for MultiValueMap parameter.

spring rest api multivaluemap

You cannot pass the input request as JSON value so, I am passing as key/value pairs as a x-www-form-urlencoded.

Source Code

Download

Leave a Reply

Your email address will not be published. Required fields are marked *