Thymeleaf

Spring MVC 和 Thymeleaf:如何从模板访问数据

在典型的 Spring MVC 应用程序中,@Controller类负责准备包含数据的模型映射并选择要渲染的视图。这模型映射允许对视图技术进行完全抽象,并且在 Thymeleaf 的情况下,它会被转换为一个 Thymeleaf 上下文对象(属于 Thymeleaf模板执行上下文),使得所有定义的变量都可供模板中执行的表达式使用。

Spring 模型属性

Spring MVC 将在视图执行期间可以访问的数据称为模型属性。Thymeleaf 中的等效术语是上下文变量.

存在多种方式可以将模型属性添加到 Spring MVC 中的视图中。以下是一些常见情况:

通过其ModeladdAttribute方法添加属性:

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

这在某些场景下非常简便且实用。

参考资料

无噪 Logo
无噪文档
中文文档 · 复刻官网
查看所有 ↗