# 4.4 链接URL

在网络应用模版里，因为其重要性，URL也是一等公民。Thymeleaf标准方言为它们提供了`@`语法：`@{...}`

URL有不同的类型：

* 绝对URL: `http://www.thymeleaf.org`
* 相对URL，可以是：
  * 相对于网页： `user/login.html`
  * 相对于上下文： `/itemdetails?id=3` （服务器上上下文的名字会被自动添加）
  * 相对于服务器： `~/billing/processInvoice` （允许在另一个上下文里调用URL（= application），在同一个服务器上
  * 相对于协议的URL： `//code.jquery.com/jquery-2.0.3.min.js`

对这些表达式以及将它们转换成实际URL的处理，是通过实现`org.thymeleaf.linkbuilder.ILinkBuilder`接口实现的。它会被注册到正在使用的`ITemplateEngine`对象。

默认的，这个接口的单个实现，会注册在`org.thymeleaf.linkbuilder.StandardLinkBuilder`类。对于离线（无网）或是基于Servlet API的网络场景，这都足够了。另外的场景（比如整合无ServletAPI的网络框架）可能需要这个链接构建器接口的特定实现。

让我们使用这个新语法。遇到`th:href`属性：

```markup
<!-- Will produce 'http://localhost:8080/gtvg/order/details?orderId=3' (plus rewriting) -->
<a href="details.html" 
   th:href="@{http://localhost:8080/gtvg/order/details(orderId=${o.id})}">view</a>

<!-- Will produce '/gtvg/order/details?orderId=3' (plus rewriting) -->
<a href="details.html" th:href="@{/order/details(orderId=${o.id})}">view</a>

<!-- Will produce '/gtvg/order/3/details' (plus rewriting) -->
<a href="details.html" th:href="@{/order/{orderId}/details(orderId=${o.id})}">view</a>
```

这里有一些需要注意的地方：

* `th:href`是一个修饰符属性：一旦被处理，它将会计算链接URL，并把值设置到`<a>`标签的`href`属性。
* 我们被允许为URL参数使用表达式（如你所见，`orderId=${o.id}`）。需要的URL参数编码操作也会自动执行。
* 如果需要多个参数，它们会被逗号分隔：`@{/order/process(execId=${execId},execType='FAST')}`
* 变量模版也允许出现在URL路径上：@{/order/{orderId}/details(orderId=${orderId})}
* 以`/`开头（例如：`/order/details`）的相对URL会自动加上应用上下文名字作为前缀。
* 如果没有启用cookie或者还不知道有没有启用，那么后缀`";jsessionid=..."`会加到相对URL上，这样就保存了会话。这称为URL重写。Thymeleaf允许你为每一个URL使用来自于Servlet API的`response.encodeURL(...)`机制，插入你自己的重写的过滤器。
* `th:href`属性允许在我们的模版里，（可选的）有一个正在工作的静态`href`属性。这样，当为了查看设计直接打开时，我们的模版链接仍旧可以被浏览器正确导航。

就像信息语法（`#{...}`），URL也可以是求值另一个表达式的结果：

```markup
<a th:href="@{${url}(orderId=${o.id})}">view</a>
<a th:href="@{'/details/'+${user.login}(orderId=${o.id})}">view</a>
```
