Kong
Kong

Reputation: 9596

Difference between Apache HTTP Client and Spring RestTemplate

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:

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

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";

Apache:

@Test
public void apache() throws IOException {
    String response = Request.Get(URL).execute().returnContent().asString();
    System.out.println(response);
}

Returns (correctely):

{ "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 (incorrectely):

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

Am I missing something in RestTemplate HTTP header configuration?

Upvotes: 2

Views: 7984

Answers (1)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 280178

RestTemplate methods that accept a String URL perform URL encoding.

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).

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

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

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

which, if you decode, is equivalent to

Professeur+des+%C3%A9coles

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

As the documentation suggests

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.

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


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

Upvotes: 7

Related Questions