Wednesday, January 23, 2013

Spring & RestTemplate: Dealing with Double Escaped Entities

We've been using Spring's RestTemplate pretty extensively to perform various operations. Several have escaped entities in the query. For example, one query requires its parameters be surrounded by quotes:

http://myhost.com/records?query=no+"1"+owner="John"

We could inject that URL into a bean containing a RestTemplate instance, representing the URL with a String and escaping the quotes with %22 to make the parsing of the bean file easier:

    <bean id="recordUrl" class="java.lang.String">
        <constructor-arg value="http://myhost.com/records?query=no+%221%22+owner=%22John%22"/>
    </bean>

Then executing the query:

  restTemplate.getForObject(recordUrl, String.class, urlVariables)

However, our query would not work as each %22 would be escaped again as %2522. For example:

  DEBUG main org.springframework.web.client.RestTemplate - Created GET request for: "http://myhost.com/records?query=no+%25221%2522+owner=%2522John%2522"

How do we avoid the double escaping?. The RestTemplate Javadoc contains the answer. To avoid the double-escaping, we need to use the version of the RestTemplate method that takes a java.net.URI as the first parameters instead of a String representing the URL:

  restTemplate.getForObject(new URI(recordUrl), String.class, urlVariables)

Or instead of creating a URI, inject an instance of one like what was done with the String originally.

3 comments:

  1. Thanks for this tip, it helped me solve a similar problem, where a request param contained an ampersand (&) character. Escaping the param did not fix the issue, as RestTemplate appeared to be unescaping before performing the GET. Escaping the param and also using "new URI()" solved the issue.

    ReplyDelete
  2. You saved my life too. Thanks.

    ReplyDelete