| 此版本仍在开发中,尚未被视为稳定版本。最新的稳定版本请使用 Spring Framework 6.1.13! | 
| 此版本仍在开发中,尚未被视为稳定版本。最新的稳定版本请使用 Spring Framework 6.1.13! | 
本节描述了 Spring Framework 中可用于准备 URI 的各种选项。
UriComponents
Spring MVC 和 Spring WebFlux
UriComponentsBuilder有助于使用变量从 URI 模板构建 URI,如下例所示:
- 
Java 
- 
Kotlin 
UriComponents uriComponents = UriComponentsBuilder
		.fromUriString("https://example.com/hotels/{hotel}") (1)
		.queryParam("q", "{q}") (2)
		.encode() (3)
		.build(); (4)
URI uri = uriComponents.expand("Westin", "123").toUri(); (5)| 1 | 具有 URI 模板的静态工厂方法。 | 
| 2 | 添加或替换 URI 组件。 | 
| 3 | 请求对 URI 模板和 URI 变量进行编码。 | 
| 4 | 构建一个 . UriComponents | 
| 5 | 展开变量并获取 . URI | 
val uriComponents = UriComponentsBuilder
		.fromUriString("https://example.com/hotels/{hotel}") (1)
		.queryParam("q", "{q}") (2)
		.encode() (3)
		.build() (4)
val uri = uriComponents.expand("Westin", "123").toUri() (5)| 1 | 具有 URI 模板的静态工厂方法。 | 
| 2 | 添加或替换 URI 组件。 | 
| 3 | 请求对 URI 模板和 URI 变量进行编码。 | 
| 4 | 构建一个 . UriComponents | 
| 5 | 展开变量并获取 . URI | 
前面的示例可以合并为一个链,并用 ,
如下例所示:buildAndExpand
- 
Java 
- 
Kotlin 
URI uri = UriComponentsBuilder
		.fromUriString("https://example.com/hotels/{hotel}")
		.queryParam("q", "{q}")
		.encode()
		.buildAndExpand("Westin", "123")
		.toUri();val uri = UriComponentsBuilder
		.fromUriString("https://example.com/hotels/{hotel}")
		.queryParam("q", "{q}")
		.encode()
		.buildAndExpand("Westin", "123")
		.toUri()您可以通过直接转到 URI(这意味着编码)来进一步缩短它, 如下例所示:
- 
Java 
- 
Kotlin 
URI uri = UriComponentsBuilder
		.fromUriString("https://example.com/hotels/{hotel}")
		.queryParam("q", "{q}")
		.build("Westin", "123");val uri = UriComponentsBuilder
		.fromUriString("https://example.com/hotels/{hotel}")
		.queryParam("q", "{q}")
		.build("Westin", "123")您可以使用完整的 URI 模板进一步缩短它,如下例所示:
- 
Java 
- 
Kotlin 
URI uri = UriComponentsBuilder
		.fromUriString("https://example.com/hotels/{hotel}?q={q}")
		.build("Westin", "123");val uri = UriComponentsBuilder
		.fromUriString("https://example.com/hotels/{hotel}?q={q}")
		.build("Westin", "123")| 1 | 具有 URI 模板的静态工厂方法。 | 
| 2 | 添加或替换 URI 组件。 | 
| 3 | 请求对 URI 模板和 URI 变量进行编码。 | 
| 4 | 构建一个 . UriComponents | 
| 5 | 展开变量并获取 . URI | 
| 1 | 具有 URI 模板的静态工厂方法。 | 
| 2 | 添加或替换 URI 组件。 | 
| 3 | 请求对 URI 模板和 URI 变量进行编码。 | 
| 4 | 构建一个 . UriComponents | 
| 5 | 展开变量并获取 . URI | 
Uri生成器
Spring MVC 和 Spring WebFlux
UriComponentsBuilder 实现 .您可以依次使用 .一起提供一种可插入的机制,以基于
共享配置,例如基本 URL、编码首选项和其他详细信息。UriBuilderUriBuilderUriBuilderFactoryUriBuilderFactoryUriBuilder
您可以配置 和 来自定义 URI 的准备。 是默认值
实现 that uses internal,
公开共享配置选项。RestTemplateWebClientUriBuilderFactoryDefaultUriBuilderFactoryUriBuilderFactoryUriComponentsBuilder
以下示例显示如何配置 :RestTemplate
- 
Java 
- 
Kotlin 
// import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode;
String baseUrl = "https://example.org";
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);
factory.setEncodingMode(EncodingMode.TEMPLATE_AND_VALUES);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(factory);// import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode
val baseUrl = "https://example.org"
val factory = DefaultUriBuilderFactory(baseUrl)
factory.encodingMode = EncodingMode.TEMPLATE_AND_VALUES
val restTemplate = RestTemplate()
restTemplate.uriTemplateHandler = factory以下示例配置了一个 :WebClient
- 
Java 
- 
Kotlin 
// import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode;
String baseUrl = "https://example.org";
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);
factory.setEncodingMode(EncodingMode.TEMPLATE_AND_VALUES);
WebClient client = WebClient.builder().uriBuilderFactory(factory).build();// import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode
val baseUrl = "https://example.org"
val factory = DefaultUriBuilderFactory(baseUrl)
factory.encodingMode = EncodingMode.TEMPLATE_AND_VALUES
val client = WebClient.builder().uriBuilderFactory(factory).build()此外,您也可以直接使用。它类似于 using ,但它不是静态工厂方法,而是一个实际的实例
,其中包含 configuration 和 preferences,如下例所示:DefaultUriBuilderFactoryUriComponentsBuilder
- 
Java 
- 
Kotlin 
String baseUrl = "https://example.com";
DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory(baseUrl);
URI uri = uriBuilderFactory.uriString("/hotels/{hotel}")
		.queryParam("q", "{q}")
		.build("Westin", "123");val baseUrl = "https://example.com"
