Spring RestTemplate getForObject URL 不适用于 Apple iTunes
Spring RestTemplate getForObject URL not working for Apple iTunes
我创建了以下简单测试来查询 iTunes:
@Test
fun loadArtist()
{
val restTemplate = RestTemplate()
val builder = UriComponentsBuilder.fromHttpUrl("https://itunes.apple.com/search")
builder.queryParam("term", "howling wolf")
builder.queryParam("entity", "allArtist")
builder.queryParam("limit", 1)
println("\n\nURL ${builder.toUriString()}")
val result = restTemplate.getForObject(builder.toUriString(), String::class.java);
println("Got artist: $result")
}
并且输出出乎意料:
URL https://itunes.apple.com/search?term=howling%20wolf&entity=allArtist&limit=1
Got artist:
{
"resultCount":0,
"results": []
}
将生成的 URL 粘贴到浏览器中 会产生预期结果 - 艺术家返回。
https://itunes.apple.com/search?term=howling%20wolf&entity=allArtist&limit=1
此外,硬编码查询有效:
val result = restTemplate.getForObject("https://itunes.apple.com/search?term=howling%20wolf&entity=allArtist&limit=1", String::class.java);
。 .该问题似乎只出现在包含空格的 term
查询中。
出了什么问题?除了手动 assemble 和 URL 之外,如何修复?
似乎是对空格进行双重编码的情况。来自 RestTemplate Javadoc:
For each HTTP method there are three variants: two accept a URI
template string and URI variables (array or map) while a third accepts
a URI. Note that for URI templates it is assumed encoding is
necessary, e.g. restTemplate.getForObject("http://example.com/hotel
list") becomes "http://example.com/hotel%20list". This also means if
the URI template or URI variables are already encoded, double encoding
will occur, e.g. http://example.com/hotel%20list becomes
http://example.com/hotel%2520list). To avoid that use a URI method
variant to provide (or re-use) a previously encoded URI. To prepare
such an URI with full control over encoding, consider using
UriComponentsBuilder.
所以看起来 getForObject 实际上会查询 https://itunes.apple.com/search?term=howling%2520wolf&entity=allArtist&limit=1,因此结果为空。您始终可以在您的术语中用“+”替换空格,或者尝试使其中一个空格 类 跳过编码过程。
我创建了以下简单测试来查询 iTunes:
@Test
fun loadArtist()
{
val restTemplate = RestTemplate()
val builder = UriComponentsBuilder.fromHttpUrl("https://itunes.apple.com/search")
builder.queryParam("term", "howling wolf")
builder.queryParam("entity", "allArtist")
builder.queryParam("limit", 1)
println("\n\nURL ${builder.toUriString()}")
val result = restTemplate.getForObject(builder.toUriString(), String::class.java);
println("Got artist: $result")
}
并且输出出乎意料:
URL https://itunes.apple.com/search?term=howling%20wolf&entity=allArtist&limit=1
Got artist:
{
"resultCount":0,
"results": []
}
将生成的 URL 粘贴到浏览器中 会产生预期结果 - 艺术家返回。
https://itunes.apple.com/search?term=howling%20wolf&entity=allArtist&limit=1
此外,硬编码查询有效:
val result = restTemplate.getForObject("https://itunes.apple.com/search?term=howling%20wolf&entity=allArtist&limit=1", String::class.java);
。 .该问题似乎只出现在包含空格的 term
查询中。
出了什么问题?除了手动 assemble 和 URL 之外,如何修复?
似乎是对空格进行双重编码的情况。来自 RestTemplate Javadoc:
For each HTTP method there are three variants: two accept a URI template string and URI variables (array or map) while a third accepts a URI. Note that for URI templates it is assumed encoding is necessary, e.g. restTemplate.getForObject("http://example.com/hotel list") becomes "http://example.com/hotel%20list". This also means if the URI template or URI variables are already encoded, double encoding will occur, e.g. http://example.com/hotel%20list becomes http://example.com/hotel%2520list). To avoid that use a URI method variant to provide (or re-use) a previously encoded URI. To prepare such an URI with full control over encoding, consider using UriComponentsBuilder.
所以看起来 getForObject 实际上会查询 https://itunes.apple.com/search?term=howling%2520wolf&entity=allArtist&limit=1,因此结果为空。您始终可以在您的术语中用“+”替换空格,或者尝试使其中一个空格 类 跳过编码过程。