【发布时间】:2021-06-02 07:38:20
【问题描述】:
我有自定义 ConstraintValidator 来检查 @RequestParam 的有效值。 我也有一些带有 @NotNull 注释的属性的休眠实体。
默认行为是将 ConstraintViolationException 转换为 HttpStatus=500。 这是从休眠状态引发的错误(即持久实体等)所需要的。 但我想为 @RestController 提出的 ConstraintViolations 提出 HttpStatus=400。
@ExceptionHandler 有效,但它无法区分从休眠和弹簧层引发的违规行为。我猜这两个层都使用了休眠验证器依赖,但我们应该能够区分它们。
@ExceptionHandler(ConstraintViolationException.class)
protected ResponseEntity<Object> handleConstraintViolationException(ConstraintViolationException ex, WebRequest request) {
return getObjectResponseEntity(ex, request, HttpStatus.BAD_REQUEST);
}
我想知道是否还有其他方法可以实现这一点。我试过@InitBinder 验证器,但它似乎不适用于@RequestParam。
你有什么想法吗?谢谢。
对此的一种解决方案是列出给定异常中的所有违规行为,并检查根 bean 的名称是否类似于 *Controller,但这不是很干净的解决方案,并且以这种方式将开发人员绑定到命名控制器。
@ExceptionHandler(ConstraintViolationException.class)
protected ResponseEntity<Object> handleConstraintViolationException(ConstraintViolationException ex, WebRequest request) {
// TODO ugly
boolean isFromController = ex.getConstraintViolations().stream()
.map(cv -> cv.getRootBeanClass().getSimpleName())
.anyMatch(cv -> cv.contains("Controller"));
return getObjectResponseEntity(ex, request, isFromController ? HttpStatus.BAD_REQUEST : HttpStatus.INTERNAL_SERVER_ERROR);
}
带有@SupportedFileTypes 自定义验证器的控制器看起来像这样,它根据内部枚举检查字符串值。
@GetMapping(value = "/{requirementId}/export-cisel", produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
public CisRadDto exportRequirementNumbers(
@PathVariable UUID requirementId,
@SupportedFileTypes @RequestParam(value = "formatSouboru", required = false) String fileFormat
) {
return pozadavekFacade.exportRequirementNumbers(requirementId, fileFormat != null ? fileFormat : "default");
}
pozadavekFacade 只保存创建的具有以下检查的实体:
@NotBlank
@Column(length = 10, nullable = false)
private String idUzivatele;
【问题讨论】:
-
中间有层吗?还是您的控制器直接从用户输入构建实体?也许您可以在问题中添加更多代码 sn-p
-
其实是的。层数很少 - 使用服务的外观类。我现在要用一些代码 sn-ps 来编辑问题。
标签: java spring validation