使用Java Hibernate验证列表项的子集,获取完整的属性路径
我正在使用javax和hibernate创建我的第一个springbootweb应用程序,以验证从JSP表单输入的数据。我有一个预订模型,其中包括一系列行程模型:使用Java Hibernate验证列表项的子集,获取完整的属性路径,java,spring-boot,hibernate-validator,Java,Spring Boot,Hibernate Validator,我正在使用javax和hibernate创建我的第一个springbootweb应用程序,以验证从JSP表单输入的数据。我有一个预订模型,其中包括一系列行程模型: @ValidBooking(groups = {BookingI.class}) public class Booking { @Min(value = 1, groups = {BookingI.class, Default.class}) private int totalJourneys; @Valid pri
@ValidBooking(groups = {BookingI.class})
public class Booking {
@Min(value = 1, groups = {BookingI.class, Default.class})
private int totalJourneys;
@Valid
private List<Journey> journeys;
// relevant getters and setters
上面的代码适用于我的测试,但是当使用jsp表单呈现时,spring数据绑定失败,因为违规约束的属性路径返回为“locations[0]”,而不是预期的“booking.journies[0].locations[0]”
是否有人对如何返回完整的属性路径有任何建议,或者提供更好的解决方案
提前谢谢
Java 8、javax验证api 2.0.1、hibernate validator 6.0.7
首先,有几点意见:
- 在验证器中构建
不是一个好主意。这是一个非常沉重的对象,每次验证它时都需要构建验证器工厂
bean的元数据,速度会很慢旅程
- 要构建约束,您需要构建精确的路径,即使用
,inContainer()
。。。不能简单地将atIndex()
传递给属性toString()
- 创建一个
,该程序实现JourneyDefaultGroupSequenceProvider
,当它是要验证的对象时返回有效组,当不想验证旅程时,返回未在任何约束中使用的某个随机组<代码>列表感谢@GuillaumeSmet的回复和建议,我正在实施GroupSequenceProvider。我唯一的问题是,我是否可以访问旅程GroupSequenceProvider中的父对象信息(在本例中为Booking),以便识别旅程对象的索引位置是否小于Booking.totalJourneys值?您只有一个实例,其中有DefaultGroupSequenceProvider
。因此,不幸的是,您需要一个指向对象中父对象的链接。我创建了一个更明显的东西。将在其中添加有关索引的案例,但我不确定找到解决方案是否容易。@GroupSequenceProvider
@ValidJourney public class Journey { @Valid private List<Location> locations; private List<String> dates; private List<String> times; // relevant getters and setters
public class ValidBookingValidator implements ConstraintValidator<ValidBooking, Booking> { @Override public boolean isValid(Booking booking, ConstraintValidatorContext constraintValidatorContext) { ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); int totalJourneys = booking.getTotalJourneys(); int validJourneys = 0; for (int journeyIdx = 0; journeyIdx < totalJourneys; journeyIdx++) { Set<ConstraintViolation<Journey>> journeyConstraintViolations = validator.validate(booking.getJourneys().get(journeyIdx)); if (journeyConstraintViolations.isEmpty()) { validJourneys++; } else { for (ConstraintViolation<Journey> violation : journeyConstraintViolations) { constraintValidatorContext.buildConstraintViolationWithTemplate(violation.getMessage()) .addPropertyNode(violation.getPropertyPath().toString()) .addConstraintViolation(); } } } return totalJourneys == validJourneys; } }
@GroupSequenceProvider(JourneyDefaultGroupSequenceProvider.class) public class Journey { // ... }