Spring Framework
  1. Spring Framework
  2. SPR-9220

RestTemplate support for URL elements that can contain { } characters

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Works as Designed
    • Affects Version/s: 3.1.1
    • Fix Version/s: None
    • Component/s: Web
    • Labels:

      Description

      The following issue was observed when working with Apache Solr, which has a query function syntax of query parameter values declared within bracket {} delimiters. For example:

      http://localhost:8983/solr/select?wt=json&indent=true&fl=*&q=*:*&fq=

      {!geofilt}

      &sfield=venue_location&pt=28.0674,-80.5595&d=25.

      Calling restTemplate.getForObject(String, Class<T>) and manually escaping

      { and }

      with %7B and %7D doesn't work because the escaping gets applied twice. Leaving the { } characters as-is doesn't work as the parameter value is treated as a URI variable.

      Present workaround seems to construct a URI instead of passing in a url String. Wanted to submit this issue for documentation and see if it's possible to add enhanced support for cases like this.

        Activity

        Hide
        Keith Donald added a comment -

        Working example here: https://gist.github.com/2012289.

        If you review the code you see there are a couple of other opportunities for simplification:

        • addSupportedMediaType(MediaType) on AbstractHttpMessageConverter
        • addMessageConverter(HttpMessageConverter) on RestTemplate
        Show
        Keith Donald added a comment - Working example here: https://gist.github.com/2012289 . If you review the code you see there are a couple of other opportunities for simplification: addSupportedMediaType(MediaType) on AbstractHttpMessageConverter addMessageConverter(HttpMessageConverter) on RestTemplate
        Hide
        Chris Beams added a comment -

        Assigned to Rossen; Arjen added as watcher for any comments.

        Show
        Chris Beams added a comment - Assigned to Rossen; Arjen added as watcher for any comments.
        Hide
        Rossen Stoyanchev added a comment - - edited

        The URI-based RestTemplate methods are there as an alternative to the URI-template syntax. They would be appropriate for the given example. However, constructing a URI is not always very convenient. The UriComponentsBuilder provides a way to construct the URI and encode it with various options.

        Here is one example that starts with a complete URI string:

        String url = "http://localhost:8983/solr/select?wt=json&indent=true&fl=*&q=*:*&fq={!geofilt}&sfield=venue_location&pt=28.0674,-80.5595&d=25";
        URI uri = UriComponentsBuilder.fromUriString(url).build().encode().toUri();
        
        System.out.println(uri);
        // http://localhost:8983/solr/select?wt=json&indent=true&fl=*&q=*:*&fq=%7B!geofilt%7D&sfield=venue_location&pt=28.0674,-80.5595&d=25
        

        There are a number of other methods in UriComponentsBuilder for building the URI incrementally.

        Show
        Rossen Stoyanchev added a comment - - edited The URI-based RestTemplate methods are there as an alternative to the URI-template syntax. They would be appropriate for the given example. However, constructing a URI is not always very convenient. The UriComponentsBuilder provides a way to construct the URI and encode it with various options. Here is one example that starts with a complete URI string: String url = "http: //localhost:8983/solr/select?wt=json&indent= true &fl=*&q=*:*&fq={!geofilt}&sfield=venue_location&pt=28.0674,-80.5595&d=25" ; URI uri = UriComponentsBuilder.fromUriString(url).build().encode().toUri(); System .out.println(uri); // http://localhost:8983/solr/select?wt=json&indent= true &fl=*&q=*:*&fq=%7B!geofilt%7D&sfield=venue_location&pt=28.0674,-80.5595&d=25 There are a number of other methods in UriComponentsBuilder for building the URI incrementally.
        Hide
        Rossen Stoyanchev added a comment -

        You can also encapsulate the content in a variable. In other words "{var}" where var is equal to "{!geofilt}". The variable will get expanded and encoded.

        Show
        Rossen Stoyanchev added a comment - You can also encapsulate the content in a variable. In other words "{var}" where var is equal to "{!geofilt}" . The variable will get expanded and encoded.

          People

          • Assignee:
            Rossen Stoyanchev
            Reporter:
            Keith Donald
            Last updater:
            Rossen Stoyanchev
          • Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Days since last comment:
              1 year, 35 weeks, 1 day ago