问题描述
这篇文章之后:http://dolszewski.com/spring/how-to-bind-requestparam-to-object/
我创建了以下控制器:
@GetMapping("/highlights")
public ResponseEntity<List<Highlight>> getHighlights(
HighlightFilterCriteria highlightFilterCriteria
) {
//...
HighlightFilterCriteria POJO具有以下形状:
public class HighlightFilterCriteria {
private LocalDateTime updatedDate;
private UUID userId;
public LocalDateTime getUpdatedDate() {
return updatedDate;
}
public void setUpdatedDate(String updatedDate) {
DateTimeFormatter dateTimeFormat = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
try {
this.updatedDate = LocalDateTime.parse(updatedDate,dateTimeFormat);
} catch (DateTimeParseException exc) {
throw new InvalidInputException("udpatedDate","should be ISO date");
}
}
public UUID getUserId() {
return userId;
}
public void setUserId(String userId) {
try {
this.userId = UUID.fromString(userId);
} catch (IllegalArgumentException exc) {
throw new InvalidInputException("userId","should be UUID");
}
}
}
这是我创建的InvalidInputException
自定义异常的实现:
package com.hmhco.rcehighlightspoc.exceptionsHandling;
public class InvalidInputException extends RuntimeException {
private String paramName;
private String message;
public InvalidInputException(String paramName,String message) {
super("\"" + paramName + "\" provided is invalid. It should be " + message);
this.paramName = paramName;
this.message = message;
}
}
然后这是ControllerAdvice实现,其中包含InvalidInputException
的异常处理程序和泛型捕获所有Exception
处理程序:
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = InvalidInputException.class)
public ResponseEntity<Object> handleInvalidInputException(InvalidInputException ex) {
log.info("Handled: Invalid input",ex);
return buildresponseEntity(new ApiErrorResponse(
HttpStatus.BAD_REQUEST,"Incorrect input",ex
));
}
@ExceptionHandler(value = Exception.class)
public ResponseEntity<Object> handleException(Exception ex) {
log.error("Handled: Catch all exception","Catch all exception handler",ex
));
}
private ResponseEntity<Object> buildresponseEntity(ApiErrorResponse errorResponse) {
return new ResponseEntity<>(errorResponse,errorResponse.getStatus());
}
当我发送带有格式不正确的userId查询参数(不正确的UUID)http://localhost:8080/v1/highlights?updatedDate=2020-05-18T08:58:33.876Z&userId=badUUID
的请求时,HighlightFilterCriteria
中的try / catch捕获InvalidInputException
并将其作为我的自定义{{1} },但不幸的是,由于某些原因,ControllerAdvice的InvalidInputException
的{{1}}处理程序无法捕获它。
它被handleInvalidInputException
处理程序捕获,我可以在日志中看到它:
InvalidInputException
我希望由于控制器使用此POJO来解析请求参数,因此可以捕获自定义异常。
如果要测试,我可以通过以下方式直接从控制器中抛出自定义@ExceptionHandler(value = Exception.class)
:
ERROR com.hmhco.rcehighlightspoc.exceptionsHandling.GlobalExceptionHandler.handleException - Handled: Catch all exception
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'highlightFilterCriteria' on field 'userId': rejected value [abcacf9b-926a-49c4-b980]; codes [methodInvocation.highlightFilterCriteria.userId,methodInvocation.userId,methodInvocation.java.util.UUID,methodInvocation]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [highlightFilterCriteria.userId,userId]; arguments []; default message [userId]]; default message [Property 'userId' threw exception; nested exception is com.hmhco.rcehighlightspoc.exceptionsHandling.InvalidInputException: "userId" provided is invalid. It should be should be UUID]
at org.springframework.web.method.annotation.modelattributeMethodProcessor.resolveArgument(modelattributeMethodProcessor.java:164)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
...
然后我可以看到InvalidInputException
处理程序按预期捕获了它。
@GetMapping("/highlights")
public ResponseEntity<List<Highlight>> getHighlights(
@Valid HighlightFilterCriteria highlightFilterCriteria
) {
if (true) throw new InvalidInputException("userId","should be UUID");
...
}
主要问题是为什么InvalidInputException
的{{1}}异常处理程序未捕获INFO com.hmhco.rcehighlightspoc.exceptionsHandling.GlobalExceptionHandler.handleInvalidInputException - Handled: Invalid input
com.hmhco.rcehighlightspoc.exceptionsHandling.InvalidInputException: "userId" provided is invalid. It should be should be UUID
at com.hmhco.rcehighlightspoc.controller.HighlightController.getHighlights(HighlightController.java:63)
,而InvalidInputException
异常处理程序却捕获了它?
或者也许我正试图以一种不正确的方式在POJO中进行验证,如果是这样,那么当控制器方法获得POJO时,处理诸如ISO格式的UUID和Date之类的复杂类型的解析错误的正确方法是什么?作为论点?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)