Spring @MatrixVariable

In this tutorial I will show you how to use @MatrixVariable annotation in Spring Web MVC (Model View Controller) application. The URI has the possibility of including name-value pairs within path segments. The general “URI path parameters” could be applied although the more unique “Matrix URIs”, originating from an old post by Tim Berners-Lee, is also frequently used and fairly well known. Within Spring MVC these are referred to as matrix variables.

Matrix variables can appear in any path segment, each matrix variable separated with a ; (semicolon). For example: /cars;color=red;year=2012. Multiple values may be either , (comma) separated color=red,green,blue or the variable name may be repeated color=red;color=green;color=blue.

If a URL is expected to contain matrix variables, the request mapping pattern must represent them with a URI template. This ensures the request can be matched correctly regardless of whether matrix variables are present or not and in what order they are provided.

Below is an example of extracting the matrix variable q:

// GET /reports/42;q=11;r=22
@RequestMapping(value = "/reports/{reportId}", method = RequestMethod.GET)
public void findReport(@PathVariable String reportId, @MatrixVariable int q) {
  // reportId == 42
  // q == 11
}

I am going to create Spring Boot application and Thymeleaf as a template view file for the front-end or UI (User Interface).

Prerequisites

Java at least 8, Gradle 6.5.1, Maven 3.6.3, Spring Boot 2.3.3, Thymeleaf Template

Project Setup

You can create either gradle or maven based project in your favorite IDE or tool. The name of the project is spring-matrix-variable.

If you are creating gradle based project then use below build.gradle script:

buildscript {
	ext {
		springBootVersion = '2.3.3.RELEASE'
	}
	
    repositories {
    	mavenCentral()
    }
    
    dependencies {
    	classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

plugins {
    id 'java-library'
    id 'org.springframework.boot' version "${springBootVersion}"
}

sourceCompatibility = 12
targetCompatibility = 12

repositories {
    mavenCentral()
}

dependencies {
	implementation "org.springframework.boot:spring-boot-starter-web:${springBootVersion}"
	implementation("org.springframework.boot:spring-boot-starter-thymeleaf:${springBootVersion}")
}

If you are creating maven based project then use below pom.xml file:

<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-matrix-variable</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.3.RELEASE</version>
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
	</dependencies>

    <build>
        <plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
				<configuration>
					<source>at least 8</source>
					<target>at least 8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Web Configuration

@MatrixVariable annotation indicates that a method parameter should be bound to a name-value pair within a path segment. @MatrixVariable annotation is disabled by default in Spring MVC. In order to enable it you need to tweak the configuration and set the removeSemicolonContent property of RequestMappingHandlerMapping to false. By default it is set to true.

If you do not set it to false then you will see the following exception in your application:

Missing matrix variable 'q' for method parameter of type String

In order to support matrix variable in your Spring MVC application, you need to do the following in your Spring Boot application:

package com.roytuts.spring.matrix.variable.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.util.UrlPathHelper;

@Configuration
public class WebConfig implements WebMvcConfigurer {

	@Override
	public void configurePathMatch(PathMatchConfigurer configurer) {
		UrlPathHelper urlPathHelper = new UrlPathHelper();
		urlPathHelper.setRemoveSemicolonContent(false);
		configurer.setUrlPathHelper(urlPathHelper);
	}
}

Web Controller

You need to create a Spring web controller to render your view on UI.

In the following example, I have path variable, matrix variable and the model where I am passing the value of the matrix variable to be available on UI.

package com.roytuts.spring.matrix.variable.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.MatrixVariable;
import org.springframework.web.bind.annotation.PathVariable;

@Controller
public class HomeController {

	@GetMapping("/report/{id}")
	public String homePage(@PathVariable String id, @MatrixVariable String q, Model model) {
		System.out.println("id : " + id);
		System.out.println("q: " + q);
		
		model.addAttribute("matrixVarValue", q);
		
		return "index";
	}

}

View File – UI

The following view file displays the value of matrix variable’s value when rendered in the browser. This template file – index.html – is kept under src/main/resources/templates folder.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Boot Matrix Variable</title>
</head>
<body>
	<p>
		 Matrix Variable's Value : <strong th:text="${matrixVarValue}"></strong>
	</p>
</body>
</html>

Main Class

A class having main method with @SpringBootApplication is enough to deploy the application into embedded Tomcat server.

package com.roytuts.spring.matrix.variable;

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

@SpringBootApplication
public class SpringMatrixVariableApp {

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

}

Testing the Application

Now hit the URL http://localhost:8080/report/50;q=1 in the browser, you will see the below output in the browser:

spring matrix variable

Console Output

id : 50
q: 1

Source Code

Download

Thanks for reading.

Leave a Comment