diff --git a/src/main/java/org/springframework/hateoas/client/Traverson.java b/src/main/java/org/springframework/hateoas/client/Traverson.java index f0776b26..9ba81be4 100644 --- a/src/main/java/org/springframework/hateoas/client/Traverson.java +++ b/src/main/java/org/springframework/hateoas/client/Traverson.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -241,7 +241,7 @@ public class Traverson { public T toObject(Class type) { Assert.notNull(type, "Target type must not be null!"); - return operations.exchange(traverseToFinalUrl(), GET, prepareRequest(headers), type).getBody(); + return operations.exchange(traverseToFinalUrl(true), GET, prepareRequest(headers), type).getBody(); } /** @@ -254,7 +254,7 @@ public class Traverson { public T toObject(ParameterizedTypeReference type) { Assert.notNull(type, "Target type must not be null!"); - return operations.exchange(traverseToFinalUrl(), GET, prepareRequest(headers), type).getBody(); + return operations.exchange(traverseToFinalUrl(true), GET, prepareRequest(headers), type).getBody(); } /** @@ -268,7 +268,7 @@ public class Traverson { Assert.hasText(jsonPath, "JSON path must not be null or empty!"); - String forObject = operations.exchange(traverseToFinalUrl(), GET, prepareRequest(headers), String.class) + String forObject = operations.exchange(traverseToFinalUrl(true), GET, prepareRequest(headers), String.class) .getBody(); return JsonPath.read(forObject, jsonPath); } @@ -282,25 +282,42 @@ public class Traverson { public ResponseEntity toEntity(Class type) { Assert.notNull(type, "Target type must not be null!"); - return operations.exchange(traverseToFinalUrl(), GET, prepareRequest(headers), type); + return operations.exchange(traverseToFinalUrl(true), GET, prepareRequest(headers), type); } /** - * Returns the {@link Link} found for the last rel int the rels configured to follow. + * Returns the {@link Link} found for the last rel in the rels configured to follow. Will expand the final + * {@link Link} using the * * @return + * @see #withTemplateParameters(Map) * @since 0.15 */ public Link asLink() { - - Assert.isTrue(rels.size() > 0, "At least one rel needs to be provided!"); - return new Link(traverseToFinalUrl(), rels.get(rels.size() - 1)); + return traverseToLink(true); } - private String traverseToFinalUrl() { + /** + * Returns the templated {@link Link} found for the last rel in the rels configured to follow. + * + * @return + * @since 0.17 + */ + public Link asTemplatedLink() { + return traverseToLink(false); + } + + private Link traverseToLink(boolean expandFinalUrl) { + + Assert.isTrue(rels.size() > 0, "At least one rel needs to be provided!"); + return new Link(traverseToFinalUrl(expandFinalUrl), rels.get(rels.size() - 1)); + } + + private String traverseToFinalUrl(boolean expandFinalUrl) { String uri = getAndFindLinkWithRel(baseUri.toString(), rels.iterator()); - return new UriTemplate(uri).expand(templateParameters).toString(); + UriTemplate uriTemplate = new UriTemplate(uri); + return expandFinalUrl ? uriTemplate.expand(templateParameters).toString() : uriTemplate.toString(); } private String getAndFindLinkWithRel(String uri, Iterator rels) { diff --git a/src/test/java/org/springframework/hateoas/client/Server.java b/src/test/java/org/springframework/hateoas/client/Server.java index d1a6b06f..aca407cf 100644 --- a/src/test/java/org/springframework/hateoas/client/Server.java +++ b/src/test/java/org/springframework/hateoas/client/Server.java @@ -81,6 +81,14 @@ public class Server implements Closeable { respond(). // withBody("{ \"key\" : \"value\"}"). // withContentType(MediaType.APPLICATION_JSON_VALUE); + + // For templated link access + + onRequest(). // + havingPathEqualTo("/link"). // + respond(). // + withBody("{ \"_links\" : { \"self\" : { \"href\" : \"/{?template}\" }}}"). // + withContentType(MediaTypes.HAL_JSON.toString()); } public String rootResource() { diff --git a/src/test/java/org/springframework/hateoas/client/TraversonTests.java b/src/test/java/org/springframework/hateoas/client/TraversonTests.java index 8eaeeb16..5f78e47c 100644 --- a/src/test/java/org/springframework/hateoas/client/TraversonTests.java +++ b/src/test/java/org/springframework/hateoas/client/TraversonTests.java @@ -30,6 +30,7 @@ import org.springframework.core.ParameterizedTypeReference; import org.springframework.hateoas.Link; import org.springframework.hateoas.MediaTypes; import org.springframework.hateoas.Resource; +import org.springframework.hateoas.client.Traverson.TraversalBuilder; import org.springframework.hateoas.core.JsonPathLinkDiscoverer; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpRequest; @@ -209,6 +210,25 @@ public class TraversonTests { assertThat(result.getRel(), is("movies")); } + /** + * @see #307 + */ + @Test + public void returnsTemplatedLinkIfRequested() { + + TraversalBuilder follow = new Traverson(URI.create(server.rootResource().concat("/link")), MediaTypes.HAL_JSON) + .follow("self"); + + Link link = follow.asTemplatedLink(); + + assertThat(link.isTemplated(), is(true)); + assertThat(link.getVariableNames(), hasItem("template")); + + link = follow.asLink(); + + assertThat(link.isTemplated(), is(false)); + } + private void setUpActors() { Resource actor = new Resource(new Actor("Keanu Reaves"));