<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-uri-template</artifactId>
<version>5.2.1</version>
</dependency>
Vert.x URI Template 模板引擎 (vertx-uri-template)
该组件是针对 RFC 6570 URI Template 标准的响应式高性能实现。
完整支持 RFC 6570 规范定义的 Level 4 全部语法。
引入依赖
要在项目中使用该组件,请在构建描述文件中添加以下依赖:
-
Maven(在
pom.xml中):
-
Gradle(在
build.gradle文件中):
compile '''io.vertx:vertx-uri-template:5.2.1'''
创建模板
创建 URI 模板极其简单直观:
UriTemplate template = UriTemplate.of("http://{host}/product/{id}{?sort}");
系统在创建时会对模板合法性进行严格静态校验,任何不合法的模板表达式将在创建时立即抛出异常:
UriTemplate template = UriTemplate.of("{!invalid}}"); // 将抛出解析异常
模板变量展开 (Template Expansion)
调用 expandToString 并传入变量集,即可求值生成规范合法的 URI 字符串:
UriTemplate template = UriTemplate.of("http://{host}/product/{id}{?sort}");
String uri = template.expandToString(Variables
.variables()
.set("host", "localhost")
.set("id", "12345")
.set("sort", "price")
);
Variables 负责承载模板展开所需的键值字典:
-
设置单值普通变量:
variables.set("server", "localhost");
variables.set("port", "8080");
-
设置列表集合变量:
variables.set("ids", Arrays.asList("123", "456"));
-
设置 Map 键值对字典变量:
Map<String, String> query = new HashMap<>();
query.put("firstName", "Dale");
query.put("lastName", "Cooper");
variables.set("query", query);
如前所述,模板中的变量由花括号包围声明(如 {host} 引用变量 host),此展开方式称为 简单字符串展开(Simple String Expansion)。
| 规范还支持其他丰富的 展开风格,它们在格式组织和编码策略上各具特性。 |
列表在展开时默认转换为以逗号分隔的字符串:
UriTemplate template = UriTemplate.of("http://server.com/products?sort={sort}");
Variables variables = Variables.variables().set("sort", Arrays.asList("price", "name"));
assertEquals("http://server.com/products?sort=price,name", template.expandToString(variables));
同样,Map 默认展开为逗号分隔的键值对序列(例如 { "firstName": "Dale", "lastName": "Cooper" } 展开为 "firstName,Dale,lastName,Cooper");但若追加了 * 修饰符(Explode 展开),则会展开为规范的键值对:
UriTemplate template = UriTemplate.of("http://server.com/?details={details*}");
Map<String, String> details = new HashMap<>();
details.put("firstName", "Dale");
details.put("lastName", "Cooper");
Variables variables = Variables.variables().set("details", details);
assertEquals("http://server.com/?firstName=Dale,lastName=Cooper", template.expandToString(variables));
模板字符编码规则
超出 保留字符集 与 非保留字符集 之外的字面量字符将被自动执行 百分号编码(Percent-Encoding):
RFC 6570 展开风格速查表
1. 表单查询参数展开 (Form-Style Query Expansion)
常用于生成带 ? 前缀的 HTTP GET Query 参数。
-
语法:
{?varname} -
允许字符:非保留字符集
| 变量输入 | 模板表达式 | 生成 URI 结果 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2. 表单查询参数延续 (Form-Style Query Continuation)
用于在已有 Query 参数的 URL 末尾继续追加参数(带 & 前缀)。
-
语法:
{&varname} -
允许字符:非保留字符集
| 变量输入 | 模板表达式 | 生成 URI 结果 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3. 保留字符展开 (Reserved Expansion)
允许保留字符(如 /)不被转义,常用于动态拼接完整子路径。
| 变量输入 | 模板表达式 | 生成 URI 结果 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4. 片段标识展开 (Fragment Expansion)
用于生成 URL 锚点 Hash(带 # 前缀)。
| 变量输入 | 模板表达式 | 生成 URI 结果 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5. 点前缀标签展开 (Dot-Prefix Label Expansion)
常用于文件后缀或以 . 隔开的分段命名。
-
语法:
{.varname} -
允许字符:非保留字符集
| 变量输入 | 模板表达式 | 生成 URI 结果 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6. 路径分号参数展开 (Path-Style Parameter Expansion)
常用于 Matrix URI 风格矩阵参数(带 ; 前缀)。
-
语法:
{;varname} -
允许字符:非保留字符集
| 变量输入 | 模板表达式 | 生成 URI 结果 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RFC 字符集对照速查
保留字符集 (Reserved Set)
!*'();:@&=+$,/?#[]
非保留字符集 (Unreserved Set)
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~