#185 - Traverson can now get LinkDiscoverers configured.
Moved to a setter based configuration for both the RestOperations and LinkDiscoverers to be used. Related pull request: #189.
This commit is contained in:
@@ -93,7 +93,15 @@ class Rels {
|
||||
*/
|
||||
@Override
|
||||
public Link findInResponse(String response, MediaType mediaType) {
|
||||
return discoverers.getLinkDiscovererFor(mediaType).findLinkWithRel(rel, response);
|
||||
|
||||
LinkDiscoverer discoverer = discoverers.getLinkDiscovererFor(mediaType);
|
||||
|
||||
if (discoverer == null) {
|
||||
throw new IllegalStateException(String.format("Did not find LinkDiscoverer supporting media type %s!",
|
||||
mediaType));
|
||||
}
|
||||
|
||||
return discoverer.findLinkWithRel(rel, response);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,11 +62,19 @@ import com.jayway.jsonpath.JsonPath;
|
||||
*/
|
||||
public class Traverson {
|
||||
|
||||
private static final LinkDiscoverers DEFAULT_LINK_DISCOVERERS;
|
||||
|
||||
static {
|
||||
LinkDiscoverer discoverer = new HalLinkDiscoverer();
|
||||
DEFAULT_LINK_DISCOVERERS = new LinkDiscoverers(OrderAwarePluginRegistry.create(Arrays.asList(discoverer)));
|
||||
}
|
||||
|
||||
private final URI baseUri;
|
||||
private final RestOperations operations;
|
||||
private final LinkDiscoverers discoverers;
|
||||
private final List<MediaType> mediaTypes;
|
||||
|
||||
private RestOperations operations;
|
||||
private LinkDiscoverers discoverers;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Traverson} interacting with the given base URI and using the given {@link MediaType}s to
|
||||
* interact with the service.
|
||||
@@ -75,29 +83,15 @@ public class Traverson {
|
||||
* @param mediaType must not be {@literal null} or empty.
|
||||
*/
|
||||
public Traverson(URI baseUri, MediaType... mediaTypes) {
|
||||
this(null, baseUri, mediaTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Traverson} with custom rest operations, interacting with the given base URI and using the
|
||||
* given {@link MediaType}s to interact with the service. The custom rest operations will be prepared with message
|
||||
* converters for the given media types.
|
||||
*
|
||||
* @param operations allowing to customize the http requests with interceptors, client configurations etc.
|
||||
* @param baseUri must not be {@literal null}.
|
||||
* @param mediaType must not be {@literal null} or empty.
|
||||
*/
|
||||
public Traverson(RestOperations operations, URI baseUri, MediaType... mediaTypes) {
|
||||
|
||||
Assert.notNull(baseUri, "Base URI must not be null!");
|
||||
Assert.notEmpty(mediaTypes, "At least one media type must be given!");
|
||||
|
||||
this.mediaTypes = Arrays.asList(mediaTypes);
|
||||
this.baseUri = baseUri;
|
||||
this.operations = operations == null ? createDefaultTemplate(this.mediaTypes) : operations;
|
||||
this.discoverers = DEFAULT_LINK_DISCOVERERS;
|
||||
|
||||
LinkDiscoverer discoverer = new HalLinkDiscoverer();
|
||||
this.discoverers = new LinkDiscoverers(OrderAwarePluginRegistry.create(Arrays.asList(discoverer)));
|
||||
setRestOperations(createDefaultTemplate(this.mediaTypes));
|
||||
}
|
||||
|
||||
private static final RestOperations createDefaultTemplate(List<MediaType> mediaTypes) {
|
||||
@@ -134,6 +128,34 @@ public class Traverson {
|
||||
return converter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the {@link RestOperations} to use. If {@literal null} is provided a default {@link RestTemplate} will be
|
||||
* used.
|
||||
*
|
||||
* @param operations
|
||||
* @return
|
||||
*/
|
||||
public Traverson setRestOperations(RestOperations operations) {
|
||||
|
||||
this.operations = operations == null ? createDefaultTemplate(mediaTypes) : operations;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link LinkDiscoverers} to use. By default a single {@link HalLinkDiscoverer} is registered. If
|
||||
* {@literal null} is provided the default is reapplied.
|
||||
*
|
||||
* @param discoverer can be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public Traverson setLinkDiscoverers(List<? extends LinkDiscoverer> discoverer) {
|
||||
|
||||
this.discoverers = discoverers == null ? DEFAULT_LINK_DISCOVERERS : new LinkDiscoverers(
|
||||
OrderAwarePluginRegistry.create(discoverer));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a {@link TraversalBuilder} to follow the given rels.
|
||||
*
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.hateoas.Resource;
|
||||
import org.springframework.hateoas.Resources;
|
||||
import org.springframework.hateoas.core.EvoInflectorRelProvider;
|
||||
import org.springframework.hateoas.hal.Jackson2HalModule;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
@@ -66,6 +67,20 @@ public class Server implements Closeable {
|
||||
havingPathEqualTo("/"). //
|
||||
respond(). //
|
||||
withBody("");
|
||||
|
||||
// For GitHubLinkDiscoverer tests
|
||||
|
||||
onRequest(). //
|
||||
havingPathEqualTo("/github"). //
|
||||
respond(). //
|
||||
withBody("{ \"foo_url\" : \"" + rootResource() + "/github/4711\"}"). //
|
||||
withContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
onRequest(). //
|
||||
havingPathEqualTo("/github/4711"). //
|
||||
respond(). //
|
||||
withBody("{ \"key\" : \"value\"}"). //
|
||||
withContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
|
||||
public String rootResource() {
|
||||
|
||||
@@ -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.core.JsonPathLinkDiscoverer;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -176,12 +177,26 @@ public class TraversonTests {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
restTemplate.setInterceptors(Arrays.<ClientHttpRequestInterceptor> asList(interceptor));
|
||||
|
||||
this.traverson = new Traverson(restTemplate, baseUri, MediaTypes.HAL_JSON);
|
||||
this.traverson = new Traverson(baseUri, MediaTypes.HAL_JSON);
|
||||
this.traverson.setRestOperations(restTemplate);
|
||||
|
||||
traverson.follow("movies", "movie", "actor").<String> toObject("$.name");
|
||||
assertThat(interceptor.intercepted, is(4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #185
|
||||
*/
|
||||
@Test
|
||||
public void usesCustomLinkDiscoverer() {
|
||||
|
||||
this.traverson = new Traverson(URI.create(server.rootResource() + "/github"), MediaType.APPLICATION_JSON);
|
||||
this.traverson.setLinkDiscoverers(Arrays.asList(new GitHubLinkDiscoverer()));
|
||||
|
||||
String value = this.traverson.follow("foo").toObject("$.key");
|
||||
assertThat(value, is("value"));
|
||||
}
|
||||
|
||||
private void setUpActors() {
|
||||
|
||||
Resource<Actor> actor = new Resource<Actor>(new Actor("Keanu Reaves"));
|
||||
@@ -206,4 +221,11 @@ public class TraversonTests {
|
||||
return execution.execute(request, body);
|
||||
}
|
||||
};
|
||||
|
||||
static class GitHubLinkDiscoverer extends JsonPathLinkDiscoverer {
|
||||
|
||||
public GitHubLinkDiscoverer() {
|
||||
super("$.%s_url", MediaType.APPLICATION_JSON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user