James
James

Reputation: 3184

Why do methods on @RestControllerAdvice class return HTML instead of JSON?

I have the following exception handler:

@RestControllerAdvice
@RequiredArgsConstructor
public class ControllerExceptionHandler {

    @ExceptionHandler(FeignException.class)
    @ResponseBody
    public String afterThrowing(FeignException ex, HttpServletResponse response) {
        response.setStatus(ex.status());
        return ex.contentUTF8();
    }

}

I would expect when the FeignException propagates to one of my REST controllers that

  1. The afterThrowing method would be called
  2. The response returned to an HTTP client would be JSON

The method is called but the content type returned to the client is HTML instead of JSON. How can I have JSON returned instead of HTML?

Upvotes: 0

Views: 1176

Answers (1)

Xnart
Xnart

Reputation: 101

You should wrap your response with something(class or map).

Wrapper class :

public class ApiError {
    private HttpStatus status;
    private String response;

    public ApiError(String response, HttpStatus status) { 
       this.response = s;
       this.status = status;
    }

    // getter setter
} 

And exception handler :

  @ExceptionHandler(FeignException.class)
  protected ResponseEntity<Object> handleFeignException(FeignException ex) {
    ApiError apiError = new ApiError(ex.contentUTF8(), NOT_ACCEPTABLE);
    return new ResponseEntity<>(apiError, apiError.getStatus());
  }

For further reading you can check this question : How to return simple String as JSON in Rest Controller


Edit: Since your ex.contentUTF8() call returns valid JSON you don't need to wrap it. Simply return String with ResponseEntity.

  @ExceptionHandler(FeignException.class)
  protected ResponseEntity<String> handleFeignException(FeignException ex) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    return new ResponseEntity<>(ex.contentUTF8(), headers, BAD_REQUEST);
  }

Upvotes: 1

Related Questions