gpt4 book ai didi

java - Spring Boot - 使用RestControllerAdvice的全局自定义异常处理机制

转载 作者:行者123 更新时间:2023-11-30 02:27:07 29 4
gpt4 key购买 nike

我正在使用 Spring Boot 来实现 Restful Web 服务。

尝试设置一个全局自定义异常处理机制,该机制依赖于@RestControllerAdvice,它可以处理已知但也未知的异常。

pom.xml

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
</parent>

<properties>
<java.version>1.8</java.version>
</properties>

<repositories>
<repository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</repository>
</repositories>

<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>

<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

全局 Controller 异常处理程序:

@RestControllerAdvice
public class GlobalControllerExceptionHandler {

private static final Logger LOG = Logger.getLogger(GlobalControllerExceptionHandler.class);

@ExceptionHandler(value = { ConstraintViolationException.class })
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ApiErrorResponse constraintViolationException(ConstraintViolationException ex) {
LOG.error(ex.getCause().toString());
return new ApiErrorResponse(400, "Bad Request");
}

@ExceptionHandler(value = { NoHandlerFoundException.class })
@ResponseStatus(HttpStatus.NOT_FOUND)
public ApiErrorResponse noHandlerFoundException(Exception ex) {
LOG.error(ex.getCause().toString());
return new ApiErrorResponse(404, "Resource Not Found");
}

@ExceptionHandler(value = { Exception.class })
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ApiErrorResponse unknownException(Exception ex) {
LOG.error(ex.getCause().toString());
return new ApiErrorResponse(500, "Internal Server Error");
}
}

API错误响应:

public class ApiErrorResponse {

private int status;
private String message;

public ApiErrorResponse(int status, String message) {
this.status = status;
this.message = message;
}

public int getStatus() {
return status;
}

public String getMessage() {
return message;
}

@Override
public String toString() {
return new ToStringBuilder(this).append(status)
.append(message)
.toString();
}
}

问题是当我使用第三方库来做某事时,未知异常可能是 404,但返回为 500!

例如使用具有未知索引的 ElasticSearch(故意查看异常类型):

{
"timestamp": 1501236796640,
"status": 500,
"error": "Internal Server Error",
"exception": "org.elasticsearch.client.ResponseException",
"message": "POST http://localhost:9200/fn3r4343/_search?pretty=true: HTTP/1.1 404 Not Found"
{
"error": {
"root_cause": [
{
"type": "index_not_found_exception",
"reason": "no such index",
"resource.type": "index_or_alias",
"resource.id": "fn3r4343",
"index_uuid": "_na_",
"index": "fn3r4343"
}
],
"type": "index_not_found_exception",
"reason": "nosuchindex",
"resource.type": "index_or_alias",
"resource.id": "fn3r4343",
"index_uuid": "_na_",
"index": "fn3r4343"
}
{ "root_cause" :
[
{
"type" :"index_not_found_exception",
"reason" : no such index", "resource.type" : "index_or_alias",
"resource.id" : "fn3r4343",
"index_uuid" : "_na_",
"index" : "fn3r4343"
}
],
[
{
"type" : "index_not_found_exception",
"reason" : "no such index",
"resource.type" : "index_or_alias",
"resource.id" : "fn3r4343",
"index_uuid" : "_na_",
"index" : "fn3r4343"
},
"status": 404
]
}
"path": "/myapp/search"
}

正如我们所见,这会返回 HTTP 500 状态,但在有效负载中,它实际上是 HTTP 404!

我想要返回的是:

{ 
"message" : "Index Not Found Exception",
"status" : "HTTP 404"
}

对于已知的 HTTP 404 异常:

{ 
"message" : "Not Found",
"status" : "HTTP 404"
}

是否有良好的实践/机制来使用 RestControllerAdvice 捕获任何类型的异常并将响应自定义为 JSON 格式,该格式对使用 REST API 的客户端可读/有用?

这篇文章并不是专门针对 Elastic Search 的,而是寻求如何通过尝试使用 @RestControllerAdvice 处理任何类型的异常,为客户端应用程序提供正确的响应...

最佳答案

引发的底层异常是 org.elasticsearch.client.ResponseException(您可能正在使用低级 REST 客户端)。

因此,在您的建议中,您需要为该异常添加一个处理程序并返回底层状态代码:

@ExceptionHandler(value = { ResponseException.class })
public ApiErrorResponse noHandlerFoundException(Exception ex) {
LOG.error(ex.getCause().toString());
int status = ((ResponseException) ex).getResponse().getStatusLine().getStatusCode();
return new ApiErrorResponse(status, "<some message depending on status code>");
}

关于java - Spring Boot - 使用RestControllerAdvice的全局自定义异常处理机制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45371429/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com