此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.1.10Spring中文文档

此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.1.10Spring中文文档

本节介绍 Spring Framework 中可用于准备 URI 的各种选项。Spring中文文档

UriComponents

Spring MVC 和 Spring WebFluxSpring中文文档

UriComponentsBuilder帮助从具有变量的 URI 模板生成 URI,如以下示例所示:Spring中文文档

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

前面的例子可以合并成一个链,并用 缩短为 , 如以下示例所示:buildAndExpandSpring中文文档

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(这意味着编码)来进一步缩短它, 如以下示例所示:Spring中文文档

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 模板进一步缩短它,如以下示例所示:Spring中文文档

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

UriBuilder的

Spring MVC 和 Spring WebFluxSpring中文文档

UriComponentsBuilder 实现 。您可以依次创建一个 ,并带有 .一起,并提供一种可插入机制,以基于 URI 模板构建 URI 共享配置,例如基本 URL、编码首选项和其他详细信息。UriBuilderUriBuilderUriBuilderFactoryUriBuilderFactoryUriBuilderSpring中文文档

您可以配置 和 来自定义 URI 的准备。 是默认值 在内部使用和 公开共享配置选项。RestTemplateWebClientUriBuilderFactoryDefaultUriBuilderFactoryUriBuilderFactoryUriComponentsBuilderSpring中文文档

以下示例演示如何配置:RestTemplateSpring中文文档

// 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

以下示例配置:WebClientSpring中文文档

// 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()

此外,您也可以直接使用。它类似于 use,但它不是静态工厂方法,而是一个实际实例 它包含配置和首选项,如以下示例所示:DefaultUriBuilderFactoryUriComponentsBuilderSpring中文文档

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 WebFluxSpring中文文档

UriComponentsBuilder在两个级别公开编码选项:Spring中文文档

这两个选项都将非 ASCII 和非法字符替换为转义八位字节。但是,第一种选择 还会替换 URI 变量中显示的具有保留含义的字符。Spring中文文档

考虑“;”,它在路径中是合法的,但具有保留的含义。第一个选项将 “;” 在 URI 变量中带有“%3B”,但在 URI 模板中则不然。相比之下,第二种选择永远不会 替换“;”,因为它是路径中的合法字符。

在大多数情况下,第一个选项可能会给出预期的结果,因为它处理 URI 变量作为要完全编码的不透明数据,而第二个选项在 URI 时很有用 变量确实有意包含保留字符。第二个选项也很有用 当根本不扩展 URI 变量时,因为这也将编码任何 顺便说一句,看起来像一个 URI 变量。Spring中文文档

下面的示例使用第一个选项:Spring中文文档

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(这意味着编码)来缩短前面的示例, 如以下示例所示:Spring中文文档

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 模板进一步缩短它,如以下示例所示:Spring中文文档

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 模板内部通过 策略。两者都可以使用自定义策略进行配置, 如以下示例所示:WebClientRestTemplateUriBuilderFactorySpring中文文档

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 模板。作为工厂,它提供了一个单一的配置位置 基于以下编码模式之一的编码方法:DefaultUriBuilderFactoryUriComponentsBuilderSpring中文文档

  • TEMPLATE_AND_VALUES:用途,对应于 前面列表中的第一个选项,用于对 URI 模板进行预编码,并在以下情况下严格编码 URI 变量 扩大。UriComponentsBuilder#encode()Spring中文文档

  • VALUES_ONLY:不对 URI 模板进行编码,而是应用严格的编码 到 URI 变量,然后将它们扩展到 模板。UriUtils#encodeUriVariablesSpring中文文档

  • URI_COMPONENT:使用对应于前面列表中的第二个选项的 在 URI 变量展开对 URI 组件值进行编码。UriComponents#encode()Spring中文文档

  • NONE:不应用编码。Spring中文文档

设置为历史 原因和向后兼容性。依赖于默认值 in ,从 in 更改而来 5.0.x 到 5.1 中。RestTemplateEncodingMode.URI_COMPONENTWebClientDefaultUriBuilderFactoryEncodingMode.URI_COMPONENTEncodingMode.TEMPLATE_AND_VALUESSpring中文文档

考虑“;”,它在路径中是合法的,但具有保留的含义。第一个选项将 “;” 在 URI 变量中带有“%3B”,但在 URI 模板中则不然。相比之下,第二种选择永远不会 替换“;”,因为它是路径中的合法字符。