标准 URL 语法
Thymeleaf标准方言——被称为标准和SpringStandard——提供了一种简便的方式在您的Web应用中创建URL,使其包含任何所需的URL准备元素。这是通过所谓的链接表达式来实现的,这是一种Thymeleaf标准表达式: @{...}
绝对URL
绝对URL允许您创建指向其他服务器的链接。它们以指定协议名称开头(http://
或https://
)
<a th:href="@{http://www.thymeleaf/documentation.html}">
它们完全不会被修改(除非您有URL重写过滤器在服务器上配置并执行HttpServletResponse.encodeUrl(...)
方法中的修改):
<a href="http://www.thymeleaf/documentation.html">
上下文相对URL
最常用的URL类型是上下文相对类型。这些URL是指部署到服务器上后应相对于Web应用程序根目录的URL。例如,如果我们把一个myapp.war
文件部署进Tomcat服务器,我们的应用可能可以通过http://localhost:8080/myapp
访问,并且myapp
将成为上下文名称.
上下文相对URL以/
:
<a th:href="@{/order/list}">
开头。如果我们的应用安装在http://localhost:8080/myapp
,该URL将输出:
<a href="/myapp/order/list">
服务器相对URL
服务器相对URL与上下文相对URL非常相似,不同之处在于它们不假定您希望您的URL连接到您应用程序上下文内的资源,因此允许您链接到同一服务器中的不同上下文:
<a th:href="@{~/billing-app/showDetails.htm}">
当前应用的上下文将被忽略,因此尽管我们的应用部署在http://localhost:8080/myapp
,该URL将输出:
<a href="/billing-app/showDetails.htm">
协议相对URL
协议相对URL实际上是绝对URL,它们将保留用于显示当前页面的协议(HTTP、HTTPS)。通常用于包含外部资源如样式表、脚本等:
<script th:src="@{//scriptserver.example.net/myscript.js}">...</script>
……将无修改地渲染(除了URL重写),例如:
<script src="//scriptserver.example.net/myscript.js">...</script>
添加参数
我们如何使用@{...}
表达式创建的URL添加参数?很简单:
<a th:href="@{/order/details(id=3)}">
输出如下:
<a href="/order/details?id=3">
您可以添加多个参数,用逗号分隔:
<a th:href="@{/order/details(id=3,action='show_all')}">
输出如下:
<!-- Note ampersands (&) should be HTML-escaped in tag attributes... -->
<a href="/order/details?id=3&action=show_all">
您也可以以路径变量的形式包含参数,类似于普通参数,但在URL路径中指定占位符:
<a th:href="@{/order/{id}/details(id=3,action='show_all')}">
输出如下:
<a href="/order/3/details?action=show_all">
URL片段标识符
片段标识符可以包含在URL中,不论是带有还是不带参数的。它们总是会包含在URL的基础部分中,所以:
<a th:href="@{/home#all_info(action='show')}">
……将输出为:
<a href="/home?action=show#all_info">
URL重写
Thymeleaf允许您在应用中配置URL重写过滤器,它通过调用Servlet API中response.encodeURL(...)
方法javax.servlet.http.HttpServletResponse
类来处理每个由Thymeleaf模板生成的URL。
这是Java Web应用中支持URL重写操作的标准方式,允许URL进行以下操作:
- 自动检测用户是否启用了Cookie,如果没有启用(或者如果是第一次请求且Cookie配置仍未知)则向URL添加
;jsessionid=...
片段。 - 在需要时自动对URL应用代理配置。
- 如果配置了的话,还可以利用不同的CDN(内容分发网络)设置,以便链接到分布在多个服务器上的内容。
一种非常常见(并且推荐)的URL重写技术是URLRewriteFilter.
仅限于th:href属性吗?
不要认为URL@{...}
表达式只用于th:href
属性中。实际上,它们可以在任意位置使用,任何地方都可以,就像变量表达式(${...}
)或消息外化/国际化表达式(#{...}
)。
例如,您可以将其用在表单中……
<form th:action="@{/order/processOrder}">
……或者作为其他表达式的一部分。这里它是外部化/国际化的字符串的一个参数:
<p th:text="#{orders.explanation('3', @{/order/details(id=3,action='show_all')})}">
在URL中使用表达式
如果我们需要编写像这样的URL表达式:
<a th:href="@{/order/details(id=3,action='show_all')}">
……但3
和'show_all'
都不能是字面量,因为我们只在运行时才知道它们的值怎么办?
没问题!每个URL参数值实际上都是一个表达式,因此您可以轻松地将字面量替换为任何其他表达式,包括i18n、条件判断等:
<a th:href="@{/order/details(id=${order.id},action=(${user.admin} ? 'show_all' : 'show_public'))}">
更进一步地说,像这样的URL表达式:
<a th:href="@{/order/details(id=${order.id})}">
……实际上是下列表达式的简写形式:
<a th:href="@{'/order/details'(id=${order.id})}">
意味着URL本身也可通过表达式来指定,例如一个变量表达式:
<a th:href="@{${detailsURL}(id=${order.id})}">
……或者一个外部化/国际化的文本:
<a th:href="@{#{orders.details.localized_url}(id=${order.id})}">
……甚至可以使用复杂的表达式,比如条件判断:
<a th:href="@{(${user.admin}? '/admin/home' : ${user.homeUrl})(id=${order.id})}">
想让它更整洁些?使用th:with
:
<a th:with="baseUrl=(${user.admin}? '/admin/home' : ${user.homeUrl})"
th:href="@{${baseUrl}(id=${order.id})}">
……或者…
<div th:with="baseUrl=(${user.admin}? '/admin/home' : ${user.homeUrl})">
...
<a th:href="@{${baseUrl}(id=${order.id})}">...</a>
...
</div>