2

When attempting to post to a Spring-Data-Rest web service via RestTemplate, the JSON representation of my domain object is being converted to a full blown JSON object that isn't in HAL representation. My assumption here is that I need to register the Jackson2HalModule as a deserializer though am not sure how to do that considering I register it to the objectMapper. The serialization works correctly when calling GET on the webservice, just not for POST/PUT:

Request outputBuffer field:

{
  "id" : 1,
  "name" : "Name",
  "description" : "",
  "childObject" : {
    "id" : 1,
    "name" : "test"
  }
} 

Rest Template configuration:

@Bean
public ObjectMapper objectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(new JodaModule());
    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    objectMapper.setDateFormat(new ISO8601DateFormat());
    objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
    objectMapper.registerModule(new Jackson2HalModule());
    return objectMapper;
}

public void configureMessageConverters(
        List<HttpMessageConverter<?>> messageConverters) {
    MappingJackson2HttpMessageConverter jsonMessageConverter = new MappingJackson2HttpMessageConverter();
    jsonMessageConverter.setObjectMapper(objectMapper());
    jsonMessageConverter.setSupportedMediaTypes(MediaType
            .parseMediaTypes("application/hal+json,application/json"));
    messageConverters.add(jsonMessageConverter);
}

@Bean
public RestTemplate restTemplate() {
    RestTemplate restTemplate = new RestTemplate();
    List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
    configureMessageConverters(messageConverters);
    restTemplate.setMessageConverters(messageConverters);
    return restTemplate;
}

Request Headers:

  HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);

Calling method:

ResponseEntity<DomainObject> responseEntity =
    restTemplate.exchange(this.getBaseUri() + resolveResource(), HttpMethod.POST, new HttpEntity(domainObject,createHttpHeaders(tenantId)), DomainObject.class);
Richard Neish
  • 8,414
  • 4
  • 39
  • 69
Vlad
  • 51
  • 6

1 Answers1

0

I think you should not register your own ObjectMapper. Spring creates it for you and also registers all the modules needed. So I would just try to remove your ObjectMapper bean.

If you need to customize the ObjectMapper you could use a Jackson2ObjectMapperBuilder. See the documentation for more details - http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-customize-the-jackson-objectmapper

@Bean
    public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
        return Jackson2ObjectMapperBuilder //
                .json() //
                .locale(ENGLISH) //
                .timeZone("UTC") //
                .indentOutput(true) //
                .serializationInclusion(NON_NULL) //
                .featuresToDisable(WRITE_DATES_AS_TIMESTAMPS, FAIL_ON_UNKNOWN_PROPERTIES) //
                ;
    }

I would also let spring take care of the message converters:

So let spring inject them when you create the RestTemplate - so something like this:

@Bean
public RestTemplate restTemplate(List<HttpMessageConverter<?>> messageConverters) {
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.setMessageConverters(messageConverters);
    return restTemplate;
}
Mathias Dpunkt
  • 11,594
  • 4
  • 45
  • 70