Spring-boot: Make it easier to control how the keys in the basic error controller's response are formatted

Created on 14 Aug 2020  Â·  2Comments  Â·  Source: spring-projects/spring-boot

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.

enhancement

Most helpful comment

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.

All 2 comments

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.

Was this page helpful?
0 / 5 - 0 ratings