Spring REST 接口自定义404响应内容

版本说明:Spring Boot 2.0.1.RELEASE

REST风格默认的404响应如下:

{
    "timestamp": "2018-06-07T05:23:27.196+0000",
    "status": 404,
    "error": "Not Found",
    "message": "No message available",
    "path": "/shopping/123/TEST"
}

如果不想返回此内容,需要做如下配置:

application.yml

spring: 
  mvc:
    throw-exception-if-no-handler-found: true
  resources:
    add-mappings: false

添加以上配置后,404时DispatcherServlet会抛出NoHandlerFoundException,注意spring.resources.add-mappings 在当前版本下需要设置为false,否则不会抛出异常。

异常捕获

在项目中我使用了全局异常处理,如下:

@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(value = {Exception.class})
    public ResponseEntity<Object> handleExceptions(Exception ex, WebRequest request) {
        logger.error("Exception", ex);
        mailPublisher.publishMailToAdministrator(ex);

        return handleExceptionInternal(ex, RESPONSE_ERROR, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR, request);
    }
    
    /**
     * Handle NoHandlerFoundException
     * @param ex
     * @param headers
     * @param status
     * @param request
     * @return
     */
    @Override
    protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        return handleExceptionInternal(ex, RESPONSE_ERROR, headers, status, request);
    }    
    
}

重写ResponseEntityExceptionHandler的handleNoHandlerFoundException方法来处理404异常,注意不要在全局异常处理中添加如下方法:

    @ExceptionHandler(value = {NoHandlerFoundException.class})
    public ResponseEntity<Object> handleNotFoundExceptions(NoHandlerFoundException ex) {
        return handleExceptionInternal(ex, RESPONSE_ERROR, new HttpHeaders(), HttpStatus.NOT_FOUND, null);
    }

否则会抛出如下异常,因为ResponseEntityExceptionHandler.handleException已经注册了对该异常的处理,如果我们再注册一个,会有两个异常处理,导致Ambiguous。

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