Apache HTTP 客户端和 Spring RestTemplate 之间的区别
Difference between Apache HTTP Client and Spring RestTemplate
我正在调用 Google Translate API,一个是通过 Apache HTTP 客户端,另一个是通过 Spring 的 RestTemplate,得到不同的结果。两者的 GETing 完全相同 URL:
我想将 "Professeur des écoles" 从法语翻译成英语。
使用的 URL 是(为了便于阅读分成两行):
private static String URL = "https://www.googleapis.com/language/translate/v2?
key=AIzaSyBNv1lOS...&source=fr&target=en&q=Professeur+des+%C3%A9coles";
阿帕奇:
@Test
public void apache() throws IOException {
String response = Request.Get(URL).execute().returnContent().asString();
System.out.println(response);
}
Returns(正确):
{
"data":{
"translations": [
{
"translatedText": "School teacher"
}
]
}
}
@Test
public void spring() {
RestTemplate template = new RestTemplate();
String response = template.getForObject(URL, String.class);
System.out.println(response);
}
Returns(错误):
{
"data":{
"translations": [
{
"translatedText": "Professor + of +% C3% A9coles"
}
]
}
}
我是否在 RestTemplate HTTP header 配置中遗漏了什么?
RestTemplate
接受 String
URL 的方法执行 URL 编码。
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
).
大概您提供了以下 String
作为第一个参数
https://www.googleapis.com/language/translate/v2?key=MY_KEY&source=fr&target=en&q=Professeur+des+%C3%A9coles
必须对字符 %
进行编码。因此,您的 q
参数值变为
Professeur%2Bdes%2B%25C3%25A9coles
如果您decode,则相当于
Professeur+des+%C3%A9coles
Google 的翻译服务不知道如何处理 %C3%A9coles
。
如文档所示
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
.
与其使用接受 String
URL 的重载,不如自己构建一个 URI 并使用它。
Apache 的 HttpComponents Fluent API 没有指定行为,但字符串值似乎按原样使用。
我正在调用 Google Translate API,一个是通过 Apache HTTP 客户端,另一个是通过 Spring 的 RestTemplate,得到不同的结果。两者的 GETing 完全相同 URL:
我想将 "Professeur des écoles" 从法语翻译成英语。
使用的 URL 是(为了便于阅读分成两行):
private static String URL = "https://www.googleapis.com/language/translate/v2?
key=AIzaSyBNv1lOS...&source=fr&target=en&q=Professeur+des+%C3%A9coles";
阿帕奇:
@Test
public void apache() throws IOException {
String response = Request.Get(URL).execute().returnContent().asString();
System.out.println(response);
}
Returns(正确):
{ "data":{ "translations": [ { "translatedText": "School teacher" } ] } }
@Test
public void spring() {
RestTemplate template = new RestTemplate();
String response = template.getForObject(URL, String.class);
System.out.println(response);
}
Returns(错误):
{ "data":{ "translations": [ { "translatedText": "Professor + of +% C3% A9coles" } ] } }
我是否在 RestTemplate HTTP header 配置中遗漏了什么?
RestTemplate
接受 String
URL 的方法执行 URL 编码。
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
becomeshttp://example.com/hotel%2520list
).
大概您提供了以下 String
作为第一个参数
https://www.googleapis.com/language/translate/v2?key=MY_KEY&source=fr&target=en&q=Professeur+des+%C3%A9coles
必须对字符 %
进行编码。因此,您的 q
参数值变为
Professeur%2Bdes%2B%25C3%25A9coles
如果您decode,则相当于
Professeur+des+%C3%A9coles
Google 的翻译服务不知道如何处理 %C3%A9coles
。
如文档所示
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
.
与其使用接受 String
URL 的重载,不如自己构建一个 URI 并使用它。
Apache 的 HttpComponents Fluent API 没有指定行为,但字符串值似乎按原样使用。