I just started using Spring Web & Thymeleaf for the development of a simple webapplication. It is going pretty well but so far I am unable to figure out how to prevent duplicate code for the hrefs and various paths/routes.
Example Spring get mapping:
...
@GetMapping(path="/hello")
public String hello(){
return "hello";
}
...
First HTML page (index.html) containing href to '/hello', using Thymeleaf:
...
<a th:href="@{/hello}">Hello</a>
...
Second HTML page (home.html) containing href to '/hello', using Thymeleaf:
...
<a th:href="@{/hello}">Hello</a>
...
How can I arrange my code so that I don't have to manual update the href on each HTML page when I change the path of a @GetMapping?
Basically I would like to assign the path '/hello' to a variable which i can then reference at each href and getmapping
BR, Kazi
I have been googling for a couple of hours but am unable to find any usable information on my problem. I have noticed the 'name' attribute of the Spring '@GetMapping' annotation but have no idea if this provides a solution or how it should work together with Thymeleaf. Also i know that the Django framework for Python based webapplications provides the ability to name routes (using urlpatterns) and reference these from within its templating language. I would expect a similar solution is available for the Spring framework.
CodePudding user response:
I manage to find two solutions:
Solution 1
Using the capital letters of the controller name in combination with the name of the requestmethod, as described in section 11.1 'Building URIs to controllers' of the official Thymeleaf document Thymeleaf Tutorial: Thymeleaf Spring. The capital letters of the controller name and the requestmethod name are separate by a '#'.
Important: The 'name' attribute of the @RequestMapping must not be used else Thymeleaf won't be able to resolve the view!
Note: Possibly this solution is preferred in case path variables or request parameters must be added to the url. (I have not investigated this.)
Example Controller
public class ExampleController {
@RequestMapping("/data")
public String getData(Model model) {
...
return "template"
}
@RequestMapping("/data")
public String getDataParam(@RequestParam String type) {
...
return "template"
}
}
Example links
<a th:href="${(#mvc.url('EC#getData')).build()}">Get Data Param</a>
<a th:href="${(#mvc.url('EC#getDataParam').arg(0,'internal')).build()}">Get
Data Param</a>
Solution 2
Using the 'name' attribute of the @RequestMapping. As discribe in the following answer to Stackoverflow question Url building by @RequestMapping name not working as expected with custom names
The first example only uses the 'name' attribute in the @RequestMapping at the method level.
Example Controller 1
@Controller
public class ExampleController {
@RequestMapping(value="/", method=RequestMethod.GET, name="home")
public String index(Model model) {
return "index"
}
}
Example link 1
<a th:href="${(#mvc.url('home')).build()}">Home</a>
The second example uses the 'name' attribute in the @RequestMapping at the method level and type level.
Example Controller 2
@Controller
@RequestMapping(value="/information", name="info")
public class ExampleController {
@RequestMapping(value="/organisation", method=RequestMethod.GET,
name="org")
public String contact(Model model) {
return "organisation"
}
}
Example link 2
<a th:href="${(#mvc.url('info#org')).build()}">Contact</a>