Thymeleaf+SpringMVC,如何從模板中獲取數據
在一個典型的SpringMVC應用中,帶@Controller注解的類負責准備數據模型Map的數據和選擇一個視圖進行渲染。這個模型Map對視圖進行完全的抽象,在使用Thymeleaf的情況下,它將是一個VariablesMap對象(即Thymeleaf模板執行上下文的屬性),使其可以用於模板重點表達式。
Spring中Model的attributes屬性
SpringMVC調用可以在視圖模型的執行過程中訪問的數據,在Thymeleaf中相當於上下文變量。
在SpringMVC中添加一個attributes有幾種不同的方法,下面有一些常見的情況:
給Model的addAttribut方法新增一個attribute
@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屬性添加到model的方法中,Thymeleaf視圖均可用。
在Thymeleaf中,這些model的attributes屬性值均可以使用${attributeName}來訪問,這個attributeName對於Thymeleaf來說就是一個messages,這是一個SpringEL表達式,總之,SpringEL表達式是一種支持在運行時查詢和操作對象圖的語言。
在Thymeleaf中訪問model的Attributes方式如下:
<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>
Request參數
Request參數在Thymeleaf視圖中可以很容易的使用,Request參數一般為從客戶端到服務器傳送參數,如:
https://example.com/query?q=Thymeleaf+Is+Great!
現在假設有一個@Controller控制器,控制器中重定向的方式發送一個request參數:
@Controller
public class SomeController {
@RequestMapping("/")
public String redirect() {
return "redirect:/query?q=Thymeleaf Is Great!";
}
}
訪問參數q可以使用param前綴
<p th:text="${param.q[0]}" th:unless="${param.q == null}">Test</p>
例子中有兩點需要注意的地方:
- ${param.q!=null}檢查set中是否有參數q
- 參數是一個數組,因為它可以多值比如?q=a&r=b
還有一種訪問方式是使用#httpServletRequest對象,可以直接進入javax.servlet.http.HttpServletRequest對象:
<p th:text="${#httpServletRequest.getParameter('q')}" th:unless="${#httpServletRequest.getParameter('q') == null}">Test</p>
Session屬性
比如為session添加了一個mySessionAttribute屬性:
@RequestMapping({"/"})
String index(HttpSession session) {
session.setAttribute("mySessionAttribute", "someValue");
return "index";
}
和Request參數訪問方式類似,這里使用session前綴:
<div th:text="${session.mySessionAttribute}">[...]</div>
同樣的,還可以使用#httpSession方式訪問,它直接進入javax.servlet.http.HttpSession對象。
ServletContext屬性
ServletContext屬性可以再request和session中共享,未來訪問ServletContext屬性,可以使用application前綴:
<table>
<tr>
<td>context中的attribute</td>
<!-- 檢索ServletContext的屬性'myContextAttribute' -->
<td th:text="${application.myContextAttribute}">42</td>
</tr>
<tr>
<td>attributes數量:</td>
<!-- 返回attributes的數量 -->
<td th:text="${application.size()}">42</td>
</tr>
<tr th:each="attr : ${application.keySet()}">
<td th:text="${attr}">javax.servlet.context.tempdir</td>
<td th:text="${application.get(attr)}">/tmp</td>
</tr>
</table>
Spring beans
Thymeleaf可以通過@beanName訪問Spring應用上下午中注冊的bean,如
<div th:text="${@urlService.getApplicationUrl()}">...</div>
在這個例子中,@urlService就是在上下文中注冊的Spring Bean:
@Configuration
public class MyConfiguration {
@Bean(name = "urlService")
public UrlService urlService() {
return new FixedUrlService("somedomain.com/myapp"); // 一個實現
}
}
public interface UrlService {
String getApplicationUrl();
}