java - 使用 BeanUtils.getProperty() 时出现未知属性错误

标签 java reflection spring-boot apache-commons-beanutils

这是我的类(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();
    }
}

validator 类是

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;
    }
}

validator 检查开始日期是否早于结束日期。

执行此操作时,BeanUtils.getProperty() 抛出 java.lang.NoSuchMethodException 以及未知属性“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 的 setter/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;
    }
}

关于java - 使用 BeanUtils.getProperty() 时出现未知属性错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41820182/

相关文章:

java - eclipse JDT AST : How to write generated AST to java file?

java - 使用 ViewPager2 折叠工具栏会出现滚动问题

java - 使用反射更改 boolean 字符串值不起作用

java - 决定在执行时实例化哪个子类

spring - 为 Spring-boot 应用程序捕获应用程序停止事件

java - 在外部文件夹 war 文件命令中运行类路径 Spring java

java - Android 相当于 iOS 的 beginIgnoringInteractionEvents

java - 无法使用 fetch-profile 或 hibernate.initialize() 覆盖 Hibernate 延迟获取

go - 递归扩展包含指针的结构定义

spring-boot - 如何防止访问已安装的 secret 文件?