Spring boot教程-为所有资源实现通用的异常处理
为所有资源实现通用的异常处理
正如之前讨论的,我们应该定义一个标准的异常结构,使其在所有的 RESTful 服务中得以遵循。在本节中,我们将讨论如何为所有资源实现通用的异常处理。
让我们看看如何自定义异常消息。
步骤 1: 创建一个名为 **cn.javatiku
.server.main.exception** 的新包。
步骤 2: 在上述包中创建一个名为 ExceptionResponse 的类。
步骤 3: 基本级别上,异常结构需要三个关键要素:timestamp(时间戳),message(消息) 和 detail(细节)。定义这三个字段。
步骤 4: 使用字段生成构造函数。
步骤 5: 生成 Getters,不需要 Setters。
一旦结构被定义,我们可以为其定义 Java 实现。当发生异常时,我们将以特定格式返回一个响应。这个结构是最重要的部分,必须是语言无关的。
Spring Framework 中的一个重要类是 ResponseEntityExceptionHandler 类。它是一个抽象类和基类,用于为所有不同的异常处理方法提供集中的异常处理。我们将扩展此类以处理并提供自定义的异常处理功能。这个异常处理功能应用于所有的控制器,比如 HelloWorldController 和 UserResource(控制器)。
步骤 6: 在包 cn.javatiku server.main.exception 中创建一个名为 CustomizedResponseEntityExceptionHandler 的新类,继承 ResponseEntityExceptionHandler 类。
步骤 7: 添加 @ControllerAdvice 和 @RestController 注解。
步骤 8: 在包资源管理器中展开 Maven 依赖 -> 展开 spring-webmvc-5.1.9.RELEASE.jar -> 展开 org.springframework.web.servlet.mvc.method.annotation -> 打开 ResponseEntityExceptionHandler.class。
步骤 9: 从 ResponseEntityExceptionHandler.class 复制 ResponseEntityMethod<Object> 方法,并粘贴到 CustomizedResponseEntityExceptionHandler.java 文件中。
步骤 10: 覆盖 ResponseEntityMethod 方法。将方法名改为 handleAllExceptions()。
步骤 11: 创建异常响应结构。
步骤 12: 创建一个 ResponseEntity 对象,并将异常响应和 HTTP 状态作为参数传递。
CustomizedResponseEntityExceptionHandler.java:
package cn.javatiku.server.main;
import java.util.Date;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import cn.javatiku.server.main.exception.ExceptionResponse;
//defining exception handling for all the exceptions
@ControllerAdvice
@RestController
public class CustomizedResponseEntityExceptionHandler extends ResponseEntityExceptionHandler
{
@ExceptionHandler(Exception.class)
//override method of ResponseEntityExceptionHandler class
public final ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request)
{
//creating exception response structure
ExceptionResponse exceptionResponse= new ExceptionResponse(new Date(), ex.getMessage(), request.getDescription(false));
//returning exception structure and specific status
return new ResponseEntity(exceptionResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
步骤 13: 打开 REST 客户端 Postman 并发送一个 Get 请求。我们得到了 Status: 500 Internal Server Error 和我们定义的异常结构。
如果我们想将状态 Internal Server Error 自定义为 Not Found,我们需要在 CustomizedResponseEntityExceptionHandler.java 文件中做一些更改。
CustomizedResponseEntityExceptionHandler.java:
package cn.javatiku.server.main;
import java.util.Date;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import cn.javatiku.server.main.exception.ExceptionResponse;
import cn.javatiku.server.main.user.UserNotFoundException;
//defining exception handling for all the exceptions
@ControllerAdvice
@RestController
public class CustomizedResponseEntityExceptionHandler extends ResponseEntityExceptionHandler
{
@ExceptionHandler(Exception.class)
//override method of ResponseEntityExceptionHandler class
public final ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request)
{
//creating exception response structure
ExceptionResponse exceptionResponse= new ExceptionResponse(new Date(), ex.getMessage(), request.getDescription(false));
//returning exception structure and Internal Server status
return new ResponseEntity(exceptionResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler(UserNotFoundException.class)
//override method of ResponseEntityExceptionHandler class
public final ResponseEntity<Object> handleUserNotFoundExceptions(UserNotFoundException ex, WebRequest request)
{
//creating exception response structure
ExceptionResponse exceptionResponse= new ExceptionResponse(new Date(), ex.getMessage(), request.getDescription(false));
//returning exception structure and Not Found status
return new ResponseEntity(exceptionResponse, HttpStatus.NOT_FOUND);
}
}
再次切换到 Postman 并发送一个 Get 请求。我们得到了 Status: 404 Not Found 和定义的异常结构。