how to access variables in thymeleaf templates using spring mvc - spring-mvc

How can I access the variables I add to model in Spring MVC inside the thymeleaf templates? I have the following controller code:
#Controller
public class ThymeLeafController {
#GetMapping("/thyme")
public void thymeleaf(ModelAndView modelAndView) {
modelAndView.addObject("var1", "var1");
modelAndView.addObject(Arrays.asList("var2", "var3", "var4"));
modelAndView.getModel().put("var5", "var5");
modelAndView.getModelMap().addAttribute("var6", "var6");
modelAndView.getModelMap().addAttribute(Arrays.asList("var7", "var8", "var9"));
modelAndView.setViewName("thymeleaf");
}
}
How can I access the variables var1, var5, var6, etc. inside thymeleaf templates?
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>Thymeleaf</title>
</head>
<body>
<div th:if="#{var1}"></div>
</body>
</html>

Behavior:
Accessing the attributes depends upon where they were added. If the attributes were added to the ModelAndView object, they must be accessed throught "${modelAndView.model.xxxx}" where xxxx is the attribute name. If the attributes were added to Model object, they are accessible using just the attribute name itself "${attributeName}". See example below.
Controller:
#GetMapping("/thyme")
public void thymeleaf(ModelAndView modelAndView, Model model) {
modelAndView.addObject("var1", "var1");
modelAndView.addObject(Arrays.asList("var2", "var3", "var4"));
modelAndView.getModel().put("var5", "var5");
modelAndView.getModelMap().addAttribute("var6", "var6");
modelAndView.getModelMap().addAttribute(Arrays.asList("var7", "var8", "var9"));
model.addAttribute("attribute1", "attributeValue1");
}
Template:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Thymeleaf</title>
</head>
<body>
<div th:text="${attribute1}"></div>
<div th:text="${modelAndView.model}"></div>
<div th:text="${modelAndView.model.var1}"></div>
</body>
</html>
Output:
attributeValue1
{var1=var1, stringList=[var7, var8, var9], var5=var5, var6=var6}
var1

Related

Unable to display value which is returned from Spring controller

I'm trying to display like ${mesg}, it's not displaying the content, which is coming from the Spring controller. I have tried many ways, but no luck.
<html>
<head> <meta charset="ISO-8859-1">
<title>HOME</title>
</head>
<body>
<div align="center"> ${mesg} </div>
</body>
</html>
#RequestMapping(value="/savefile",method=RequestMethod.POST)
public String getStatus(#PathParam("pwd") String Pwd,ModelMap map){
System.out.println(":::pwd::"+Pwd);
map.addAttribute("mesg", "Welcome to mBOK");
return "Success";
}

css doesn't load in this project. but css working smoothly in other projects

Controller Class
#RequestMapping(value = "/")
public String indexmethod(){
return "index";
}
css file location : \src\main\resources\static\index.css
jsp file:
<%# taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %>
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<link href="/index.css" rel="stylesheet">
<title></title>
</head>
<body>
<div>
<h2>cascascascascas</h2>
</div>
</body>
</html>
Try this:
<link href="${pageContext.request.contextPath}/index.css" rel="stylesheet">
Found the Solution. A specific #requestmapping(value="...") option in
Controller class block the static file.. I just delete that specific
#reqestmapping and after that i get access to static folder. I am
keeping this question. So that, it can help other to solve same
problem.

Thymeleaf + Spring-Boot - why can't I access static resources?

