Generic Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE

1. Introduction

In this short tutorial, we're going to learn how to use Thymeleaf to create URLs using Spring path variables.

We use path variables when we want to pass a value as part of the URL. In a Spring controller, we access these values using the @PathVariable annotation.

2. Using Path Variables

First, let's set up our example by creating a simple Item class:

public class Item {
    private int id;
    private String name;

    // Constructor and standard getters and setters
}

Now, let's take create our controller:

@Controller
public class PathVariablesController {

    @GetMapping("/pathvars")
    public String start(Model model) {
        List<Item> items = new ArrayList<Item>();
        items.add(new Item(1, "First Item"));
        items.add(new Item(2, "Second Item"));
        model.addAttribute("items", items);
        return "pathvariables/index";
    }
    
    @GetMapping("/pathvars/single/{id}")
    public String singlePathVariable(@PathVariable("id") int id, Model model) {
        if (id == 1) {
            model.addAttribute("item", new Item(1, "First Item"));
        } else {
            model.addAttribute("item", new Item(2, "Second Item"));
        }
        
        return "pathvariables/view";
    }
}

In our index.html template, let's loop through our items and create links calling the singlePathVariable method:

<div th:each="item : ${items}">
    <a th:href="@{/pathvars/single/{id}(id = ${item.id})}">
        <span th:text="${item.name}"></span>
    </a>
</div>

The code we just created makes URLs like this:

http://localhost:8080/pathvars/single/1

This is standard Thymeleaf syntax for using expressions in URLs.

We can also use concatenation to achieve the same result:

<div th:each="item : ${items}">
    <a th:href="@{'/pathvars/single/' + ${item.id}}">
        <span th:text="${item.name}"></span>
    </a>
</div>

3. Using Multiple Path Variables

Now that we've covered the basics of creating a path variable URL in Thymeleaf, let's quickly cover using multiple.

First, we'll create a Detail class and modify our Item class to have a list of them:

public class Detail {
    private int id;
    private String description;

    // constructor and standard getters and setters
}

Next, let's add a list of Detail to Item:

private List<Detail> details;

Now, let's update our controller to add a method using multiple @PathVariable annotations:

@GetMapping("/pathvars/item/{itemId}/detail/{dtlId}")
public String multiplePathVariable(@PathVariable("itemId") int itemId, 
  @PathVariable("dtlId") int dtlId, Model model) {
    for (Item item : items) {
        if (item.getId() == itemId) {
            model.addAttribute("item", item);
            for (Detail detail : item.getDetails()) {
                if (detail.getId() == dtlId) {
                    model.addAttribute("detail", detail);
                }
            }
        }
    }
    return "pathvariables/view";
}

Finally, let's modify our index.html template to create URLs for each detail record:

<ul>
    <li th:each="detail : ${item.details}">
        <a th:href="@{/pathvars/item/{itemId}/detail/{dtlId}(itemId = ${item.id}, dtlId = ${dtl.id})}">
            <span th:text="${detail.description}"></span>
        </a>
    </li>
</ul>

4. Conclusion

In this quick tutorial, we learned how to use Thymeleaf to create URLs with path variables. We started by creating a simple URL with only one. Later, we expanded on our example to use multiple path variables.

The example code is available over on GitHub.

Generic bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE
Comments are closed on this article!