Apache HTTP Client 和 Spring RestTemplate 的区别 [英] Difference between Apache HTTP Client and Spring RestTemplate

查看:94
本文介绍了Apache HTTP Client 和 Spring RestTemplate 的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在调用 Google Translate API,一个是通过 Apache HTTP Client,另一个是通过 Spring 的 RestTemplate,然后得到不同的结果.两者都在获取完全相同的 URL:

I'm making a call to the Google Translate API, one via Apache HTTP Client and one via Spring's RestTemplate, and getting different results back. Both are GETing exactly the same URL:

我想将Professeur des écoles"从法语翻译成英语.

I want to translate "Professeur des écoles" from French to English.

使用的 URL 是(为了可读性,分成两行):

The URL used is (split onto two lines for sake of readability):

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);
}

返回(正确):

{数据": {翻译":[{"translatedText": "学校老师"}]}}

{ "data": { "translations": [ { "translatedText": "School teacher" } ] } }

@Test
public void spring() {
    RestTemplate template = new RestTemplate();
    String response = template.getForObject(URL, String.class);
    System.out.println(response);
}

返回(错误地):

{数据": {翻译":[{"translatedText": "+% C3% A9coles 教授 +"}]}}

{ "data": { "translations": [ { "translatedText": "Professor + of +% C3% A9coles" } ] } }

我是否遗漏了 RestTemplate HTTP 标头配置中的某些内容?

Am I missing something in RestTemplate HTTP header configuration?

推荐答案

RestTemplate 接受 String URL 的方法执行 URL 编码.

RestTemplate methods that accept a String URL perform URL encoding.

对于每个 HTTP 方法都有三种变体:两种接受一个 URI模板字符串和 URI 变量(数组或映射),而第三个接受一个 URI.请注意,对于 URI 模板,假设编码为必要的,例如restTemplate.getForObject("http://example.com/hotellist") 变为 "http://example.com/hotel%20list".这也意味着如果URI 模板或 URI 变量已经编码,双重编码会发生,例如http://example.com/hotel%20list 变成http://example.com/hotel%2520list).

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 作为第一个参数

Presumably you've provided the following String as the first argument

https://www.googleapis.com/language/translate/v2?key=MY_KEY&source=fr&target=en&q=Professeur+des+%C3%A9coles

必须对字符 % 进行编码.您的 q 参数的值因此变为

The character % must be encoded. Your q parameter's value therefore becomes

Professeur%2Bdes%2B%25C3%25A9coles

如果您解码,相当于

Professeur+des+%C3%A9coles

Google 的翻译服务不知道如何处理 %C3%A9coles.

Google's translation services doesn't know what to do with %C3%A9coles.

正如文档所建议的

为了避免使用 URI 方法变体来提供(或重用)先前编码的 URI.准备这样一个可以完全控制的 URI编码,考虑使用 UriComponentsBuilder.

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 并使用它.

instead of using overloads that accept a String URL, construct a URI yourself and use that.

Apache 的 HttpComponents Fluent API 未指定行为,但似乎字符串值按原样使用.

Apache's HttpComponents Fluent API does not specify the behavior but it seems the String value is taken as is.

这篇关于Apache HTTP Client 和 Spring RestTemplate 的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