Mastering Spring Boot @MatrixVariable: Real-World Examples and Implementation

This article explains Spring Boot’s @MatrixVariable feature, covering its RFC 3986 basis, practical usage scenarios, multiple code examples, and the underlying request‑mapping mechanism, helping developers efficiently pass multi‑dimensional parameters within URI paths.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Mastering Spring Boot @MatrixVariable: Real-World Examples and Implementation

Environment: Spring Boot 3.0.5

1. Introduction

RFC 3986 ( https://datatracker.ietf.org/doc/html/rfc3986#section-3.3 ) discusses name‑value pairs in path segments. In Spring MVC they are called matrix variables , also known as URI path parameters.

Matrix variables can appear in any path segment, each variable separated by a semicolon and multiple values separated by commas (e.g., /cars;color=red,green;year=2012). Repeating the same variable name also adds multiple values (e.g., color=red;color=green;color=blue).

When a URL contains matrix variables, the controller method’s mapping must use URI variables to mask the variable content and ensure the request matches regardless of the order or presence of matrix variables.

// GET /pets/42;q=11;r=22
@GetMapping("/pets/{petId}")
public void findPet(@PathVariable String petId, @MatrixVariable int q) {
  // petId == 42
  // q == 11
}

@MatrixVariable Use Cases

Useful when multiple parameters related to a path segment need to be passed while keeping the URI clear and semantic.

Applicable for resources that require multi‑dimensional identification, such as an image service that distinguishes pictures by color mode, resolution, etc.

Example request:

2. Practical Cases

2.1 Case 1

@GetMapping("/m1/{id}")
public Object matrix1(@PathVariable("id") Long id, @MatrixVariable Integer q, @MatrixVariable String p) {
  return String.format("input, id: %d, q: %d, p: %s", id, q, p);
}

2.2 Case 2 – Multiple Matrix Variables in Different Path Variables

@GetMapping("/m2/{cateId}/a2/{artId}")
public Object matrix2(
    @PathVariable("cateId") Long cateId,
    @MatrixVariable(pathVar = "cateId", name = "q") Integer q1,
    @PathVariable("artId") Long artId,
    @MatrixVariable(pathVar = "artId", name = "q") Integer q2) {
  return String.format("input, cateId: %d, q: %d, artId: %d, q: %s%n", cateId, q1, artId, q2);
}

Request illustration:

2.3 Case 3 – Using Map to Receive Matrix Values

@GetMapping("/m3/{cateId}/a2/{artId}")
public Object matrix3(
    @PathVariable("cateId") Long cateId,
    @MatrixVariable MultiValueMap<String, String> cateMap,
    @PathVariable("artId") Long artId,
    @MatrixVariable(pathVar = "artId") MultiValueMap<String, String> artMap) {
  return Map.of("cate", cateMap, "art", artMap);
}

Request illustration:

2.4 Case 4 – Handling Missing Matrix Parameters

If a matrix parameter is absent after the variable path, Spring will throw an error. You can configure the parameter as optional or provide a default value.

@GetMapping("/m2/{cateId}/a2/{artId}")
public Object matrix2(...,
    // set default value
    @MatrixVariable(pathVar = "artId", name = "q", required = false, defaultValue = "999") Integer q2) {
  return String.format("input, cateId: %d, q: %d, artId: %d, q: %s%n", cateId, q1, artId, q2);
}

3. Implementation Principle

3.1 Path Matching Stores Matrix Variables

public abstract class AbstractHandlerMethodMapping {
  protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
    HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
  }
  protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) {
    handleMatch(bestMatch.mapping, lookupPath, request);
  }
}

During matching, the matrix part of the URI is extracted and stored in the request attributes.

public abstract class RequestMappingInfoHandlerMapping {
  protected void handleMatch(RequestMappingInfo info, String lookupPath, HttpServletRequest request) {
    extractMatchDetails(pprc, lookupPath, request);
  }
  private void extractMatchDetails(...) {
    // Store matrix variables in the request
    request.setAttribute(MATRIX_VARIABLES_ATTRIBUTE, result.getMatrixVariables());
  }
}

3.2 Resolving @MatrixVariable Parameters

public class MatrixVariableMethodArgumentResolver {
  protected Object resolveName(...) throws Exception {
    // Retrieve the map stored in the previous step
    Map<String, MultiValueMap<String, String>> pathParameters =
        (Map<String, MultiValueMap<String, String>>)
        request.getAttribute(HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
    MatrixVariable ann = parameter.getParameterAnnotation(MatrixVariable.class);
    String pathVar = ann.pathVar();
    if (!pathVar.equals(ValueConstants.DEFAULT_NONE)) {
      if (pathParameters.containsKey(pathVar)) {
        paramValues = pathParameters.get(pathVar).get(name);
      }
    }
    return paramValues.get(0);
  }
}

That concludes the entire article. Hope it helps you.

Finished!!!

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaSpring BootrestMatrix Variable
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.