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();
}