Just What Are Spring 3.2 Matrix Variables? – Part 2: The Code

My last blog on Spring’s support for Matrix Variables concentrated on explaining what they were and why you’d want to use them. Having sorted out the what and the why, this blog is all about the how and how you use them. I also gave several examples of Matrix URIs and so, it seems good idea to demonstrate some code that processes a couple of them.

The examples were:



As you’d expect, in writing code to handle Matrix Variables, the Guys at Spring are building upon the existing Spring MVC framework by introducing the new @MatrixVariable annotation. This is used to annotate request handler method arguments so that Spring can inject the relevant bits of the matrix uri. @MatrixVariable has four arguments: value,defaultValue, pathVar and required, all of which are fully explained in Springs javadocs.

And so to some code… If you remember in my last blog on this subject, the scenario I chose was one that deals with processing a bunch of share/stock prices and the sample application, available on Github, takes a Matrix URI, chops it up and adds it to a Model for a JSP to display.

In writing the code, the first thing to do is to create a new controller to process the URIs…

@RequestMapping(value = "/matrixvars") 
public class MatrixVariableController { 
  private static final Logger logger = LoggerFactory.getLogger(MatrixVariableController.class); 

In the code I’ve added a class level @RequestMapping annotation, which contains the first chunk of my URIs: matrixvars. This is a useful thing to do as it directs all URIs that contain the value ‘matrixvar‘ as the first path element to this controller and saves a lot of duplication.

The next thing to do is to add some code to this class that deals with the first URI:


The first request handler method is:

  @RequestMapping(value = "/{stocks}", method = RequestMethod.GET) 
  public String showPortfolioValues(@MatrixVariable Map<String, List<String>> matrixVars, Model model) { 
    logger.info("Storing {} Values which are: {}", new Object[] { matrixVars.size(), matrixVars }); 
    List<List<String>> outlist = map2List(matrixVars); 
    model.addAttribute("stocks", outlist); 
    return "stocks"; 
  private List<List<String>> map2List(Map<String, List<String>> stocksMap) { 
    List<List<String>> outlist = new ArrayList<List<String>>(); 
    Collection<Entry<String, List<String>>> stocksSet = stocksMap.entrySet(); 
    for (Entry<String, List<String>> entry : stocksSet) { 
      List<String> rowList = new ArrayList<String>(); 
      String name = entry.getKey(); 
      List<String> stock = entry.getValue(); 
    return outlist; 

Looking at the @RequestMapping annotation you can see that I’ve assigned it a value of /{stocks}. This, when combined with the class level @RequestMapping annotation, will instruct Spring to map any matching requests to this method. The text inside the curly braces, {stocks}, indicates that this part of the URI can be parsed and injected into the appropriate method argument.

Next, take a look at the @MatrixVariable annotation. This sits neatly in front of the argument into which I want the stock data injected; however, the slightly tricky thing here is getting the argument type right. If you get this wrong then you’ll simply get a ClassCastException when you try to use your data. When the input data is of the form:




…then the type is Map<String,List<String>>, where the keys are A and W and their respective values are B,C,D and X,Y,Z.

Hence, given the URI above, the map argument will contain….

{BT.A=[276.70, +10.40, +3.91], AZN=[236.00, +103.00, +3.29], SBRY=[375.50, +7.60, +2]}

That’s the important bit over with, the rest of the method is very straight forward in that is simply converts the input map into a list and adds it to the model for the JSP (not shown here) to display. Note that this isn’t very useful code, so don’t pay that much attention to it and besides I’m not fond of embedding collections within collections – it doesn’t seem like a good idea.

Moving on, I’ll now take a look at the next URI. Notice that I’ve purposely made this similar to the first, with the only difference being the addition of the user’s account details:


This URI is mapped to the following method:

  @RequestMapping(value = "/{stocks}/{account}", method = RequestMethod.GET) 
  public String showPortfolioValuesWithAccountInfo(@MatrixVariable(pathVar = "stocks") Map<String, List<String>> stocks, 
      @MatrixVariable(pathVar = "account") Map<String, List<String>> accounts, Model model) { 
    List<List<String>> stocksView = map2List(stocks); 
    model.addAttribute("stocks", stocksView); 
    List<List<String>> accountDetails = map2List(accounts); 
    model.addAttribute("accountDetails", accountDetails); 
    return "stocks"; 

In this case the full path description is /matrixvars/{stocks}/{account}. I guess that this simply tells Spring to look out for /matrixvars, followed by a '/' followed by anything, followed by a '/', followed by anything, when it does its mapping.

In this case there are two @MatrixVariable annotations to which I’ve added the annotation’s pathVar argument supplying values stocks and accounts. These neatly label where the matrix variable values need injecting into the method arguments.

The final point to remember is that Matrix Variable are incredibly flexible; there are another three arguments to the @MatrixVaraible annotation that I’ve not considered here; however, the general procedure is the same in every case: take the URI, figure out what the different matrix variables are, design a request handler and map the URI’s matrix variables to your methods arguments – taking care to ensure that you get the argument type correct.

  • The full sample code for this blog is available on Github: https://github.com/roghughe/captaindebug/tree/master/spring-3.2
Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

Leave a Reply

one + 3 =

Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books