跟进之前的Spring Boot异常处理问题-与现有错误处理共存的最佳方式



这是关于Spring Boot异常处理的早期问题的后续问题:

试图让Spring Boot应用程序在请求没有"错误"时发送错误响应消息;内容类型";HTTP请求头

在前面的线程之前,我们已经有了一个扩展ResponseEntityExceptionHandler的类(名为"myResponseEntityExceptionHandler"(,它处理了一个验证异常,也是一个包罗万象的类。

但当我测试新的SpringExceptionHandler(来自尝试让SpringBoot应用程序在请求没有"内容类型"HTTP请求头时发送错误响应消息(时,我发现我必须删除已经存在的类,为了让SpringExceptionHandler工作(如果我记得的话,如果两者都在构建中,那么SpringExceptionHandler中的代码就从未使用过(。

既然我已经有了SpringExceptionHandler,我想尝试使它发挥作用,这样我们既可以处理已经存在的类处理的异常,也可以处理SpringExceptionHandler处理的异常。

所以我想知道你们会推荐什么方法来做到这一点?

  • 修改较新的SpringExceptionHandler以合并处理验证异常AND也成为异常的全部?

  • 也许可以修改已经存在的类或SpringExceptionHandler,使它们可以共存并工作?

  • 或者可能还有其他方法?

仅供参考,这里是";myResponseEntityExceptionHandler";类别:

package xxx....errorhandling;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import xxx.....ErrorResponse;
/**
* 
* Error handler
* 
* Any exception thrown by Controllers will be captured by this exception handler
* and after logging a complete stack trace it will send minimal error message with
* status code to the caller.   
* 
*
*/
@ControllerAdvice
public class myResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
private static final Logger logger = LogManager.getLogger(myResponseEntityExceptionHandler.class);
/**
*  This method will catch errors on malformed request payloads
*  TODO: Send more user friendly error messages describing the error.
*/
@Override
protected ResponseEntity<Object> handleHttpMessageNotReadable(final HttpMessageNotReadableException ex,
HttpHeaders headers, HttpStatus status, final WebRequest request) {
logger.error("Error: Unable to process request.", ex);
String error = ex.getLocalizedMessage();
Throwable innerThrowable = ex.getCause();

if (innerThrowable instanceof MismatchedInputException) {
MismatchedInputException mismatchEx = (MismatchedInputException) innerThrowable;
error = "Invalid input message: " + mismatchEx.getOriginalMessage() 
+ " at line: " + mismatchEx.getLocation().getLineNr()
+ " column: " + mismatchEx.getLocation().getColumnNr();
}

final ErrorResponse apiError = new ErrorResponse(HttpStatus.BAD_REQUEST.value(), error);
return new ResponseEntity<Object>(apiError, new HttpHeaders(),HttpStatus.BAD_REQUEST);
}
/**
* Catch errors relating to validation of the request message.
* @param ex
* @param request
* @return
*/
@ExceptionHandler({ RequestValidationException.class })
protected ResponseEntity<Object> handleMethodArgumentTypeMismatch(final RequestValidationException ex,
final WebRequest request) {
logger.error("Error: Unable to process request.", ex);
final String error = "Missing or invalid parameters - " + ex.getMessage();
final ErrorResponse apiError = new ErrorResponse(HttpStatus.BAD_REQUEST.value(), error);
return new ResponseEntity<Object>(apiError, new HttpHeaders(), HttpStatus.BAD_REQUEST);
}

}

再次感谢!

Jim

编辑2:当我试图组合来自新的";SpringExceptionHandler";与原件";myResponseEntityExceptionHandler";,获取:

package .....errorhandling;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import ......ErrorResponse;
/**
* 
* Error handler
* 
* Any exception thrown by Controllers will be captured by this exception handler
* and after logging a complete stack trace it will send minimal error message with
* status code to the caller.   
* 
*
*/
@ControllerAdvice
public class myResponseEntityExceptionHandler extends     ResponseEntityExceptionHandler {
private static final Logger logger =     LogManager.getLogger(myResponseEntityExceptionHandler.class);
/**
*  This method will catch errors on malformed request payloads
*  TODO: Send more user friendly error messages describing the error.
*/
@Override
protected ResponseEntity<Object> handleHttpMessageNotReadable(final HttpMessageNotReadableException ex,
HttpHeaders headers, HttpStatus status, final WebRequest request) {
logger.error("Error: Unable to process request.", ex);
String error = ex.getLocalizedMessage();
Throwable innerThrowable = ex.getCause();

if (innerThrowable instanceof MismatchedInputException) {
MismatchedInputException mismatchEx = (MismatchedInputException) innerThrowable;
error = "Invalid input message: " + mismatchEx.getOriginalMessage() 
+ " at line: " + mismatchEx.getLocation().getLineNr()
+ " column: " + mismatchEx.getLocation().getColumnNr();
}

final ErrorResponse apiError = new ErrorResponse(HttpStatus.BAD_REQUEST.value(), error);
return new ResponseEntity<Object>(apiError, new HttpHeaders(),HttpStatus.BAD_REQUEST);
}
/**
* Catch errors relating to validation of the request message.
* @param ex
* @param request
* @return
*/
@ExceptionHandler({ RequestValidationException.class })
protected ResponseEntity<Object> handleMethodArgumentTypeMismatch(final RequestValidationException ex,
final WebRequest request) {
logger.error("Error: Unable to process request.", ex);
final String error = "Missing or invalid parameters - " + ex.getMessage();
final ErrorResponse apiError = new ErrorResponse(HttpStatus.BAD_REQUEST.value(), error);
return new ResponseEntity<Object>(apiError, new HttpHeaders(), HttpStatus.BAD_REQUEST);
}

/**
* Catch errors where the request either does not include "Content-type" header or the value of "Content-type" header is not one that handled.
* @param ex
* @param request
* @return
*/
@ExceptionHandler(org.springframework.web.HttpMediaTypeNotSupportedException.class)
public ResponseEntity <Object> handleControllerException(final HttpMediaTypeNotSupportedException ex, final WebRequest req)
{
ErrorResponse errorResponse = null;
//ex.printStackTrace();
errorResponse = new ErrorResponse();
//errorResponse.setCode(HttpCodes.HTTP_CODE_INTERNAL_ERROR);
System.out.println("In SpringExceptionHandler.handleControllerException: HttpStatus.INTERNAL_SERVER_ERROR.value()=[" + HttpStatus.INTERNAL_SERVER_ERROR.value() + "]");
System.out.println("In SpringExceptionHandler.handleControllerException: ex.getMessage()=[" + ex.getMessage() + "]");
int myCode = errorResponse.getCode();
System.out.println("In SpringExceptionHandler.handleControllerException: errorResponse.getCode()/String.valueOf(myCode)=[" + String.valueOf(myCode) + "]");

errorResponse.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
errorResponse.setMessage(ex.getMessage());
myCode = errorResponse.getCode();
System.out.println("In SpringExceptionHandler.handleControllerException: errorResponse.getCode()/String.valueOf(myCode)=[" + String.valueOf(myCode) + "]");
//return new ResponseEntity<Object>(errorResponse, HttpStatus.valueOf(errorResponse.getCode()));
//return new ResponseEntity<Object>(HttpStatus.INTERNAL_SERVER_ERROR);
return ResponseEntity
.status(HttpStatus.valueOf(415))
.body(ex.getMessage());

} // end handleControllerException()

} // end CLASS myResponseEntityExceptionHandler

构建失败,出现";模棱两可的"错误:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerExceptionResolver]: Factory method 'handlerExceptionResolver' threw exception; nested exception is java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.HttpMediaTypeNotSupportedException]: {public org.springframework.http.ResponseEntity ......errorhandling.PDPResponseEntityExceptionHandler.handleControllerException(org.springframework.web.HttpMediaTypeNotSupportedException,org.springframework.web.context.request.WebRequest), public final org.springframework.http.ResponseEntity org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest) throws java.lang.Exception}
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.12.jar:5.3.12]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.12.jar:5.3.12]
... 85 more

