3

I am trying to POST a user group:

public UserGroup createUserGroup(UserGroup userGroup) {
    ResponseEntity<UserGroup> userGroupResponseEntity = oauthRestTemplate
            .postForEntity(GROUPS_ENDPOINT, userGroup, UserGroup.class);
    return userGroupResponseEntity.getBody();
}

Since I am using @RepositoryRestResource I had to configure the object mapper:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new Jackson2HalModule());
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
messageConverter.setObjectMapper(objectMapper);
messageConverter.setSupportedMediaTypes(Collections.singletonList(MediaTypes.HAL_JSON));

this.oauthRestTemplate.setMessageConverters(Collections.singletonList(messageConverter));

However, running the POST from above will throw me

Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (START_OBJECT), expected VALUE_STRING: Expected array or string.
 at [Source: (org.apache.catalina.connector.CoyoteInputStream); line: 1, column: 87] (through reference chain: mahlzeit.api.hibernate.model.UserGroup["voteUntil"])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63) ~[jackson-databind-2.9.4.jar:2.9.4]
    at com.fasterxml.jackson.databind.DeserializationContext.wrongTokenException(DeserializationContext.java:1507) ~[jackson-databind-2.9.4.jar:2.9.4]
    at com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer.deserialize(LocalDateTimeDeserializer.java:138) ~[jackson-datatype-jsr310-2.9.2.jar:2.9.2]
    at com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer.deserialize(LocalDateTimeDeserializer.java:39) ~[jackson-datatype-jsr310-2.9.2.jar:2.9.2]
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127) ~[jackson-databind-2.9.4.jar:2.9.4]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:369) ~[jackson-databind-2.9.4.jar:2.9.4]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159) ~[jackson-databind-2.9.4.jar:2.9.4]
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001) ~[jackson-databind-2.9.4.jar:2.9.4]
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3072) ~[jackson-databind-2.9.4.jar:2.9.4]
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:235) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    ... 93 common frames omitted

2018-04-02 15:12:52.788 DEBUG 1811 --- [nio-8081-exec-3] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@24f17053
2018-04-02 15:12:52.789 DEBUG 1811 --- [nio-8081-exec-3] o.s.s.w.a.ExceptionTranslationFilter     : Chain processed normally
2018-04-02 15:12:52.789 DEBUG 1811 --- [           main] o.s.s.oauth2.client.OAuth2RestTemplate   : POST request for "http://localhost:8081/groups" resulted in 400 (null); invoking error handler
2018-04-02 15:12:52.789 DEBUG 1811 --- [nio-8081-exec-3] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
org.springframework.web.client.HttpClientErrorException: 400 null
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:94)
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:79)
    at org.springframework.security.oauth2.client.http.OAuth2ErrorHandler.handleError(OAuth2ErrorHandler.java:172)
    at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:777)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:730)
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:128)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:686)
    at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:468)

and I just don't get why!

Stefan Falk
  • 23,898
  • 50
  • 191
  • 378
  • 1
    One quick suggestion: when debugging, do NOT disable `DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES` -- it can hide all kinds of problems. It may make sense to disable in production (but not always), but when troubleshooting it is best to leave on. This may not be the problem here but I have seen so many cases where this has hidden what would otherwise be a simple problem to solve. – StaxMan Apr 02 '18 at 22:53
  • @StaxMan Thank! I welcome advice like that very much. I will try to leave this enabled - tbh I didn't think much about its effect - I was just following a stackoverflow answer - something one shouldn't do as we can see :D – Stefan Falk Apr 03 '18 at 09:48
  • @StaxMan Okay, I've tested this. The problem is that this does not work with the `hal+json` format that comes from Spring Data JPA. I don't know if I can work around this but at this point I either have to enable it or write my own resource classes for that it would seem. – Stefan Falk Apr 03 '18 at 16:15
  • See this [answer](https://stackoverflow.com/questions/45662820/how-to-set-format-of-string-for-java-time-instant-using-objectmapper/54346334#54346334) in another post. – Laura Liparulo Jan 24 '19 at 12:09

1 Answers1

12

For anybody who runs into this - and this is why Spring can get so immense frustrating sometimes if you are not careful or remember a million things that you configured beforehand.

So in case you're like me and used application-test.properties in order to configure certain things, let's say something like this:

# Used to enable ISO format for time data
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false

but have already forgotten about that, then you might want to bear in mind that this property gets ignored as soon as you set, like me, your custom ObjectMapper in order to consume the hal+json output from Spring Data REST endpoints. And because of that you might want to set:

objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.registerModule(new JavaTimeModule());
Stefan Falk
  • 23,898
  • 50
  • 191
  • 378