Alexander
Alexander

Reputation: 803

RestTemplate URI template syntax

In my project, I'm using RestTempate in a client app to access existing service. Service itself returns a list of valid URI templates, and one that I'm trying to use looks like

http://corpdomain.com/service{?idparam}

At runtime, it should expand to something like

http://corpdomain.com/service?idparam=12345

Problem is, RestTemplate's getForObject() does not know what to do with "{?idparam}" notation. If I feed it the URI http://corpdomain.com/service?idparam={idparam}, everything works fine. But this is not the URI template that server returns to me.

Do you know how to make RestTemplate.getForObject() working with {?idparam} type notation in template?

Do you know if there is ANY documentation out there regarding the syntax of URI templates?

I'm currently going through spring's java sources and eventually should be able to figure out the solution. However, what really bugs me is the lack of documentation or third party information.

Thanks everybody in advance!

Upvotes: 2

Views: 12768

Answers (3)

pdc
pdc

Reputation: 2414

Looks like the service is returning RFC 6570 URI templates, which include notations like {?foo} and {+foo} that are are not supported by Spring.

There is a library Handy URI Templates that implements the RFC 6570 spec.

Upvotes: 4

Barath
Barath

Reputation: 5283

You can either pass uri variables as part of getForObject method

getForObject(String url, Class<T> responseType, Map<String,?> uriVariables)

Docs: http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

or else you can make use of build and expand method of UriComponentsBuilder like below :

        String url="http://localhost:8080/test?idparam={idparam}";
        RestTemplate restTemplate=new RestTemplate();
        Map<String,String> uriVariables=new HashMap<String,String>();
        uriVariables.put("idparam", "1234");
        UriComponents builder=UriComponentsBuilder.fromHttpUrl(url).buildAndExpand(uriVariables);
        System.out.println(" url built "+builder.toUri());

Output:

 url built http://localhost:8080/test?idparam=1234

In case, query params are dynamic as you are not sure what url is going to get passed, you can do like below :

    UriComponentsBuilder builder=UriComponentsBuilder.fromHttpUrl(url);
    Map<String,String> uriVariables =builder.build().getQueryParams().toSingleValueMap();
    //set or get required query params
    restTemplate.getForObject(url, String.class, uriVariables);

Upvotes: 2

ferahgo
ferahgo

Reputation: 408

I am not familiar with that syntax. However I would define a BASE_SERVICE_URL and use that with a UriComponentsBuilder to make your URL. It would look something like this

  private static final String BASE_SERVICE_URL = "http://corpdomain.com/service"

    public void doTheThing(String idParam) {
    ...
    UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
            .queryParam("idparam", idparam)
    ...
    HttpEntity<String> response = restTemplate.exchange(
        builder.build().encode().toUri(), 
        HttpMethod.GET, 
        entity, 
        String.class);
    }

Upvotes: 1

Related Questions