+
作为查询参数进行url编码。该API的文档说明如下:
日期必须采用W3C格式,例如'2016-10-24T13:33:23+02:00'。
目前为止还好,所以我使用以下代码(最小化)来生成URL:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssX");
ZonedDateTime dateTime = ZonedDateTime.now().minusDays(1);
String formated = dateTime.format(formatter);
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(baseUrl);
uriComponentsBuilder.queryParam("update", formated);
uriComponentsBuilder.build();
String url = uriComponentsBuilder.toUriString();
未编码的查询将如下所示:
https://example.com?update=2017-01-05T12:40:44+01
编码后的字符串结果为:
https://example.com?update=2017-01-05T12:40:44%2B01
在我的看法中,这是一个正确编码的查询字符串。请注意,在查询字符串末尾,+01
中的 +
被替换为 %2B
。
然而,当我使用编码后的 URL 向 API 发送请求时,我收到一个错误,说请求无法处理。
但是,如果在发送请求之前将 %2B
替换为 +
,则可以正常工作:
url.replaceAll("%2B", "+");
据我理解,
+
符号是用来替代空格的。所以经过解码后服务器真正接收到的URL应该是:https://example.com?update=2017-01-05T12:40:44 01
我的假设是否正确?
除了联系API所有者以使用正确编码的查询(而不是奇怪的非标准字符串替换),还有其他我可以做的事情吗?
更新:
根据规范RFC 3986(第3.4节),查询参数中的+
符号不需要编码。
根据stackoverflow上的这个答案,Spring的UriComponentBuilder使用了这个规范,但实际上并没有完全遵循。那么一个新的问题就出现了,如何让UriComponentBuilder遵循规范?3.4. Query
The query component contains non-hierarchical data that, along with data in the path component (Section 3.3), serves to identify a
resource within the scope of the URI's scheme and naming authority
(if any). The query component is indicated by the first question
mark ("?") character and terminated by a number sign ("#") character
or by the end of the URI.Berners-Lee, et al. Standards Track [Page 23] RFC 3986 URI Generic Syntax
January 2005query = *( pchar / "/" / "?" )
The characters slash ("/") and question mark ("?") may represent data within the query component. Beware that some older, erroneous implementations may not handle such data correctly when it is used as the base URI for relative references (Section 5.1), apparently
because they fail to distinguish query data from path data when
looking for hierarchical separators. However, as query components
are often used to carry identifying information in the form of
"key=value" pairs and one frequently used value is a reference to
another URI, it is sometimes better for usability to avoid percent-
encoding those characters.