使用ControllerAdvice自定义NohandLerexception响应
我尝试在Spring Boot REST应用程序中实现一个自定义错误响应,以解决404个错误。 我阅读了Stackoverflow中介绍的许多解决方案,没有成功。
当我调用一个无效的入口点时,我会获得此结果:
{
"timestamp": "2022-06-22T10:38:41.114+00:00",
"status": 404,
"error": "Not Found",
"path": "/ws-facturx/fx2"
}
但是我想有一个应该这样的响应:
{
"operationId": "u044eZg2gHwtadqxB5CVv6aeMBjj0w",
"status": "ERROR",
"operation": "webserviceName",
"clientName": "ACME Inc",
"errorMessage": "Error message from Server",
"createdAt": "2022-06-22T09:15:04.844+00:00"
}
我首先尝试使用@RestControllerAdvice在投掷时拦截异常。
@ExceptionHandler(value = {AppServiceException.class, NoHandlerFoundException.class, ServletServiceException.class })
public ResponseEntity<Object> handleAppServiceException(Exception ex,
WebRequest req) throws JsonProcessingException {
FacturxDto request = context.getFacturxDtoContext();
ErrorMessage errorMessage = errorMessageBuilder(request, ex);
return new ResponseEntity<>(errorMessage, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
}
我还修改了我的应用程序
spring.mvc.throw-exception-if-no-handler-found=true
spring.web.resources.add-mappings=false
。我试图使用拦截器。 我向添加了一个用于将拦截器添加到InterceptorRegistry的课程:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
private final ApplicationExchangeContext context;
public WebMvcConfig(ApplicationExchangeContext context) {
this.context = context;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new ApplicationInterceptor(context)).addPathPatterns("/**");
}
}
我的ApplicationInterspection看起来像这样:
@Component
public class ApplicationInterceptor implements HandlerInterceptor {
private final ApplicationExchangeContext context;
@Autowired
public ApplicationInterceptor(ApplicationExchangeContext context) {
this.context = context;
}
//unimplemented methods comes here. Define the following method so that it
//will handle the request before it is passed to the controller.
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (response.getStatus() == HttpStatus.NOT_FOUND.value()) {
// si on a un 404
System.out.println(handler);
String requestData = request.getReader().lines().collect(Collectors.joining());
System.out.println(requestData);
Gson gson = new Gson();
FacturxDto facturxDto = gson.fromJson(requestData, FacturxDto.class);
context.setFacturxDtoContext(facturxDto);
throw new ServletServiceException("404...");
}
System.out.println("Done in preHandle");
return true;
// return HandlerInterceptor.super.preHandle(request, response, handler);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
System.out.println(request);
System.out.println(response);
if (response.getStatus() == HttpStatus.NOT_FOUND.value()) {
// si on a un 404
System.out.println(handler);
String requestData = request.getReader().lines().collect(Collectors.joining());
System.out.println(requestData);
Gson gson = new Gson();
FacturxDto facturxDto = gson.fromJson(requestData, FacturxDto.class);
context.setFacturxDtoContext(facturxDto);
throw new ServletServiceException("404...");
}
System.out.println("Done in afterCompletion");
}
}
在预汉中,我确实到达了代码块的捕获部分,但我无法访问应该处理此例外并构建我的预期对象的RestControllerRADVICE方法。
抛出了例外。但是我不会将其退还给用户。相反,我确实有一个HTML页面。
I try to implement a custom error response in a spring boot rest application for 404 errors.
I read many of the solutions presented in stackoverflow, without success.
When I call an invalid entry point I obtain this result:
{
"timestamp": "2022-06-22T10:38:41.114+00:00",
"status": 404,
"error": "Not Found",
"path": "/ws-facturx/fx2"
}
But i'd like to have a response that should look like this:
{
"operationId": "u044eZg2gHwtadqxB5CVv6aeMBjj0w",
"status": "ERROR",
"operation": "webserviceName",
"clientName": "ACME Inc",
"errorMessage": "Error message from Server",
"createdAt": "2022-06-22T09:15:04.844+00:00"
}
I first tried to use @RestControllerAdvice to intercept the exception when they are thrown.
@ExceptionHandler(value = {AppServiceException.class, NoHandlerFoundException.class, ServletServiceException.class })
public ResponseEntity<Object> handleAppServiceException(Exception ex,
WebRequest req) throws JsonProcessingException {
FacturxDto request = context.getFacturxDtoContext();
ErrorMessage errorMessage = errorMessageBuilder(request, ex);
return new ResponseEntity<>(errorMessage, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
}
I also modified my application.properties :
spring.mvc.throw-exception-if-no-handler-found=true
spring.web.resources.add-mappings=false
If i call a non defined entry point I do not reach this method. I tried to use an interceptor.
I firs added a class for adding interceptor to InterceptorRegistry:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
private final ApplicationExchangeContext context;
public WebMvcConfig(ApplicationExchangeContext context) {
this.context = context;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new ApplicationInterceptor(context)).addPathPatterns("/**");
}
}
My ApplicationInterception looks like this:
@Component
public class ApplicationInterceptor implements HandlerInterceptor {
private final ApplicationExchangeContext context;
@Autowired
public ApplicationInterceptor(ApplicationExchangeContext context) {
this.context = context;
}
//unimplemented methods comes here. Define the following method so that it
//will handle the request before it is passed to the controller.
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (response.getStatus() == HttpStatus.NOT_FOUND.value()) {
// si on a un 404
System.out.println(handler);
String requestData = request.getReader().lines().collect(Collectors.joining());
System.out.println(requestData);
Gson gson = new Gson();
FacturxDto facturxDto = gson.fromJson(requestData, FacturxDto.class);
context.setFacturxDtoContext(facturxDto);
throw new ServletServiceException("404...");
}
System.out.println("Done in preHandle");
return true;
// return HandlerInterceptor.super.preHandle(request, response, handler);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
System.out.println(request);
System.out.println(response);
if (response.getStatus() == HttpStatus.NOT_FOUND.value()) {
// si on a un 404
System.out.println(handler);
String requestData = request.getReader().lines().collect(Collectors.joining());
System.out.println(requestData);
Gson gson = new Gson();
FacturxDto facturxDto = gson.fromJson(requestData, FacturxDto.class);
context.setFacturxDtoContext(facturxDto);
throw new ServletServiceException("404...");
}
System.out.println("Done in afterCompletion");
}
}
On the preHandle, i do reach the catch part of the code block but i do not access the RestControllerAdvice method that should handle this exception and build my expected object.
The exception is thrown. But i do not return it to user. Instead I do have an HTML page.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论