我创建了以下简单测试来查询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": []
}
将生成的网址粘贴到浏览器中 会给出预期的结果 - 艺术家返回。
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
查询中。
出了什么问题?除了手工组装URL,如何修复?
答案 0 :(得分:1)
似乎是对空格进行双重编码的情况。来自RestTemplate Javadoc:
对于每个HTTP方法,有三种变体:两种接受URI 模板字符串和URI变量(数组或映射),而第三个接受 一个URI。请注意,对于URI模板,假设编码为 必要的,例如restTemplate.getForObject(" http://example.com/hotel list")成为" http://example.com/hotel%20list"。这也意味着 URI模板或URI变量已经编码,双重编码 会发生,例如http://example.com/hotel%20list变成了 http://example.com/hotel%2520list)。为了避免使用URI方法 用于提供(或重用)先前编码的URI的变体。准备 这样一个完全控制编码的URI,考虑使用 UriComponentsBuilder。
因此看起来getForObject实际上会查询https://itunes.apple.com/search?term=howling%2520wolf&entity=allArtist&limit=1,从而导致结果为空。你总是可以用" +"替换空格。在您的术语中或尝试使其中一个类跳过编码过程。