Один валидатор правильно перенаправляет, а другой вообще не перенаправляет? - PullRequest
0 голосов
/ 25 апреля 2019

У меня есть два валидатора, зарегистрированных в моем контроллере.Проблема в том, что InvoiceFormValidator работает отлично, возвращает ошибки, когда они есть, и перенаправляет на нужную страницу с заполненной формой данных.

Вторая не перенаправляет вообще, она просто перенаправляет меня намоя страница с сообщением об ошибке:

Дата Чт 25 апреля 15:22:57 CEST 2019 Путь / подрядчик / обновление / 5cc193e581c7dc75cfb7bcff Ошибка Состояние плохого запроса 400 Ошибка проверки сообщения для объекта = 'подрядчик'.Количество ошибок: 1

Теперь код: (я представляю только важную часть кода)

@Autowired private InvoiceFormValidator invoiceFormValidator;
@Autowired private PersonFormValidator personFormValidator;

@InitBinder({"invoicedata"})
protected void initPersonFormBinder(WebDataBinder binder) {
    binder.addValidators(invoiceFormValidator);
}

@InitBinder({"contractor"})
protected void initContractorFormBinder(WebDataBinder binder) {
    binder.addValidators(personFormValidator);
}

Вот как это выглядит на стороне контроллера (дляinitPersonFormBinder:)

@RequestMapping(value = "/addinvoice", method = RequestMethod.POST, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public String addInvoice(@CurrentUser Contractor contractor, @ModelAttribute("invoicedata") @Validated InvoiceData invoicedata, BindingResult result, Model model, RedirectAttributes attr) {
        if (result.hasErrors()) {
            return "add";
        } else {

И для initContractorFormBinder:

@RequestMapping(value = "/contractor/update/{id}", method = RequestMethod.POST, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String updateContractor(@PathVariable("id") String id, @ModelAttribute("contractor") @Validated Contractor contractor, Model model, BindingResult result, RedirectAttributes attr)  {
if (result.hasErrors()) {
    logger.error("BINDING RESULT ERROR");
    return "index";
} else {

Проблема в том, что код никогда не входит в этот метод, НИКОГДА не достигает оператора if.

Теперь сторона кода InvoiceFormValidator:

@Component
public class InvoiceFormValidator implements Validator {

    Logger logger = LoggerFactory.getLogger(InvoiceFormValidator.class);

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

    @Override
    public void validate(Object target, Errors errors) {
        ValidationUtils.rejectIfEmpty(errors, "receptionDate", "empty");
        ValidationUtils.rejectIfEmpty(errors, "orderDate", "empty");
        ValidationUtils.rejectIfEmpty(errors, "invoiceIssueDate", "empty");
        ValidationUtils.rejectIfEmpty(errors, "contractDate", "empty");
        ValidationUtils.rejectIfEmpty(errors, "invoiceNumber", "empty");
    }
}

И в то же время PersonFormValidator выглядит так:

@Component
public class PersonFormValidator implements Validator {

    Logger logger = LoggerFactory.getLogger(com.look4app.generator.component.impl.PersonFormValidator.class);

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

    @Override
    public void validate(Object target, Errors errors) {
        Contractor contractor = (Contractor) target;
        if (contractor.getContractorData().getNip() == null || contractor.getContractorData().getNip().equals("")) {
            errors.rejectValue("contractorData.nip", "empty");
        }
        logger.error("CONTRACTOR VALIDATION ERROR");
    }
}

И небольшая часть шаблона Thymeleaf здесь,для части, которая не работает:

<form action="#" th:action="@{/contractor/update/{id}(id=${contractor.id})}" th:object="${contractor}" method="post">
            <ul class="form-style-1">
                <li>
                    <label>NIP<span class="required">*</span></label>
                    <input type="text" th:field="*{contractorData.nip}" id="nip" th:value="${contractor.contractorData?.nip}" >
                    <span class="error" th:if="${#fields.hasErrors('contractorData.nip')}" th:errors="*{contractorData.nip}">Generic error</span>
                </li>
            <li>
                <input type="submit" value="Zapisz dane firmy" />
            </li>

Тот же HTML для проверки работоспособности немного отличается, но не так сильно:

<form action="#" th:action="@{addinvoice}" th:object="${invoicedata}" method="post">
            <ul class="form-style-1">

                <li>
                    <label>Komentarz</label>
                    <input type="text" th:field="*{contractorComment}" id="contractorComment">
                </li>
                <li>
                    <input type="submit" value="Zapisz protokół" />
                </li>

Что не так с этим перенаправлением?

1 Ответ

1 голос
/ 25 апреля 2019

Обратите внимание на небольшую разницу в порядке параметров метода:

public String addInvoice      (... @ModelAttribute("invoicedata") @Validated InvoiceData invoicedata, BindingResult result, Model model, ...) {
public String updateContractor(... @ModelAttribute("contractor")  @Validated Contractor contractor, Model model, BindingResult result, ...)  {

Параметр BindingResult должен идти сразу после параметра с @Validated. Если вы измените подпись вашего метода на:

public String updateContractor(@PathVariable("id") String id, @ModelAttribute("contractor") @Validated Contractor contractor, BindingResult result, Model model, RedirectAttributes attr)  {

Вы должны иметь доступ к вашему методу. Если параметр BindingResult присутствует непосредственно после @ModelAttribute, Spring помещает результат проверки в BindingResult и вызывает метод, где вы можете обработать BindingResult вручную. В противном случае Spring обрабатывает проверку и пропускает метод.

...