从谷歌搜索SO来看;模棱两可的"意味着我正在复制一个类,但从上面的源代码来看,我没有看到任何?

谢谢,Jim

我能够使用一种方法,使用两个独立的类。

我要做的是添加一个"@订单"注释到SpringExceptionHandler类,以将其设置为";最高优先级";。

这是工作代码:

package ......errorhandling;
import org.apache.logging.log4j.LogManager;
import org.springframework.http.ResponseEntity;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
import ......models.ErrorResponse;
import org.springframework.core.annotation.Order;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
@ControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SpringExceptionHandler // extends    ExceptionHandlerExceptionResolver
{
@ExceptionHandler(org.springframework.web.HttpMediaTypeNotSupportedException.class)
public ResponseEntity handleControllerException(HttpMediaTypeNotSupportedException ex, WebRequest req)
{
ErrorResponse errorResponse = null;

errorResponse = new ErrorResponse();
errorResponse.setCode(HttpCodes.HTTP_CODE_INTERNAL_ERROR);
System.out.println("In SpringExceptionHandler.handleControllerException: HttpStatus.INTERNAL_SERVER_ERROR.value()=[" + HttpStatus.INTERNAL_SERVER_ERROR.value() + "]");
System.out.println("In SpringExceptionHandler.handleControllerException: ex.getMessage()=[" + ex.getMessage() + "]");
int myCode = errorResponse.getCode();
System.out.println("In SpringExceptionHandler.handleControllerException: errorResponse.getCode()/String.valueOf(myCode)=[" + String.valueOf(myCode) + "]");

errorResponse.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
errorResponse.setMessage(ex.getMessage());
myCode = errorResponse.getCode();
System.out.println("In SpringExceptionHandler.handleControllerException: errorResponse.getCode()/String.valueOf(myCode)=[" + String.valueOf(myCode) + "]");
return ResponseEntity
.status(HttpStatus.valueOf(415))
.body(ex.getMessage());

}
}

最新更新