Majid Abdolhosseini
Majid Abdolhosseini

Reputation: 2301

Spring Boot 2.2.5 404 page not found custom json response

How can I have a custom json for my 404 pages ? actually what I need is to be able to create custom json errors for my application. for example for 404,401,403,422, ... I searched a lot and what I found is :

package ir.darsineh.lms.http.exceptionHandler;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {


    @ExceptionHandler(NoHandlerFoundException.class)
    public void springHandleNotFound(HttpServletResponse response) throws IOException {
        response.sendError(HttpStatus.NOT_FOUND.value());
    }


}

and here is the error I get :

Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.servlet.NoHandlerFoundException]

I need my api response body json to be something like this :

{"code": 404, "message": "page not found"}

Upvotes: 0

Views: 2723

Answers (2)

Hamid Mohayeji
Hamid Mohayeji

Reputation: 4285

First, you should let Spring MVC to throw exception if no handler is found:

spring.mvc.throw-exception-if-no-handler-found=true

Then, the exception must be caught using a @ControllerAdvice:

@ControllerAdvice
public class CustomAdvice {

    // 404
    @ExceptionHandler({ NoHandlerFoundException.class })
    @ResponseBody
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public CustomResponse notFound(final NoHandlerFoundException ex) {
        return new CustomResponse(HttpStatus.NOT_FOUND.value(), "page not found");
    }
}

@Data
@AllArgsConstructor
class CustomResponse {
    int code;
    String message;
}

Do not forget to add @EnableWebMvc annotation to your app.

Upvotes: 2

Kumar V
Kumar V

Reputation: 1660

ResponseEntityExceptionHandler class already has handleNoHandlerFoundException() method defined as below.

protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
    return this.handleExceptionInternal(ex, (Object)null, headers, status, request);
}

Since the method signatures (parent class and our implementation class) are different, it resulted in ambiguous error. Using the same signature will override the above method with our custom implementation.

@ExceptionHandler(NoHandlerFoundException.class)
protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
    ErrorResponse error = new ErrorResponse("404", "page not found");
    return new ResponseEntity(error, HttpStatus.NOT_FOUND);
}

Hope this helps!!

Upvotes: 0

Related Questions