val uriBuilderFactory = DefaultUriBuilderFactory(baseUrl)
val uri = uriBuilderFactory.uriString("/hotels/{hotel}")
		.queryParam("q", "{q}")
		.build("Westin", "123")URI 编码
Spring MVC 和 Spring WebFlux
UriComponentsBuilder在两个级别公开编码选项:
- 
UriComponentsBuilder#encode() 中: 首先对 URI 模板进行预编码,然后在展开时对 URI 变量进行严格编码。 
- 
UriComponents#encode() 中: 在 URI 变量展开后对 URI 组件进行编码。 
这两个选项都用转义的八位字节替换非 ASCII 字符和非法字符。但是,第一个选项 还会替换 URI 变量中出现的具有保留含义的字符。
| 请考虑 “;”,它在 path 中是合法的,但具有保留的含义。第一个选项将 “;” 在 URI 变量中带有 “%3B”,但在 URI 模板中没有。相比之下,第二个选项永远不会 替换 “;”,因为它是路径中的合法字符。 | 
在大多数情况下,第一个选项可能会给出预期的结果,因为它将 URI 变量作为不透明数据进行完全编码,而第二个选项在 URI 变量确实有意包含保留字符。第二个选项也很有用 当根本不扩展 URI 变量时,因为这也将编码任何 顺便说一句,看起来像一个 URI 变量。
以下示例使用第一个选项:
- 
Java 
- 
Kotlin 
URI uri = UriComponentsBuilder.fromPath("/hotel list/{city}")
		.queryParam("q", "{q}")
		.encode()
		.buildAndExpand("New York", "foo+bar")
		.toUri();
// Result is "/hotel%20list/New%20York?q=foo%2Bbar"val uri = UriComponentsBuilder.fromPath("/hotel list/{city}")
		.queryParam("q", "{q}")
		.encode()
		.buildAndExpand("New York", "foo+bar")
		.toUri()
// Result is "/hotel%20list/New%20York?q=foo%2Bbar"您可以通过直接转到 URI(这意味着编码)来缩短前面的示例, 如下例所示:
- 
Java 
- 
Kotlin 
URI uri = UriComponentsBuilder.fromPath("/hotel list/{city}")
		.queryParam("q", "{q}")
		.build("New York", "foo+bar");val uri = UriComponentsBuilder.fromPath("/hotel list/{city}")
		.queryParam("q", "{q}")
		.build("New York", "foo+bar")您可以使用完整的 URI 模板进一步缩短它,如下例所示:
- 
Java 
- 
Kotlin 
URI uri = UriComponentsBuilder.fromUriString("/hotel list/{city}?q={q}")
		.build("New York", "foo+bar");val uri = UriComponentsBuilder.fromUriString("/hotel list/{city}?q={q}")
		.build("New York", "foo+bar")和 扩展和编码 URI 模板在 内部通过
策略。两者都可以使用自定义策略
如下例所示:WebClientRestTemplateUriBuilderFactory
- 
Java 
- 
Kotlin 
String baseUrl = "https://example.com";
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl)
factory.setEncodingMode(EncodingMode.TEMPLATE_AND_VALUES);
// Customize the RestTemplate..
RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(factory);
// Customize the WebClient..
WebClient client = WebClient.builder().uriBuilderFactory(factory).build();val baseUrl = "https://example.com"
val factory = DefaultUriBuilderFactory(baseUrl).apply {
	encodingMode = EncodingMode.TEMPLATE_AND_VALUES
}
// Customize the RestTemplate..
val restTemplate = RestTemplate().apply {
	uriTemplateHandler = factory
}
// Customize the WebClient..
val client = WebClient.builder().uriBuilderFactory(factory).build()该实现在内部使用
展开并编码 URI 模板。作为工厂,它提供了一个配置位置
编码方法,基于以下编码模式之一:DefaultUriBuilderFactoryUriComponentsBuilder
- 
TEMPLATE_AND_VALUES: 使用 ,对应于 前面列表中的第一个选项,用于预编码 URI 模板并在 扩大。UriComponentsBuilder#encode()
- 
VALUES_ONLY:不对 URI 模板进行编码,而是应用严格编码 到 URI 变量中,然后再将它们扩展到 模板。UriUtils#encodeUriVariables
- 
URI_COMPONENT:使用对应于前面列表中的第二个选项的 ,以 在 URI 变量展开后对 URI 组件值进行编码。UriComponents#encode()
- 
NONE:不应用编码。
设置为 historical
原因和向后兼容性。依赖于默认值
in ,该 URL 已从 in 更改
5.0.x 复制到 5.1 中。RestTemplateEncodingMode.URI_COMPONENTWebClientDefaultUriBuilderFactoryEncodingMode.URI_COMPONENTEncodingMode.TEMPLATE_AND_VALUES
| 请考虑 “;”,它在 path 中是合法的,但具有保留的含义。第一个选项将 “;” 在 URI 变量中带有 “%3B”,但在 URI 模板中没有。相比之下,第二个选项永远不会 替换 “;”,因为它是路径中的合法字符。 |