Spring MVC 和 Thymeleaf:如何从模板访问数据
在典型的 Spring MVC 应用程序中,@Controller
类负责准备包含数据的模型映射并选择要渲染的视图。这模型映射允许对视图技术进行完全抽象,并且在 Thymeleaf 的情况下,它会被转换为一个 Thymeleaf 上下文对象(属于 Thymeleaf模板执行上下文),使得所有定义的变量都可供模板中执行的表达式使用。
Spring 模型属性
Spring MVC 将在视图执行期间可以访问的数据称为模型属性。Thymeleaf 中的等效术语是上下文变量.
存在多种方式可以将模型属性添加到 Spring MVC 中的视图中。以下是一些常见情况:
通过其Model
的addAttribute
方法添加属性:
@RequestMapping(value = "message", method = RequestMethod.GET)
public String messages(Model model) {
model.addAttribute("messages", messageRepository.findAll());
return "message/list";
}
返回ModelAndView
并包含模型属性:
@RequestMapping(value = "message", method = RequestMethod.GET)
public ModelAndView messages() {
ModelAndView mav = new ModelAndView("message/list");
mav.addObject("messages", messageRepository.findAll());
return mav;
}
通过使用注解@ModelAttribute
:
@ModelAttribute("messages")
public List<Message> messages() {
return messageRepository.findAll();
}
的方法公开公共属性messages
如您所见,在以上所有情况中,
这些模型属性(或 Thymeleaf 术语中的上下文变量可以通过以下语法在 Thymeleaf 中访问:${attributeName}
,其中attributeName
在我们的例子中是messages
。这是一个Spring EL表达式。简而言之,Spring EL(Spring 表达式语言)是一种支持在运行时查询和操作对象图的语言。
您可以通过以下方式在 Thymeleaf 视图中访问模型属性:
<tr th:each="message : ${messages}">
<td th:text="${message.id}">1</td>
<td><a href="#" th:text="${message.title}">Title ...</a></td>
<td th:text="${message.text}">Text ...</td>
</tr>
请求参数
请求参数可以在 Thymeleaf 视图中轻松访问。请求参数是从客户端传递给服务器的,例如:
https://example.com/query?q=Thymeleaf+Is+Great!
假设我们有一个@Controller
发送带有请求参数的重定向:
@Controller
public class SomeController {
@RequestMapping("/")
public String redirect() {
return "redirect:/query?q=Thymeleaf+Is+Great!";
}
}
为了访问q
参数,您可以使用param.
前缀:
<p th:text="${param.q}">Test</p>
在上面的例子中,如果参数q
不存在,则段落中会显示空字符串;否则将显示q
的值。
由于参数可能是多值的(例如 `https://example.com/query?q=Thymeleaf%20Is%20Great!&q=Really%3F`),您可以使用方括号语法来访问它们:
<p th:text="${param.q[0] + ' ' + param.q[1]}" th:unless="${param.q == null}">Test</p>
注意:如果您使用${param.q}
访问多值参数,您将得到一个序列化后的数组作为值。
访问请求参数的另一种方式是使用特殊的#request
对象,该对象为您提供对javax.servlet.http.HttpServletRequest
对象的直接访问:
<p th:text="${#request.getParameter('q')}" th:unless="${#request.getParameter('q') == null}">Test</p>
会话属性
在下面的示例中,我们将mySessionAttribute
添加至会话:
@RequestMapping({"/"})
String index(HttpSession session) {
session.setAttribute("mySessionAttribute", "someValue");
return "index";
}
与请求参数类似,会话属性可以通过使用session.
前缀:
<p th:text="${session.mySessionAttribute}" th:unless="${session == null}">[...]</p>
或者通过使用#session
,该对象为您提供对javax.servlet.http.HttpSession
对象的直接访问:${#session.getAttribute('mySessionAttribute')}
ServletContext 属性
ServletContext 属性在请求和会话之间共享。要在 Thymeleaf 中访问 ServletContext 属性,您可以使用#servletContext.
前缀:
<table>
<tr>
<td>My context attribute</td>
<!-- Retrieves the ServletContext attribute 'myContextAttribute' -->
<td th:text="${#servletContext.getAttribute('myContextAttribute')}">42</td>
</tr>
<tr th:each="attr : ${#servletContext.getAttributeNames()}">
<td th:text="${attr}">javax.servlet.context.tempdir</td>
<td th:text="${#servletContext.getAttribute(attr)}">/tmp</td>
</tr>
</table>
Spring Bean
Thymeleaf 允许使用@beanName
语法访问在 Spring 应用上下文中注册的 Bean,例如:
<div th:text="${@urlService.getApplicationUrl()}">...</div>
在上面的示例中,@urlService
引用的是您上下文中注册的一个 Spring Bean,例如
@Configuration
public class MyConfiguration {
@Bean(name = "urlService")
public UrlService urlService() {
return () -> "domain.com/myapp";
}
}
public interface UrlService {
String getApplicationUrl();
}
这在某些场景下非常简便且实用。