Reputation: 24211
Here's my class.
@DateRange.List({
@DateRange(start = "startDate", end = "endDate", message = "Start date should be earlier than end date.")
})
public class MyClass {
@NotNull
@Pattern(regexp = DateConstants.DATE_FORMAT_REGEX, message = "Invalid date format.")
public String startDate;
@NotNull
@Pattern(regexp = DateConstants.DATE_FORMAT_REGEX, message = "Invalid date format.")
public String endDate;
}
I've added a @DateRange
annotation, which is declared as follows.
@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = DateRangeValidator.class)
@Documented
public @interface DateRange {
String message() default "{constraints.daterange}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String start();
String end();
@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Documented
@interface List {
DateRange[] value();
}
}
And the validator class is
public class DateRangeValidator implements ConstraintValidator<DateRange, Object> {
private String startDateFieldName;
private String endDateFieldName;
@Override
public void initialize(final DateRange constraintAnnotation) {
startDateFieldName = constraintAnnotation.start();
endDateFieldName = constraintAnnotation.end();
}
@Override
public boolean isValid(final Object value, final ConstraintValidatorContext context) {
final String startDate = (String) BeanUtils.getProperty(value, startDateFieldName);
final String endDate = (String) BeanUtils.getProperty(value, endDateFieldName);
return isValidDateRange(startDate, endDate);
}
private boolean isValidDateRange(String start, String end) {
DateFormat dateFormat = new SimpleDateFormat(DateConstants.DATE_FORMAT);
try {
Date startDate = dateFormat.parse(start);
Date endDate = dateFormat.parse(end);
if (startDate.before(endDate)) return true;
} catch (ParseException e) {}
return false;
}
}
The validator checks if the start date is before the end date.
While doing so, the BeanUtils.getProperty()
is throwing java.lang.NoSuchMethodException
along with Unknown property 'startDate'
.
java.lang.NoSuchMethodException: Unknown property 'startDate' on class 'class mypackage.domain.rest.MyClass'
at org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(PropertyUtilsBean.java:1322)
at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:770)
at org.apache.commons.beanutils.BeanUtilsBean.getNestedProperty(BeanUtilsBean.java:715)
at org.apache.commons.beanutils.BeanUtilsBean.getProperty(BeanUtilsBean.java:741)
at org.apache.commons.beanutils.BeanUtils.getProperty(BeanUtils.java:382)
at bd.com.ipay.offer.validation.imp.DateRangeValidator.isValid(DateRangeValidator.java:36)
at org.hibernate.validator.engine.ConstraintTree.validateSingleConstraint(ConstraintTree.java:278)
at org.hibernate.validator.engine.ConstraintTree.validateConstraints(ConstraintTree.java:153)
at org.hibernate.validator.engine.ConstraintTree.validateConstraints(ConstraintTree.java:117)
at org.hibernate.validator.metadata.MetaConstraint.validateConstraint(MetaConstraint.java:84)
at org.hibernate.validator.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:452)
at org.hibernate.validator.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:397)
at org.hibernate.validator.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:361)
at org.hibernate.validator.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:313)
at org.hibernate.validator.engine.ValidatorImpl.validate(ValidatorImpl.java:139)
at org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.java:108)
at org.springframework.validation.DataBinder.validate(DataBinder.java:866)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.validateIfApplicable(AbstractMessageConverterMethodArgumentResolver.java:268)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:130)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:99)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
But the startDate
is there in MyClass
. The variable is public and named camel case. Why the problem is occurring? Any idea?
Upvotes: 0
Views: 4058
Reputation: 24211
I found the solution. I just had to write the getters of my MyClass
. Seems like the attribute was not found because there was not getter function.
So the final MyClass
looks like.
@DateRange.List({
@DateRange(start = "startDate", end = "endDate", message = "Start date should be earlier than end date.")
})
public class MyClass {
@NotNull
@Pattern(regexp = DateConstants.DATE_FORMAT_REGEX, message = "Invalid date format.")
public String startDate;
@NotNull
@Pattern(regexp = DateConstants.DATE_FORMAT_REGEX, message = "Invalid date format.")
public String endDate;
public String getStartDate() {
return startDate;
}
public String getEndDate() {
return endDate;
}
}
Upvotes: 2