4

How do I configure Spring Boot to return 204 in GET methods (typically findAll methods) when the method does not fetch records? I would not like to do treatment in each method, type the code below:

if(!result)
    return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
    return new ResponseEntity<Void>(HttpStatus.OK)

I'd like to transform this method:

@GetMapping
public ResponseEntity<?> findAll(){
    List<User> result = service.findAll();
    return !result.isEmpty() ? 
            new ResponseEntity<>(result, HttpStatus.OK) : new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
}

In this one:

@GetMapping
public List<User> findAll(){
    return service.findAll();
}

If the result from findAll() is empty or null then my controller should return 204 instead of 200.

takendarkk
  • 3,347
  • 8
  • 25
  • 37
Luciano Borges
  • 817
  • 3
  • 12
  • 31

1 Answers1

7

You could register a custom ResponseBodyAdvice which allows customizing the response of @ResponseBody or ResponseEntity handler methods (right before the content is being serialized by a MessageConverter):

@ControllerAdvice
class NoContentControllerAdvice implements ResponseBodyAdvice<List<?>> {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return List.class.isAssignableFrom(returnType.getParameterType());
    }

    @Override
    public List<?> beforeBodyWrite(List<?> body, MethodParameter returnType, MediaType selectedContentType,
               Class<? extends HttpMessageConverter<?>> selectedConverterType,
               ServerHttpRequest request, ServerHttpResponse response) {

        if (body.isEmpty()) {
            response.setStatusCode(HttpStatus.NO_CONTENT);
        }
        return body;
    }
}
fateddy
  • 6,887
  • 3
  • 22
  • 26
  • 1
    But this pays no attention to the current value of the response. This is a good solution when modifying a 200 OK with null body to a 204, but this would also do the same thing for a 500 or 400? Would exception handlers bypass this? – Dennis Apr 22 '20 at 21:30
  • 1
    @Dennis well it tests the actual response body (the java.util.List). And if an exception occurs inside a handler-method (before a response is returned) - this advice is not fired. – fateddy Apr 23 '20 at 15:18
  • So I guess the strategy is to fire an exception for non 200 cases and then let this handler assume that all it will do is switch 200 -> 204 in some scenarios. Thanks! – Dennis Apr 23 '20 at 18:56
  • @fateddy will return [] Incase of Array/List return type ? – Ramanuj Jun 01 '21 at 01:44