Error consuming subresources link with RestTemplate

1.4k views Asked by At

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.

1

There are 1 answers

0
fjgm On BEST ANSWER

We found the solution.

That's the correct code to retrieve information of a resource's link:

RequestEntity<Void> request = RequestEntity.get(URI.create(resourceProject.getLink("translations").getHref())).accept(MediaTypes.HAL_JSON).build();
ResponseEntity<Resources<Resource<ProjectT>>> resultTranslations = restTemplate().exchange(
    request,
    new ParameterizedTypeReference<Resources<Resource<ProjectT>>>() {}
);