My project tree looks like this:
I can access the templates now, but can't load static resources such as CSS, images, and JS.
I have a common.html fragment where I declare all my static resources, for instance:
<link rel="stylesheet" th:href="#{/css/app.css}"/>
A header fragment where I include common.html like so:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head th:include="fragments/common :: commonFragment" lang="en"></head>
// page body
</html>
A default.html file for layout:
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head th:include="fragments/common :: commonFragment" lang="en">
<meta charset="utf-8"/>
<meta name="robots" content="noindex, nofollow"/>
<title>Touch</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta http-equiv="content-dataType" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<link rel="shortcut icon" th:href="#{/static/images/favicon.ico}" type="image/x-icon" />
</head>
<body>
<div th:id="defaultFragment" th:fragment="defaultFragment" class="container">
<div id="header" th:replace="fragments/header :: headerFragment" />
<div layout:fragment="content" />
</div>
</body>
</html>
Also, on my application.properties file, I have these entries:
#SPRING RESOURCE HANDLING
spring.resources.static-locations=classpath:/resources/
#THYMELEAF
spring.thymeleaf.cache = true
spring.thymeleaf.check-template = true
spring.thymeleaf.check-template-location = true
spring.thymeleaf.content-type=text/html
spring.thymeleaf.enabled=true
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.mode=HTML5
spring.thymeleaf.prefix=classpath:templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.template-resolver-order=1
But I keep getting the same No mapping found message.
32190 [http-nio-8081-exec-2] WARN o.s.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/central/css/app.css] in DispatcherServlet with name 'dispatcherServlet'
What am I not seeing here?
I solved this problem with the following code:
spring.resources.static-locations=classpath:templates/
Use the spring.resources.static-locations in your properties to define the static resources locations (making them directly publicly available):
spring.resources.static-locations=classpath:/your/static/resources/here/like/central/css/
you can provide comma separated values i.e. taken from the documentation:
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ # Locations of static resources.
I'm using Spring Boot 2.2 and not getting any of my static content. I discovered two solutions that worked for me:
Option #1 - Stop using #EnableWebMvc annotation
This annotation disables some automatic configuration, including the part that automatically serves static content from commonly-used locations like /src/main/resources/static. If you don't really need #EnableWebMvc, then just remove it from your #Configuration class.
Option #2 - Implement WebMvcConfigurer in your #EnableWebMvc annotated class and implementaddResourceHandlers()
Do something like this:
#EnableWebMvc
#Configuration
public class SpringMVCConfiguration implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/js/**").addResourceLocations("classpath:/static/js/");
registry.addResourceHandler("/css/**").addResourceLocations("classpath:/static/css/");
registry.addResourceHandler("/vendor/**").addResourceLocations("classpath:/static/vendor/");
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
}
}
Just remember that your code is now in charge of managing all static resource paths.
try to add mapping of your static resources in link
<link rel="stylesheet" th:href="#{/css/app.css}"
href="../../../css/app.css" />

How to pass a map in thymeleaf (spring 4)

I want to pass a map from a properties file using the thymeleaf template engine.
Exception:
org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'title' cannot be found on object of type 'java.lang.String' - maybe not public?
provider.html:
<!DOCTYPE>
<html th:include="receiver :: receiver(#{site})"></html>
receiver.html:
<!DOCTYPE HTML>
<html th:fragment="receiver(map)">
<head>
<title th:text="${map.title}">title</title>
</head>
<body th:text="${map.body}">
body
</body>
</html>
messages.properties:
site.title = Any title
site.body = Any body
Controller:
#Controller
public class StartController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public String start(Model model) {
return "provider";
}
}
It simply like in Java. Key and value of the Map
<div th:each="userEnrty: ${userMap}">
<p th:text="${userEntry.key}">No Id!</p>
<p th:text="${userEntry.value}">No Name!</p>
</div>
So I figured out that property-files are processed as Map. So 'site' wasn't a map at all.
My solution now is to pass the name of the variable-prefi and get the keys by thymeleaf preprocessing.
provider.html:
<!DOCTYPE>
<html th:include="receiver :: receiver('site')"></html>
receiver.html:
<!DOCTYPE HTML>
<html th:fragment="receiver(mapname)">
<head>
<title th:text="#{__${mapname}__.title}">title</title>
</head>
<body th:text="#{__${mapname}__.body}">
body
</body>
</html>
messages.properties
site.title = Any title
site.body = Any body

How do I use dynamic content in thymeleaf fragments?

I have a spring project set up with thymeleaf and thymeleaf-layout-dialect.
In this project I have a controller
#Controller
public class HomeController {
#RequestMapping(value="/", method = RequestMethod.GET)
public String showHome(Model model){
return "home";
}
#RequestMapping(value="/info", method = RequestMethod.GET)
public String showInfo(Model model){
return "info";
}
}
I also have a layout
...
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<body>
<div layout:fragment="header">
dummy header
</div>
<div layout:fragment="content">
dummy contents
</div>
</body>
</html>
and two views: home.html and info.html which have different unique contents
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="layout">
<body>
<div layout:fragment="content">
unique contents
</div>
</body>
</html>
and a header
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<body>
<div layout:fragment="header">
username is ${username}
</div>
</body>
</html>
I'd like to print the username in the header without passing it as an attribute on the model in the controller methods. So, Can I run some custom java code before the header is included to find out the username regardless of what controller method is beeing used? What options do I have?
If you would use Spring Security in combination with the Thymeleaf Spring Security module, you can do the following:
<span class="user-info">
<small>Welcome,</small>
<span sec:authentication="principal">Username</span>
</span>
If you don't want to use Spring Security, you can write a custom dialect/processor which inserts the username for you.

Resources