Spring框架接受自定义转换器的异常
我面临着Spring(和kotlin?)的一个问题,我的全局错误处理程序无法捕获自定义转换器中抛出的任何异常 我知道spring默认支持string->UUID映射,但我想明确检查是否确实引发了异常。它是下面的转换器。无论我自己是否实现了转换器,行为都是相同的 我的WebMvcConfuguration如下所示:Spring框架接受自定义转换器的异常,spring,spring-mvc,kotlin,Spring,Spring Mvc,Kotlin,我面临着Spring(和kotlin?)的一个问题,我的全局错误处理程序无法捕获自定义转换器中抛出的任何异常 我知道spring默认支持string->UUID映射,但我想明确检查是否确实引发了异常。它是下面的转换器。无论我自己是否实现了转换器,行为都是相同的 我的WebMvcConfuguration如下所示: @Configuration class WebMvcConfiguration : WebMvcConfigurerAdapter() { override fun add
@Configuration
class WebMvcConfiguration : WebMvcConfigurerAdapter() {
override fun addFormatters(registry: FormatterRegistry) {
super.addFormatters(registry)
registry.addConverter(Converter<String, UUID> { str ->
try {
UUID.fromString(str)
} catch(e: IllegalArgumentException){
throw RuntimeException(e)
}
})
}
最后,控制器:
@Controller
class MyController : ApiBaseController() {
@GetMapping("/something/{id}")
fun getSomething(@PathVariable("id") id: UUID) {
throw NotImplementedError()
}
}
控制器(例如NotImplementedError)方法中的异常被捕获得很好。但是当传递无效UUID时,转换器内抛出的IllegalArgumentException被吞没,spring返回一个空的400响应
我现在的问题是:如何捕捉这些错误并用自定义错误消息进行响应
提前谢谢 经过反复尝试,我找到了一个解决方案: 不是使用
@ControllerAdvice
,而是实现其他人从中继承的BaseController并在其中添加异常处理程序
因此,我的基本控制器如下所示:
abstract class ApiBaseController{
@ExceptionHandler(Exception::class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
fun handleException(ex: Exception): ApiError {
return ApiError(ex.message)
}
}
如果有人能详细说明为什么它是这样工作的,而不是相反,请这样做,我会将您的答案标记为接受。我也有同样的问题。Spring吞下了任何
IllegalArgumentException
(conversionfailedeexception
)
得到我想要的行为;i、 e.仅处理列出的异常并对其他异常使用默认行为,不能扩展ResponseEntityExceptionHandler
例如:
@ControllerAdvice
public class RestResponseEntityExceptionHandler{
@ExceptionHandler(value = {NotFoundException.class})
public ResponseEntity<Object> handleNotFound(NotFoundException e, WebRequest request){
return new ResponseEntity<>(e.getMessage(), new HttpHeaders(), HttpStatus.NOT_FOUND);
}
}
@ControllerAdvice
公共类ResponseEntityExceptionHandler{
@ExceptionHandler(值={NotFoundException.class})
public ResponseEntity handleNotFound(NotFound异常,WebRequest请求){
返回新的ResponseEntity(例如getMessage(),new HttpHeaders(),HttpStatus.NOT_FOUND);
}
}
我检查了@georg moser的解决方案。起初,它看起来不错,但它似乎包含了另一个问题。它将所有异常转换为HTTP代码500,这是一个不总是想要的东西
相反,我决定从ResponseEntityExceptionHandler
覆盖handleExceptionInternal
方法
在我的例子中,记录错误就足够了,因此我最终得出以下结论:
@Override
@NonNull
protected ResponseEntity<Object> handleExceptionInternal(@Nonnull final Exception e,
final Object body,
final HttpHeaders headers,
final HttpStatus status,
@Nonnull final WebRequest request) {
final ResponseEntity<Object> responseEntity = super.handleExceptionInternal(e, body, headers, status, request);
logGenericException(e);
return responseEntity;
}
@覆盖
@非空
受保护的响应handleExceptionInternal(@Nonnull final Exception e,
最终目标体,
最终HttpHeaders,
最终HttpStatus状态,
@非Null(最终WebRequest请求){
final ResponseEntity ResponseEntity=super.handleExceptionInternal(e、body、header、status、request);
LogGenericeException(e);
返回响应性;
}
我希望有帮助 如果您能解释一下否决票的原因,我们将不胜感激。谢谢!扩展ResponseEntityExceptionHandler对我来说也是个问题。删除它解决了这个问题。我认为值得一提的是,它将所有异常转换为HTTP代码500,这是人们并不总是想要的。
@Override
@NonNull
protected ResponseEntity<Object> handleExceptionInternal(@Nonnull final Exception e,
final Object body,
final HttpHeaders headers,
final HttpStatus status,
@Nonnull final WebRequest request) {
final ResponseEntity<Object> responseEntity = super.handleExceptionInternal(e, body, headers, status, request);
logGenericException(e);
return responseEntity;
}