错误详情

该页面工作正常,但是当我在两个输入startStatusDateendStatusDate中输入了不正确的时间段时。验证检查类DriverHistoryValidator中的错误时发生错误。

我在调试器中看到分配后生成的异常

errors.rejectValue("startStatusDate",
"co.driverHistoryStatusPeriod.notpermitted")


方法中

validate(Object o, Errors errors)


请看下面

我究竟做错了什么?

2018-05-03 11:03:54.364 ERROR 6234 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.beans.NotReadablePropertyException: Invalid property 'startStatusDate' of bean class [kg.nurtelecom.dictionaries.entity.carordering.Driver]: Bean property 'startStatusDate' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?] with root cause

org.springframework.beans.NotReadablePropertyException: Invalid property 'startStatusDate' of bean class [kg.nurtelecom.dictionaries.entity.carordering.Driver]: Bean property 'startStatusDate' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?


前端

在Thymeleaf中实现的前端:

<form id="statusSheduleForm" class="form-horizontal" th:action="@{/driver/saveStatusSchedule}"
                  th:method="POST"
                  th:object="${driverHistory}">
                <div class="form-group col-md-7">
                    <div class="input-group date">
                        <label class="validation-message" for="statusdatetimepicker1"
                               th:if="${#fields.hasErrors('startStatusDate')}"
                               th:errors="*{startStatusDate}"></label>
                        <input type="text" placeholder="Время начала" th:field="*{startStatusDate}"
                               id="statusdatetimepicker1"/>
                        <input type="text" placeholder="Время окончания" th:field="*{endStatusDate}"
                               id="statusdatetimepicker2"/>
                        <select id="status-select" required="required" th:field="*{driverStatus}">
                            <option th:each="item:${statuses}"
                                    th:value="${item.id}"
                                    th:text="${item.name}"></option>
                        </select>
                    </div>
                </div>

                <div class="form-group">
                    <button type="submit" class="btn btn-primary">Сохранить</button>
                    <a th:href="@{/driver/index}" class="btn btn-default">Закрыть</a>
                </div>

            </form>


后端:

控制者

@RequestMapping(value = "/saveStatusSchedule", method = RequestMethod.POST)
    public ModelAndView saveStatusSchedule(@ModelAttribute DriverHistory driverHistory, Driver driver,
                                           BindingResult bindingResult) {
        ModelAndView modelAndView = getModelsViews();
        Driver sessionDriver = (Driver) modelAndView.getModel().get("driver");
        if (sessionDriver != null) {
            sessionDriver.setMenu1Act();
            driverHistory.setDriver(sessionDriver);
            driverHistoryValidator.validate(driverHistory, bindingResult);
            if (bindingResult.hasErrors()) {
                return getModelsViews();
            }
            if (driverHistory.getDriverShift() != null) {
                sessionDriver.setMenu2Act();
            }
            driverHistory.setDriver(sessionDriver);
            driverHistoryService.save(driverHistory);
            return getModelsViews();
        } else {
            driver.setMenu0Act();
            modelAndView.addObject("failMessage", "Водитель не создан");
            modelAndView.addObject("driver", driver);
            return modelAndView;
        }
    }


验证器:

@Component
public class DriverHistoryValidator implements Validator {

    @Autowired
    DriverHistoryService driverHistoryService;

    @Override
    public boolean supports(Class<?> aClass) {
        return DriverHistory.class.equals(aClass);
    }

    @Override
    public void validate(Object o, Errors errors) {
        DriverHistory driverHistory = (DriverHistory) o;
        if (driverHistoryService.isExistDriverStatusInPeriodOf(driverHistory)) {
            errors.rejectValue("startStatusDate", "co.driverHistoryStatusPeriod.notpermitted");
        }
    }
}


实体:

@Entity
@Table(name = "CO_DRIVER_HISTORY")
public class DriverHistory extends BaseEntity {

    @DateTimeFormat(pattern = "dd.MM.yyyy HH:mm")
    @Column(name = "startStatusDate")
    private Date startStatusDate;

    @DateTimeFormat(pattern = "dd.MM.yyyy HH:mm")
    @Column(name = "endStatusDate")
    private Date endStatusDate;

    @DateTimeFormat(pattern = "dd.MM.yyyy HH:mm")
    @Column(name = "startShiftDate")
    private Date startShiftDate;

    @DateTimeFormat(pattern = "dd.MM.yyyy HH:mm")
    @Column(name = "endShiftDate")
    private Date endShiftDate;

    @ManyToOne
    @JoinColumn(name = "DriverId")
    private Driver driver;

    @ManyToOne
    @JoinColumn(name = "DriverStatusId")
    private DriverStatus driverStatus;

    @ManyToOne
    @JoinColumn(name = "DriverShiftId")
    private DriverShift driverShift;

    public DriverHistory() {
    }

    public Date getStartStatusDate() {
        return startStatusDate;
    }

    public void setStartStatusDate(Date startStatusDate) {
        this.startStatusDate = startStatusDate;
    }

    public Date getEndStatusDate() {
        return endStatusDate;
    }

    public void setEndStatusDate(Date endStatusDate) {
        this.endStatusDate = endStatusDate;
    }

    public Date getStartShiftDate() {
        return startShiftDate;
    }

    public void setStartShiftDate(Date startShiftDate) {
        this.startShiftDate = startShiftDate;
    }

    public Date getEndShiftDate() {
        return endShiftDate;
    }

    public void setEndShiftDate(Date endShiftDate) {
        this.endShiftDate = endShiftDate;
    }

    public Driver getDriver() {
        return driver;
    }

    public void setDriver(Driver driver) {
        this.driver = driver;
    }

    public DriverStatus getDriverStatus() {
        return driverStatus;
    }

    public void setDriverStatus(DriverStatus driverStatus) {
        this.driverStatus = driverStatus;
    }

    public DriverShift getDriverShift() {
        return driverShift;
    }

    public void setDriverShift(DriverShift driverShift) {
        this.driverShift = driverShift;
    }

}

最佳答案

我已经找出问题的根本原因。让我回答自问的问题。

在我的情况下,类[kg.nurtelecom.dictionaries.entity.carordering.Driver]中实际上不存在自属性“ startStatusDate”以来生成的org.springframework.beans.NotReadablePropertyException。让我解释一下为什么会发生。重点是以下提到的控制器方法的参数顺序不正确。

@RequestMapping(value = "/saveStatusSchedule", method = RequestMethod.POST)
    public ModelAndView saveStatusSchedule(@ModelAttribute
                                                   DriverHistory driverHistory,
                                                   Driver driver,
                                                   BindingResult bindingResult)


在参数中声明的BindingResult对象获取先前声明的参数作为目标对象。 See debug in screen shot。在我的验证器类DriverHistoryValidator中,将错误值设置为不是目标对象的类的字段。在我简单地更改上述方法中的参数顺序之后,该问题已解决:

@RequestMapping(value = "/saveStatusSchedule", method = RequestMethod.POST)
public ModelAndView saveStatusSchedule(DriverHistory driverHistory,
                                       BindingResult bindingResult,
                                       Driver driver)


对参数重新排序后,将获得类DriverHistory作为BindinResult对象中的目标对象,并且验证可以正常进行。

08-18 19:17