您好,欢迎来电子发烧友网! ,新用户?[免费注册]

您的位置:电子发烧友网 > 源码下载 > java源码下载 >

Spring Boot框架错误处理

大小:0.5 MB 人气: 2017-09-28 需要积分:1

  《blockquote》 《p》《strong》原文《/strong》:《a href=“https://www.toptal.com/java/spring-boot-rest-api-error-handling”》Guide to Spring Boot REST API Error Handling《/a》 《br》 《strong》作者《/strong》:BRUNO LEITE 《br》 《strong》翻译《/strong》:雁惊寒《/p》 《/blockquote》《p》《em》摘要:本文通过实例介绍了使用Spring Boot在设计API的时候如何正确地对异常进行处理。以下是译文《/em》《/p》《p》API在提供错误消息的同时进行适当的错误处理,是一个非常有用的功能,因为这能让API客户端对问题进行正确地响应。API处理错误的默认行为通常是返回难以理解的堆栈跟踪,而这些对API客户端来说并没有什么用。将错误信息切分成多个字段可以方便API客户端的解析,以此向用户提供更加友好的错误消息。本文将介绍在使用《a href=“https://www.toptal.com/spring”》Spring Boot《/a》构建REST API的时候如何进行合适的错误处理。《/p》《p》《/p》《center》《img src=“?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240” alt=“Person confused about a crypTIc and long error message” TItle=“”》《/center》《p》《/p》《p》在过去几年里,使用Spring构建REST API已经成为Java开发人员的标准方法。而使用Spring Boot则有助于API的构建,因为它删除了大量的样板代码,并实现了各种组件的自动化配置。我们假设你对利用这些技术进行API开发的基础知识已经非常了解。如果你对如何开发基本的REST API并不熟悉,那么你应该先阅读这篇关于《a href=“https://www.toptal.com/spring/beginners-guide-to-mvc-with-spring-framework”》Spring MVC《/a》的文章或另一篇有关《a href=“https://spring.io/guides/gs/rest-service/”》构建Spring REST服务《/a》的文章。《/p》《h2》让错误响应更清晰《/h2》《p》在本文中,我们将实现一个通过REST API来检索鸟类(代表一个对象)的应用程序,《a href=“https://github.com/brunocleite/spring-boot-excepTIon-handling”》代码托管在GitHub上《/a》。这个示例包含了本文描述的所有功能,以及比较多的错误处理场景。以下是该程序实现的端点URL:《/p》《table》 《thead》 《tr》 《th》《/th》 《th》《/th》 《/tr》 《/thead》 《tbody》《tr》 《td》《code》GET /birds/{birdId}《/code》《/td》 《td》获取鸟的相关信息,如果没有找到,则抛出异常。《/td》 《/tr》 《tr》 《td》《code》GET /birds/noexcepTIon/{birdId}《/code》《/td》 《td》这个调用也可以获取鸟的相关信息,但是即使没有找到相应的鸟,也不会抛出异常。《/td》 《/tr》 《tr》 《td》《code》POST /birds《/code》《/td》 《td》创建一只鸟。《/td》 《/tr》 《/tbody》《/table》《p》Spring框架的MVC模块在错误处理方面提供了一些很不错的功能,但是这些功能需要由开发人员主动调用,才能返回对API客户端的有具体意义的响应。《/p》《p》我们来看一下这个Spring Boot默认响应的例子。当我们向《code》/birds《/code》发送一个HTTP POST的时候,消息内容是下面这个JSON对象,字段“mass”的值是字符串“aaa”,这个字段本应该填一个整数:《/p》《pre class=“prettyprint”》《code class=“ hljs json”》{ “《span class=”hljs-attribute“》scientificName《/span》”: 《span class=“hljs-value”》《span class=“hljs-string”》“Common blackbird”《/span》《/span》, “《span class=”hljs-attribute“》specie《/span》”: 《span class=“hljs-value”》《span class=“hljs-string”》“Turdus merula”《/span》《/span》, “《span class=”hljs-attribute“》mass《/span》”: 《span class=“hljs-value”》《span class=“hljs-string”》“aaa”《/span》《/span》, “《span class=”hljs-attribute“》length《/span》”: 《span class=“hljs-value”》《span class=“hljs-number”》4《/span》 《/span》} 《/code》《/pre》《p》Spring Boot的默认响应,没有正确的处理错误:《/p》《pre class=“prettyprint”》《code class=“ hljs scilab”》{ 《span class=“hljs-string”》“timestamp”《/span》: 《span class=“hljs-number”》1500597044204《/span》, 《span class=“hljs-string”》“status”《/span》: 《span class=“hljs-number”》400《/span》, 《span class=“hljs-string”》“error”《/span》: 《span class=“hljs-string”》“Bad Request”《/span》, 《span class=“hljs-string”》“exception”《/span》: 《span class=“hljs-string”》“org.springframework.http.converter.HttpMessageNotReadableException”《/span》, 《span class=“hljs-string”》“message”《/span》: 《span class=“hljs-string”》“JSON parse error: Unrecognized token ‘《/span》《span class=”hljs-transposed_variable“》three’《/span》: was expecting (《span class=”hljs-string“》‘true’《/span》, 《span class=”hljs-string“》‘false’《/span》 《span class=”hljs-built_in“》or《/span》 《span class=”hljs-string“》‘null’《/span》); nested exception is 《span class=”hljs-transposed_variable“》com.《/span》《span class=”hljs-transposed_variable“》fasterxml.《/span》《span class=”hljs-transposed_variable“》jackson.《/span》《span class=”hljs-transposed_variable“》core.《/span》JsonParseException: Unrecognized token 《span class=”hljs-string“》‘aaa’《/span》: was expecting (《span class=”hljs-string“》‘true’《/span》, 《span class=”hljs-string“》‘false’《/span》 《span class=”hljs-built_in“》or《/span》 《span class=”hljs-string“》‘null’《/span》)\n at 《span class=”hljs-matrix“》[Source: java.io.PushbackInputStream@cba7ebc; line: 《span class=”hljs-number“》4《/span》, column: 《span class=”hljs-number“》17《/span》]《/span》《span class=”hljs-string“》”, “《/span》path《span class=”hljs-string“》”: “《/span》/birds《span class=”hljs-string“》” } 《/span》《/code》《/pre》《p》呃…… 响应消息里有一些很有用的字段,但它里面有关异常的内容太多了。 顺便说一句,这是Spring Boot中《code》DefaultErrorAttributes《/code》类的内容。 《code》timestamp《/code》字段是一个整数,不携带什么度量单位的时间戳信息。《code》exception《/code》字段只有Java开发人员会感兴趣,该消息使API消费者迷失在与它们无关的细节中。是否有更多的细节可以从错误产生的异常中提取出来呢? 下面,我们来学习如何正确地处理这些异常,并将它们包装成更好的JSON表示形式,让API客户端更容易识别。《/p》《p》由于我们要使用Java 8的日期和时间类,因此首先需要为Jackson JSR310转换器添加一个Maven依赖关系。这个包使用注解《code》@JsonFormat《/code》将Java 8的日期和时间类转换为JSON:《/p》《pre class=“prettyprint”》《code class=“ hljs xml”》《span class=“hljs-tag”》《《span class=“hljs-title”》dependency《/span》》《/span》 《span class=“hljs-tag”》《《span class=“hljs-title”》groupId《/span》》《/span》com.fasterxml.jackson.datatype《span class=“hljs-tag”》《/《span class=“hljs-title”》groupId《/span》》《/span》 《span class=“hljs-tag”》《《span class=“hljs-title”》artifactId《/span》》《/span》jackson-datatype-jsr310《span class=“hljs-tag”》《/《span class=“hljs-title”》artifactId《/span》》《/span》 《span class=“hljs-tag”》《/《span class=“hljs-title”》dependency《/span》》《/span》 《/code》《/pre》《p》好的,我们来定义一个表示API错误的类。 我们将创建一个名为《code》ApiError《/code》的类,该类用于保存REST调用期间发生错误的相关信息。《/p》《pre class=“prettyprint”》《code class=“language-java hljs ”》class ApiError { 《span class=“hljs-keyword”》private《/span》 HttpStatus status; 《span class=“hljs-annotation”》@JsonFormat《/span》(shape = JsonFormat.Shape.STRING, pattern = 《span class=“hljs-string”》“dd-MM-yyyy hh:mm:ss”《/span》) 《span class=“hljs-keyword”》private《/span》 LocalDateTime timestamp; 《span class=“hljs-keyword”》private《/span》 String message; 《span class=“hljs-keyword”》private《/span》 String debugMessage; 《span class=“hljs-keyword”》private《/span》 List《ApiSubError》 subErrors; 《span class=“hljs-keyword”》private《/span》 《span class=“hljs-title”》ApiError《/span》() { timestamp = LocalDateTime.now(); } ApiError(HttpStatus status) { 《span class=“hljs-keyword”》this《/span》(); 《span class=“hljs-keyword”》this《/span》.status = status; } ApiError(HttpStatus status, Throwable ex) { 《span class=“hljs-keyword”》this《/span》(); 《span class=“hljs-keyword”》this《/span》.status = status; 《span class=“hljs-keyword”》this《/span》.message = 《span class=“hljs-string”》“Unexpected error”《/span》; 《span class=“hljs-keyword”》this《/span》.debugMessage = ex.getLocalizedMessage(); } ApiError(HttpStatus status, String message, Throwable ex) { 《span class=“hljs-keyword”》this《/span》(); 《span class=“hljs-keyword”》this《/span》.status = status; 《span class=“hljs-keyword”》this《/span》.message = message; 《span class=“hljs-keyword”》this《/span》.debugMessage = ex.getLocalizedMessage(); } } 《/code》《/pre》《ul》 《li》《p》《code》status《/code》属性保存了操作调用的状态。 比如,4xx表示客户端错误,5xx意味着服务器错误。 比较常见的情况是:http返回码400表示BAD_REQUEST,例如,客户端发送了格式不正确的字段(如无效的电子邮件地址)。《/p》《/li》 《li》《p》《code》timestamp《/code》属性保存了发生错误的日期时间。《/p》《/li》 《li》《p》《code》message《/code》属性保存了对用户友好的错误信息。《/p》《/li》 《li》《p》《code》debugMessage《/code》属性更详细地描述了错误。《/p》《/li》 《li》《p》《code》subErrors《/code》属性保存了发生的子错误的数组。 这用于表示在单个调用中出现的多个错误。比如,校验的时候有多个字段验证失败。用《code》ApiSubError《/code》类进行封装。《/p》《/li》 《/ul》《pre class=“prettyprint”》《code class=“language-java hljs ”》《span class=“hljs-keyword”》abstract《/span》 class ApiSubError { } 《span class=“hljs-annotation”》@Data《/span》 《span class=“hljs-annotation”》@EqualsAndHashCode《/span》(callSuper = 《span class=“hljs-keyword”》false《/span》) 《span class=“hljs-annotation”》@AllArgsConstructor《/span》 class ApiValidati extends ApiSubError { 《span class=“hljs-keyword”》private《/span》 String object; 《span class=“hljs-keyword”》private《/span》 String field; 《span class=“hljs-keyword”》private《/span》 Object rejectedValue; 《span class=“hljs-keyword”》private《/span》 String message; ApiValidati(String object, String message) { 《span class=“hljs-keyword”》this《/span》.object = object; 《span class=“hljs-keyword”》this《/span》.message = message; } } 《/code》《/pre》《p》《code》ApiValidati《/code》是类《code》ApiSubError《/code》的扩展类,表示REST调用时遇到的校验问题。《/p》《p》下面,你将看到几个JSON响应的例子,这些响应根据我们上面的描述做了改进。《/p》《p》以下这个JSON是在调用URL《code》GET /birds/2《/code》后找不到实体的时候返回的:《/p》《pre class=“prettyprint”》《code class=“ hljs json”》{ “《span class=”hljs-attribute“》apierror《/span》”: 《span class=“hljs-value”》{ “《span class=”hljs-attribute“》status《/span》”: 《span class=“hljs-value”》《span class=“hljs-string”》“NOT_FOUND”《/span》《/span》, “《span class=”hljs-attribute“》timestamp《/span》”: 《span class=“hljs-value”》《span class=“hljs-string”》“18-07-2017 06:20:19”《/span》《/span》, “《span class=”hljs-attribute“》message《/span》”: 《span class=“hljs-value”》《span class=“hljs-string”》“Bird was not found for parameters {id=2}”《/span》 《/span》} 《/span》} 《/code》《/pre》《p》下面是调用《code》POST /birds《/code》时传入了无效值后返回的JSON示例:《/p》《pre class=“prettyprint”》《code class=“ hljs json”》{ “《span class=”hljs-attribute“》apierror《/span》”: 《span class=“hljs-value”》{ “《span class=”hljs-attribute“》status《/span》”: 《span class=“hljs-value”》《span class=“hljs-string”》“BAD_REQUEST”《/span》《/span》, “《span class=”hljs-attribute“》timestamp《/span》”: 《span class=“hljs-value”》《span class=“hljs-string”》“18-07-2017 06:49:25”《/span》《/span》, “《span class=”hljs-attribute“》message《/span》”: 《span class=“hljs-value”》《span class=“hljs-string”》“Validation errors”《/span》《/span》, “《span class=”hljs-attribute“》subErrors《/span》”: 《span class=“hljs-value”》[ { “《span class=”hljs-attribute“》object《/span》”: 《span class=“hljs-value”》《span class=“hljs-string”》“bird”《/span》《/span》, “《span class=”hljs-attribute“》field《/span》”: 《span class=“hljs-value”》《span class=“hljs-string”》“mass”《/span》《/span》, “《span class=”hljs-attribute“》rejectedValue《/span》”: 《span class=“hljs-value”》《span class=“hljs-number”》999999《/span》《/span》, “《span class=”hljs-attribute“》message《/span》”: 《span class=“hljs-value”》《span class=“hljs-string”》“must be less or equal to 104000”《/span》 《/span》} ] 《/span》} 《/span》} 《/code》《/pre》《h2》Spring Boot 错误处理《/h2》《p》我们来探讨一些用于异常处理的Spring注解。《/p》《p》《a href=“https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RestController.html”》《code》RestController《/code》《/a》是用于REST操作类的最基本的注解。《/p》《p》《a href=“https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ExceptionHandler.html”》《code》ExceptionHandler《/code》《/a》这个Spring注解提供了一种机制,用来处理在执行程序期间抛出的异常。此注解将作为处理此控制器中抛出的异常的入口点。总而言之,最常见的方法是在《code》@ControllerAdvice《/code》类的方法上使用《code》@ExceptionHandler《/code》,以便将异常处理应用于全局或控制器的子集。《/p》《p》《a href=“https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ControllerAdvice.html”》《code》ControllerAdvice《/code》《/a》是Spring 3.2中引入的注解,顾名思义,它是多控制器的“建议”。它使得单个《code》ExceptionHandler《/code》应用于多个控制器上。这样我们可以在一个地方定义如何处理这样的异常,当《code》ControllerAdvice《/code》覆盖的类抛出异常时,这个处理程序就会被调用。受影响的控制器子集可以在《code》@ControllerAdvice《/code》上使用以下选择器进行定义:《code》annotations()《/code》,《code》basePackageClasses()《/code》和《code》basePackages()《/code》。如果没有提供选择器,则《code》ControllerAdvice《/code》将应用于全局所有的控制器。《/p》《p》所以,通过使用《code》@ExceptionHandler《/code》和《code》@ControllerAdvice《/code》,我们可以定义一个用于处理异常的中心点,并将异常包装在《code》ApiError《/code》对象中,这比Spring Boot默认的错误处理机制更好。《/p》《h2》处理异常《/h2》《p》《/p》《center》《img src=“?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240” alt=“Representation of what happens with a successful and failed REST client call” title=“”》《/center》《p》《/p》《p》下一步是创建处理异常的类。为了简单起见,我们称之为《code》RestExceptionHandler《/code》,它必须继承自Spring Boot的《code》ResponseEntityExceptionHandler《/code》。我们也将从《code》ResponseEntityExceptionHandler《/code》继承,因为它已经提供了对Spring MVC异常的一些基本处理方法,所以,我们将改进现有的异常处理手段,并同时添加针对新异常的处理。《/p》《p》如果看一下《code》ResponseEntityExceptionHandler《/code》的源代码,你会看到有很多方法名为《code》handle******()《/code》,像《code》handleHttpMessageNotReadable()《/code》或《code》handleHttpMessageNotWritable()《/code》。我们来看看如何对《code》handleHttpMessageNotReadable()《/code》进行扩展来处理《code》HttpMessageNotReadableException《/code》异常。我们只需要在《code》RestExceptionHandler《/code》类中重写方法《code》handleHttpMessageNotReadable()《/code》:《/p》《pre class=“prettyprint”》《code class=“language-java hljs ”》《span class=“hljs-annotation”》@Order《/span》(Ordered.HIGHEST_PRECEDENCE) 《span class=“hljs-annotation”》@ControllerAdvice《/span》 《span class=“hljs-keyword”》public《/span》 《span class=“hljs-class”》《span class=“hljs-keyword”》class《/span》 《span class=“hljs-title”》RestExceptionHandler《/span》 《span class=“hljs-keyword”》extends《/span》 《span class=“hljs-title”》ResponseEntityExceptionHandler《/span》 {《/span》 《span class=“hljs-annotation”》@Override《/span》 《span class=“hljs-keyword”》protected《/span》 ResponseEntity《Object》 《span class=“hljs-title”》handleHttpMessageNotReadable《/span》(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { String error = 《span class=“hljs-string”》“Malformed JSON request”《/span》; 《span class=“hljs-keyword”》return《/span》 buildResponseEntity(《span class=“hljs-keyword”》new《/span》 ApiError(HttpStatus.BAD_REQUEST, error, ex)); } 《span class=“hljs-keyword”》private《/span》 ResponseEntity《Object》 《span class=“hljs-title”》buildResponseEntity《/span》(ApiError apiError) { 《span class=“hljs-keyword”》return《/span》 《span class=“hljs-keyword”》new《/span》 ResponseEntity《》(apiError, apiError.getStatus()); } 《span class=“hljs-comment”》//other exception handlers below《/span》 } 《/code》《/pre》《p》如果抛出一个《code》HttpMessageNotReadableException《/code》,则错误消息将是“Malformed JSON request(格式错误的JSON请求)”,该错误封装在《code》ApiError《/code》对象内。下面我们可以看到新的应答:《/p》《pre class=“prettyprint”》《code class=“ hljs scilab”》{ 《span class=“hljs-string”》“apierror”《/span》: { 《span class=“hljs-string”》“status”《/span》: 《span class=“hljs-string”》“BAD_REQUEST”《/span》, 《span class=“hljs-string”》“timestamp”《/span》: 《span class=“hljs-string”》“21-07-2017 03:53:39”《/span》, 《span class=“hljs-string”》“message”《/span》: 《span class=“hljs-string”》“Malformed JSON request”《/span》, 《span class=“hljs-string”》“debugMessage”《/span》: 《span class=“hljs-string”》“JSON parse error: Unrecognized token ‘《/span》《span class=”hljs-transposed_variable“》aaa’《/span》: was expecting (《span class=”hljs-string“》‘true’《/span》, 《span class=”hljs-string“》‘false’《/span》 《span class=”hljs-built_in“》or《/span》 《span class=”hljs-string“》‘null’《/span》); nested exception is 《span class=”hljs-transposed_variable“》com.《/span》《span class=”hljs-transposed_variable“》fasterxml.《/span》《span class=”hljs-transposed_variable“》jackson.《/span》《span class=”hljs-transposed_variable“》core.《/span》JsonParseException: Unrecognized token 《span class=”hljs-string“》‘aaa’《/span》: was expecting (《span class=”hljs-string“》‘true’《/span》, 《span class=”hljs-string“》‘false’《/span》 《span class=”hljs-built_in“》or《/span》 《span class=”hljs-string“》‘null’《/span》)\n at 《span class=”hljs-matrix“》[Source: java.io.PushbackInputStream@《span class=”hljs-number“》7《/span》b5e8d8a; line: 《span class=”hljs-number“》4《/span》, column: 《span class=”hljs-number“》17《/span》]《/span》《span class=”hljs-string“》” } } 《/span》《/code》《/pre》《h3》处理自定义异常《/h3》《p》现在,我们来看看如何创建一个方法来处理没有在Spring Boot的《code》ResponseEntityExceptionHandler《/code》中声明的异常。《/p》《p》Spring程序处理数据库调用的一个常见场景是使用库类通过id去查找记录。但是,如果研究一下《code》CrudRepository.findOne()《/code》方法,我们会发现,如果找不到对象,它将返回《code》null《/code》。这意味着如果我们的服务只是调用这个方法并直接返回给控制器,那么即使找不到资源,我们也会得到HTTP返回码200(OK)。实际上,正确的方法是返回《a href=“https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html”》HTTP/1.1规范《/a》中指定的HTTP返回码404(NOT FOUND)。《/p》《p》为了处理这种情况,我们将创建一个名为《code》EntityNotFoundException《/code》的自定义异常。它与《code》javax.persistence.EntityNotFoundException《/code》不同,因为它提供的一些构造函数可以用来选择以不同的方式处理《code》javax.persistence《/code》异常。《/p》《p》《/p》《center》《img src=“?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240” alt=“Example of a failed REST call” title=“”》《/center》《p》《/p》《p》也就是说,我们可以在《code》RestExceptionHandler《/code》类中为这个新创建的《code》EntityNotFoundException《/code》创建一个《code》ExceptionHandler《/code》。为此,创建一个名为《code》handleEntityNotFound()《/code》的方法,并使用《code》@ExceptionHandler《/code》对其进行注释,将类对象《code》EntityNotFoundException.class《/code》传递给它。这表示每次抛出《code》EntityNotFoundException《/code》的时候,Spring应该调用此方法来处理它。当用《code》@ExceptionHandler《/code》注释一个方法时,它将接受各种自动注入的参数,如《code》WebRequest《/code》、《code》Locale《/code》,以及在《a href=“https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ExceptionHandler.html”》这里《/a》提到的其他参数。我们将提供异常《code》EntityNotFoundException《/code》本身作为《code》handleEntityNotFound《/code》方法的参数。《/p》《pre class=“prettyprint”》《code class=“language-java hljs ”》《span class=“hljs-annotation”》@Order《/span》(Ordered.HIGHEST_PRECEDENCE) 《span class=“hljs-annotation”》@ControllerAdvice《/span》 《span class=“hljs-keyword”》public《/span》 《span class=“hljs-class”》《span class=“hljs-keyword”》class《/span》 《span class=“hljs-title”》RestExceptionHandler《/span》 《span class=“hljs-keyword”》extends《/span》 《span class=“hljs-title”》ResponseEntityExceptionHandler《/span》 {《/span》 《span class=“hljs-comment”》//other exception handlers《/span》 《span class=“hljs-annotation”》@ExceptionHandler《/span》(EntityNotFoundException.class) 《span class=“hljs-keyword”》protected《/span》 ResponseEntity《Object》 《span class=“hljs-title”》handleEntityNotFound《/span》( EntityNotFoundException ex) { ApiError apiError = 《span class=“hljs-keyword”》new《/span》 ApiError(NOT_FOUND); apiError.setMessage(ex.getMessage()); 《span class=“hljs-keyword”》return《/span》 buildResponseEntity(apiError); } } 《/code》《/pre》《p》太好了!我们在《code》handleEntityNotFound()《/code》方法里将HTTP状态代码设置为《code》NOT_FOUND《/code》,并使用了新的异常消息。以下是《code》GET /birds/2《/code》的响应示例:《/p》《pre class=“prettyprint”》《code class=“ hljs json”》{ “《span class=”hljs-attribute“》apierror《/span》”: 《span class=“hljs-value”》{ “《span class=”hljs-attribute“》status《/span》”: 《span class=“hljs-value”》《span class=“hljs-string”》“NOT_FOUND”《/span》《/span》, “《span class=”hljs-attribute“》timestamp《/span》”: 《span class=“hljs-value”》《span class=“hljs-string”》“21-07-2017 04:02:22”《/span》《/span》, “《span class=”hljs-attribute“》message《/span》”: 《span class=“hljs-value”》《span class=“hljs-string”》“Bird was not found for parameters {id=2}”《/span》 《/span》} 《/span》} 《/code》《/pre》《h2》结论《/h2》《p》对异常处理的控制非常重要,所以我们需要将这些异常正确映射到《code》ApiError《/code》对象上,以提供给API客户端一些重要的信息,让它们知道发生了。接下来的步骤就是为抛出的异常创建更多的处理方法(带有@ExceptionHandler的方法)。你可以在《a href=“https://github.com/brunocleite/spring-boot-exception-handling”》GitHub代码仓库《/a》中找到更多的示例。《/p》《p》这里另外还有一些资源,可对本文起到补充作用:《/p》《ul》 《li》Baeldung - 《a href=“http://www.baeldung.com/exception-handling-for-rest-with-spring”》使用Spring对REST进行错误处理《/a》《/li》 《li》Spring Blog - 《a href=“https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc”》Spring MVC中的异常处理《/a》《/li》 《/ul》

非常好我支持^.^

(0) 0%

不好我反对

(0) 0%

      发表评论

      用户评论
      评价:好评中评差评

      发表评论,获取积分! 请遵守相关规定!