使用 BeanUtils.getProperty() 时发生未知 属性 错误
Unknown property error while using BeanUtils.getProperty()
这是我的 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;
}
我添加了一个@DateRange
注解,声明如下。
@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();
}
}
验证器class是
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;
}
}
验证器检查开始日期是否早于结束日期。
在这样做时,BeanUtils.getProperty()
将 java.lang.NoSuchMethodException
与 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)
但是 startDate
在 MyClass
中。变量是 public 并命名为驼峰式。为什么会出现问题?任何的想法?
我找到了解决方案。我只需要写下 MyClass
的 getter。似乎找不到该属性,因为没有 getter 函数。
所以最后的 MyClass
看起来像。
@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;
}
}
这是我的 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;
}
我添加了一个@DateRange
注解,声明如下。
@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();
}
}
验证器class是
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;
}
}
验证器检查开始日期是否早于结束日期。
在这样做时,BeanUtils.getProperty()
将 java.lang.NoSuchMethodException
与 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)
但是 startDate
在 MyClass
中。变量是 public 并命名为驼峰式。为什么会出现问题?任何的想法?
我找到了解决方案。我只需要写下 MyClass
的 getter。似乎找不到该属性,因为没有 getter 函数。
所以最后的 MyClass
看起来像。
@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;
}
}