对于最新稳定版本,请使用Spring Framework 7.0.1spring-doc.cadn.net.cn

罗德岛大学链接

本节介绍了春季框架中用于准备URI的各种选项。spring-doc.cadn.net.cn

UriComponents

春季MVC与春季网络流spring-doc.cadn.net.cn

UriComponents构建器帮助从带有变量的URI模板构建URI,如下示例所示:spring-doc.cadn.net.cn

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.

上述例子可以合并为一条链,并缩短为构建并扩展, 如下示例所示:spring-doc.cadn.net.cn

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-doc.cadn.net.cn

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-doc.cadn.net.cn

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")

UriBuilder

春季MVC与春季网络流spring-doc.cadn.net.cn

UriComponents构建器实现UriBuilder.你可以创建一个UriBuilder,反过来,其中UriBuilder工厂.一起UriBuilder工厂UriBuilder提供一种可插拔的机制,可以基于 URI 模板构建 URI,基于 共享配置,如基础URL、编码偏好及其他细节。spring-doc.cadn.net.cn

你可以配置Rest模板Web客户端其中UriBuilder工厂以定制上呼吸道的准备方式。默认UriBuilderFactory是默认值 实现UriBuilder工厂UriComponents构建器内部和 会暴露共享配置选项。spring-doc.cadn.net.cn

以下示例展示了如何配置Rest模板:spring-doc.cadn.net.cn

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

以下示例配置为Web客户端:spring-doc.cadn.net.cn

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

此外,你也可以使用默认UriBuilderFactory径直。它类似于使用UriComponents构建器但它不是静态工厂方法,而是实际实例 它包含配置和偏好,如下示例所示:spring-doc.cadn.net.cn

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 编码

春季MVC与春季网络流spring-doc.cadn.net.cn

UriComponents构建器在两个层级上展示了编码选项:spring-doc.cadn.net.cn

这两种方式都用逃逸八位元组替换非ASCII和非法字符。然而,第一种选择 还替换了URI变量中带有保留意义的字符。spring-doc.cadn.net.cn

考虑“;”,在路径上是合法的,但保留了含义。第一种选项取代 “;”,URI变量中包含“%3B”,但URI模板中没有。相比之下,第二种选择永远不会 替换“;”,因为它是路径中的法定字符。

在大多数情况下,第一种选择很可能能达到预期结果,因为它治疗的是上呼吸道 变量作为不透明数据以实现完整编码,而第二个选项在 URI 时非常有用 变量确实有意包含保留字符。第二个选项也很有用 当完全不展开URI变量时,因为那也会编码任何 顺便说一句,看起来像是URI变量。spring-doc.cadn.net.cn

以下示例使用了第一个选项:spring-doc.cadn.net.cn

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-doc.cadn.net.cn

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-doc.cadn.net.cn

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")

Web客户端以及Rest模板通过内部展开和编码URI模板 这UriBuilder工厂策略。两者都可以自定义策略配置, 如下示例所示:spring-doc.cadn.net.cn

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

默认UriBuilderFactory实现用途UriComponents构建器内部 变为 展开并编码URI模板。作为工厂,它提供了一个单一的配置空间 基于以下编码模式之一的编码方法:spring-doc.cadn.net.cn

  • TEMPLATE_AND_VALUES:使用UriComponentsBuilder#encode(),对应于 前面列表中的第一个选项,预编码URI模板并严格编码URI变量,当 扩大。spring-doc.cadn.net.cn

  • VALUES_ONLY不编码URI模板,而是采用严格编码 通过URI变量UriUtils#encodeUriVariables在将其扩展为 模板。spring-doc.cadn.net.cn

  • URI_COMPONENT:使用UriComponents#encode(),对应于前述列表中的第二个选项,为 在展开URI变量编码URI组件值。spring-doc.cadn.net.cn

  • 没有:不使用编码。spring-doc.cadn.net.cn

Rest模板设置为EncodingMode.URI_COMPONENT历史 原因以及向后兼容。这Web客户端依赖于默认值 在默认UriBuilderFactory,该名称被更改为EncodingMode.URI_COMPONENT在 5.0.x 到EncodingMode.TEMPLATE_AND_VALUES在5.1版本中。spring-doc.cadn.net.cn