Search code examples
javaspringspring-bootspring-restcontrollerspring-rest

Spring REST add field to 404 resonse code


Using latest Spring Boot as of May 2018. I've created a 404 response like this.

@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException {

    private final int errorId;

    public NotFoundException(String errorMsg) {
        super("-1," + errorMsg);
        this.errorId = -1;
    }

    public NotFoundException(int errorId, String errorMsg) {
        super(errorId + "," + errorMsg);
        this.errorId = errorId;
    }


    public int getErrorId() {
        return errorId;
    }
}

The annotation @ResponseStatus(HttpStatus.NOT_FOUND) makes my NotFoundException appear like a 404 reponse like this

{
    "timestamp":1527751944754,
    "status":404,
    "error":"Not Found",
    "exception":"com.myapp.exception.NotFoundException",
    "message":"1000,Could not find data for owner: 1234","path":"/resource/owner/1234"
}

I hoped that property "getErrorId" would appear in the response automatically, like this

{
    "timestamp":1527751944754,
    "status":404,
    "error":"Not Found",
    "exception":"com.myapp.exception.NotFoundException",
    "message":"Could not find data for owner: 1234","path":"/resource/owner/1234",
    "errorId": 1000
}

Is the a simply way (like an annotiation to the getErrorId method) of having the property "errorId" in the response?


Solution

  • You use @ControllerAdvice and @ExceptionHanlder in Spring. that is exception controller. In fact, you will make custom exception controller and define exception.

    This is sample code for you :

    @ControllerAdvice("your.package")
    public class CommonExceptionHandler {
    
        @ExceptionHandler(value = NoHandlerFoundException.class)
        @ResponseStatus(value = HttpStatus.NOT_FOUND)
        public @ResponseBody ResponseEntity<?> setNotFoundException(Exception exception) throws JsonProcessingException {
    
            ObjectMapper mapper = new ObjectMapper();
    
            // this is sample map. you will make your custom model and you use exception parameter.
            Map<String, String> map = new HashMap<String, String>();
            map.put("timestamp", String.valueOf(new Date().getTime()));
            map.put("status", HttpStatus.NOT_FOUND.toString());
            map.put("error", "Not Found");
            map.put("exception", exception.getMessage());
            map.put("message", "Could not find data for owner: 1234");
            map.put("path", "/resource/owner/1234");
            map.put("errorId", "1000");
    
            String json = mapper.writeValueAsString(map);
    
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(json);
        }
    
    }