We are developing a server that exposes an API, and a webapp that consumes this. The server uses spring-boot (1.2.4.RELEASE) and spring-data-rest. The webapp uses spring-hateoas to consume the API. We don't have problems consuming PagedResources, but when we try to access relations list link an exception is thrown.
ResponseEntity<PagedResources<Resource<Project>>> projectsPaged = restTemplate().exchange(
"http://localhost:8080/projects",
HttpMethod.GET,
null,
new ParameterizedTypeReference<PagedResources<Resource<Project>>>() {}
);
Collection<Resource<Project>> resourcesProjects = projectsPaged.getBody().getContent();
List<Project> projectsWithTranslations = new ArrayList<>();
for (Resource<Project> resourceProject : resourcesProjects) {
ResponseEntity<Resources<Resource<ProjectT>>> resultTranslations = restTemplate().exchange(
resourceProject.getLink("translations").getHref(),
HttpMethod.GET,
null,
new ParameterizedTypeReference<Resources<Resource<ProjectT>>>() {}
); // here is where the exception is thrown
log.error("N. TRANSLATIONS: " + resultTranslations.getBody().getContent().size());
}
RestTemplate is created like this (resourceDetails() method configures ClientCredentialsResourceDetails):
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails(), new DefaultOAuth2ClientContext());
HttpClient httpClient = HttpClients.createDefault();
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
ObjectMapper o = new ObjectMapper();
o.registerModule(new Jackson2HalModule());
o.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
o.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
MappingJackson2HttpMessageConverter c = new MappingJackson2HttpMessageConverter();
c.setObjectMapper(o);
restTemplate.getMessageConverters().add(0, c);
Projects url produces this JSON (http://localhost:8080/projects):
{
"_links" : {
"self" : {
"href" : "http://localhost:8080/projects/actives{?page,size,sort}",
"templated" : true
}
},
"_embedded" : {
"projects" : [ {
"code" : "XK63489",
...
"_links" : {
"self" : {
"href" : "http://localhost:8080/projects/1"
},
"translations" : {
"href" : "http://localhost:8080/projects/1/translations"
}
}
} ]
},
"page" : {
"size" : 20,
"totalElements" : 1,
"totalPages" : 1,
"number" : 0
}
}
And this is the JSON we're trying to consume (http://localhost:8080/projects/1/translations):
{
"_embedded" : {
"projectTs" : [ {
"locale" : "es",
"name" : "Spanish name",
"_links" : {
"self" : {
"href" : "http://localhost:8080/projectTs/7"
},
"project" : {
"href" : "http://localhost:8080/projectTs/7/project"
}
}
},
...
]
}
}
When we try to consume second JSON this exception is thrown:
2015-06-12 14:22:10.212 ERROR 2968 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.client.HttpClientErrorException: 400 Bad Request] with root cause
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
at org.springframework.security.oauth2.client.http.OAuth2ErrorHandler.handleError(OAuth2ErrorHandler.java:165)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:614)
...
And this is the exception that server throws:
2015-06-12 14:22:10.199 ERROR 1895 --- [nio-8080-exec-3] s.d.r.w.AbstractRepositoryRestController : Map has no value for 'repository'
java.lang.IllegalArgumentException: Map has no value for 'repository'
at org.springframework.web.util.UriComponents$MapTemplateVariables.getValue(UriComponents.java:276)
at org.springframework.web.util.UriComponents.expandUriComponent(UriComponents.java:221)
What's wrong with our code? Thanks in advance.
We found the solution.
That's the correct code to retrieve information of a resource's link: