简体   繁体   中英

Marshalling Spring Data REST Query Results with RestTemplate

When using RestTemplate.exchange to invoke a query endpoint, what return type should I expect?

My repository has a method thus:

Page<Account> findAccountByFirstName(String name, Pageable pageable);

In my integration test, I'm making the following call with a RestTemplate :

ResponseEntity<List<Account>> accountResponse = restPleb.exchange(
    new RequestEntity<Void>(HttpMethod.GET, getUri("/accounts/search/findByFirstName?firstName=Kevin")), 
    new ParameterizedTypeReference<List<Account>>() {}
);

The response has the list of found resources in an object called accounts :

{
  "_embedded" : {
    "accounts" : [ {
      "lastName" : "Lastname",
      "firstName" : "Kevin",
      "phoneNumber " : "+44 7700000000",
      "email" : "kevin@example.com",
      "_links" : {
        "self" : {
          "href" : "http://localhost:53826/accounts/id"
        },
        "persistableAccount" : {
          "href" : "http://localhost:53826/accounts/id"
        }
      }
    } ]
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:53826/accounts/search/findByFirstName?firstName=Kevin"
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 1,
    "totalPages" : 1,
    "number" : 0
  }
}

I get the following error where between them RestTemplate and Jackson can't figure out what to do with the response. Presumably this is because it's expecting an array rather than an object.

org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token

Is there any way of getting RestTemplate to give the right hints to Jackson to deserialize this properly? I would have thought that there must be a way, being that it's Spring on both sides of the divide!

Update

I've tried specifying the response type as Resources<Account> , which prevents an exception being thrown gives an empty list instead: Resources { content: [], links: [] }

As per the format , it has to be parsed in a different manner is what I suppose. Can this example be used to parse - defined here

Registering the converter to the template -> and using the resource to parse the response.

public RestTemplate getRestTemplateWithHalMessageConverter() {
 RestTemplate restTemplate = new RestTemplate();
 List<HttpMessageConverter<?>> existingConverters = restTemplate.getMessageConverters();
 List<HttpMessageConverter<?>> newConverters = new ArrayList<>();
 newConverters.add(getHalMessageConverter());
 newConverters.addAll(existingConverters);
 restTemplate.setMessageConverters(newConverters);
 return restTemplate;
}

private HttpMessageConverter getHalMessageConverter() {
 ObjectMapper objectMapper = new ObjectMapper();
 objectMapper.registerModule(new Jackson2HalModule());
 MappingJackson2HttpMessageConverter halConverter = new TypeConstrainedMappingJackson2HttpMessageConverter(ResourceSupport.class);
 halConverter.setSupportedMediaTypes(Arrays.asList(HAL_JSON));
 halConverter.setObjectMapper(objectMapper);
 return halConverter;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM