I have a Spring Boot 2.3.2.RELEASE WebFlux application. In the application.yml I have these settings:
spring:
jackson:
property-naming-strategy: SNAKE_CASE
serialization:
write-date-timestamps-as-nanoseconds: false
write-dates-as-timestamps: true
Indeed, almost any JSON response is sent back to the user-agents correctly: in _snake case_ format, except for the _auto-generated ones_:
This is a usual GET response from the application:
{
"port_code": "blah",
"firm_code": "foo",
"type": "THE_TYPE",
"status": "BAR",
}
...this is a custom (intercepted within a @RestControllerAdvice) response for a ConstraintViolationException:
{
"timestamp": 1597344667156,
"path": "/path/to/resources/null",
"status": 400,
"error": "Bad Request",
"message": [
{
"field": "id",
"code": "field.id.Range",
"message": "Identifier must be a number within the expected range"
}
],
"request_id": "10c4978f-3"
}
...and finally this is how Spring Boot auto-generates an HTTP 404 from a controller (based on a ResponseStatusException, that's what I meant by _auto-generated ones_ :innocent:):
{
"timestamp": 1597344662823,
"path": "/path/to/resources/312297273",
"status": 404,
"error": "Not Found",
"message": null,
"requestId": "10c4978f-2" <== NOTICE HERE requestId INSTEAD OF request_id ...what the hell?!
}
This is how I'm triggering that in the controller:
return service.findById(id).switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.NOT_FOUND)));
If Jackson is configured in such way, wouldn't that apply across the entire application? Looks like there are parts of it not honouring those settings.
Probably, I missed a configuration setting somewhere, but I can't find anything else, so I decided to file a bug report here — and this is the corresponding StackOverflow question.
To avoid people duplicating effort, I'm going to close this in favour of the question on Stack Overflow. We can re-open it if it turns out that a change in Spring Boot is necessary.
It looks like there is some room for improvement here. The response from BasicErrorController is unaffected by Jackson's property naming strategy as it's a Map<String, Object> and the property naming strategy only applies to JavaBean-style properties when a POJO is being serialised. The format of a map's keys can be controlled with a custom StringKeySerializer but it would be nice to make it easier. Returning a POJO from the BasicErrorController may work, but it would be a breaking change and we'd need to be careful that it worked not just with Jackson but with GSON and any other JSON serialisation library that we support.
Most helpful comment
It looks like there is some room for improvement here. The response from
BasicErrorControlleris unaffected by Jackson's property naming strategy as it's aMap<String, Object>and the property naming strategy only applies to JavaBean-style properties when a POJO is being serialised. The format of a map's keys can be controlled with a customStringKeySerializerbut it would be nice to make it easier. Returning a POJO from theBasicErrorControllermay work, but it would be a breaking change and we'd need to be careful that it worked not just with Jackson but with GSON and any other JSON serialisation library that we support.