为所有资源实现通用的异常处理

正如之前讨论的,我们应该定义一个标准的异常结构,使其在所有的 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

restful-web-services-exception-handling.png

步骤 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 和我们定义的异常结构。

restful-web-services-exception-handling2.png

如果我们想将状态 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 和定义的异常结构。
restful-web-services-exception-handling3.png

标签: spring, Spring教程, Spring语言学习, Spring框架, Spring框架教程, Spring框架高级教程, spring boot, spring boot入门教程, spring boot学习教程, spring boot下载, spring boot框架入门, spring boot面试题, spring boot笔试题, spring boot技术, 学习指南