Почему мой пользовательский Validator для внутреннего объекта не используется для проверки? - PullRequest
0 голосов
/ 25 апреля 2019

У меня есть собственный валидатор, который выглядит следующим образом:

@Component
public class PersonFormValidator implements Validator {

    Logger logger = LoggerFactory.getLogger(com.myapp.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(errors.toString());
    }
}

На стороне шаблона 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>

Мой контроллер выглядит так:

@RequestMapping(value = "/contractor/update/{id}", method = RequestMethod.POST, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String updateContractor(@PathVariable("id") String id, @Validated @ModelAttribute("contractor") Contractor contractor, Model model, BindingResult result) {
if (result.hasErrors()) {
    logger.error("BINDING RESULT ERROR");
    return "index";
} else {
    Contractor contractorPO = contractorRepository.findById(id).get();
    ContractorData contractorData = 
    //not important code here
    contractorPO.setContractorData(contractorData);
    contractorRepository.save(contractorPO);
    model.addAttribute("contractor", contractorPO);
    return "index";
}

И, конечно, я зарегистрировал валидатор:

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

Когда я запускаю приложение и захожу по адресу приложения, я получаю ошибку, подобную этой:

Неверная цель для Валидатора [Com.myapp.generator.component.impl.InvoiceFormValidator@e52be6c]: Подрядчик (id = 5cc193e581c7dc75cfb7bcff, email=some@mail.com, contractorData = ContractorData (firstName = имя, фамилия = фамилия, businessName = Apple, businessLocation = Варшава, nip =, regon = adgadgdagdag), счета-фактуры = [])

У меня ничего не работает, я борюсь с этой проблемой со вчерашнего дня ...

Что я могу изменить в своем коде, чтобы проверка работала?

1 Ответ

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

Я предполагаю, что оба валидатора применяются к обеим формам:

  • Для invoiceData;применить invoiceFormValidator И personFormValidator
  • Для подрядчика;применить invoiceFormValidator AND personFormValidator

Что если бы вы связали валидаторы двумя отдельными методами?

@InitBinder("invoicedata")
protected void invoiceDataBinder(WebDataBinder binder) {
    binder.setValidator(invoiceFormValidator);
}

@InitBinder("contractor")
protected void contractorDataBinder(WebDataBinder binder) {
    binder.setValidator(personFormValidator);
}
...