Search code examples
javagoogle-mapsspring-bootencodingasyncresttemplate

AsyncRestTemplate '#' sign encoding in query parameter


I am using AsyncRestTemplate to make an API call to Google Maps from a Springboot 1.5.2 service. Unfortunately, some of my search strings contain a pound/hashtag sign # and are not getting encoded properly in my search parameters. I am using the exchange method.

An example below for address 05406, VT, BURLINGTON, 309 College St #10:

@Service
public class ExampleAsyncRestTemplate {

    private AsyncRestTemplate asyncRestTemplate;

    @Autowired
    public ExampleAsyncRestTemplate() {
        this.asyncRestTemplate = new AsyncRestTemplate();
    }


    public ListenableFuture<ResponseEntity<T>> getGeoCodedAddress() {
         String googleUrl = "https://maps.googleapis.com/maps/api/geocode/json?address=05406, VT, BURLINGTON, 309 College St #10&key=some_key";

         Map<String, String> uriVariables = new HashMap<>();
         uriVariables.put("address", "05406, VT, BURLINGTON, 309 College St #10");
         uriVariables.put("key", "some_key");

         return asyncRestTemplate.exchange(googleUrl, HttpMethod.GET, new HttpEntity<>(), GoogleResponse.class, uriVariables);
    }
}

The resulting URL gets encoded as:

https://maps.googleapis.com/maps/api/geocode/json?address=05406,%20VT,%20BURLINGTON,%20309%20College%20St%20#10&key=some_key

Note that the # is still in the address parameter, when it should be encoded as %23 as per the docs.

Digging into the debugger, seems like the string after the # (10&key=some_key) is being taken as the fragment of the URL. Hence why the # never gets encoded.

Has anybody been able to submit # signs in your query parameters using AsyncRestTemplate?

The only thing I've been able to come up with is replacing # with number, which actually works, but feels hacky/suboptimal.

Thanks for your help.


Solution

  • Note that googleUrl is a template where the encoded params get interpolated into. So you cannot provide the actual parameters as part of the url. You need to change the String into a template like this

    final String googleUrl = "https://maps.googleapis.com/maps/api/geocode/json?address={address}&key={key}";
    

    This returns the correct encoding:

    https://maps.googleapis.com/maps/api/geocode/json?address=05406,%20VT,%20BURLINGTON,%20309%20College%20St%20%2310&key=some_key