【发布时间】:2022-01-01 06:04:58
【问题描述】:
我正在尝试使用自定义验证器验证枚举,在我的自定义验证器中,当枚举值中不存在参数时,我尝试返回自定义消息。
下面是我的枚举
public enum Type {
MISSING_SITE,
INACTIVE_SITE;
}
下面我的PostMapping 方法
@PostMapping(value = "/line-kpi", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Find Kpis by one or more customer property")
public ResponseEntity<List<KpiDTO>> findKPILineByCustomer(@RequestBody @ValidCustomerParameter CustomerParameter customerParameter, @RequestParam @ValidExtractionDate String extractionDate) {
var linesKpi = Optional.ofNullable(
kpiService.findKPILineByCustomer(
Optional.ofNullable(customerParameter.getEntityPerimeter()).orElse(List.of()),
Optional.ofNullable(customerParameter.getName()).orElse(List.of()),
Optional.ofNullable(customerParameter.getIc01()).orElse(List.of()),
Optional.ofNullable(customerParameter.getSiren()).orElse(List.of()),
Optional.ofNullable(customerParameter.getEnterpriseId()).orElse(List.of()),
LocalDate.parse(extractionDate)
)
);
return linesKpi.map(ResponseEntity::ok).orElseThrow(() -> new ResourceNotFoundException(KPIS));
}
我无法在方法本身中将枚举类型切换为字符串,因为我使用的是 swagger,它显示了一个不错的枚举选择列表。
不幸的是,当我尝试为 Type 提供不同的值时,它返回一个错误的请求,并且我的验证器没有被触发。
所以我试图序列化我的枚举以在它到达控制器时被解释为字符串,为此我需要使用杰克逊,我试图寻找一个解决方案,但我找不到一个好的解决方案我的情况。
下面是我的验证器
public class ReportTypeValidator implements ConstraintValidator<ValidReportType, Type> {
private String globalMessage;
@Override
public void initialize(ValidReportType constraintAnnotation) {
ConstraintValidator.super.initialize(constraintAnnotation);
globalMessage = constraintAnnotation.message();
}
@Override
public boolean isValid(Type type, ConstraintValidatorContext constraintValidatorContext) {
if (Arrays.stream(Type.values()).filter(type1 -> type1.equals(type)).toList().isEmpty()) {
constraintValidatorContext
.buildConstraintViolationWithTemplate(globalMessage + ", report type does not exist")
.addConstraintViolation();
return false;
}
return true;
}
}
@Constraint(validatedBy = ReportTypeValidator.class)
@Target( { ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Valid
public @interface ValidReportType {
String message() default "Invalid value for report type";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
谁能告诉我如何将我的枚举转换为字符串,以便我的验证器可以处理它?
【问题讨论】:
-
我想我没有完全理解问题的复杂性,但你“只是想要”(类似):
globalMessage + ": " + type.name() +", report type does not exist"?? -
..但我怀疑,这段代码是否会执行......(如果你/某人发送
Type.UNDEFINED??)? -
对于this,有更好的解决方案:Interpolating constraint error messages(您可以使用占位符等等...)
-
问题不在于枚举值,而是关于参数的弹簧默认处理,因为他在调用验证器之前检查枚举的值,并且由于我有一个 emum 参数,他检查参数的值是否为这种类型的有效枚举,如果不是,他会返回错误的请求。我不希望他对枚举进行默认处理,我希望他直接调用验证器
标签: java spring-boot validation enums jackson