一个验证器正确重定向,另一个验证器根本没有重定向? [英] One validator redirecting correctly, another one not redirecting at all?
问题描述
我在我的控制器中注册了两个验证器.问题是 - InvoiceFormValidator 工作完美,在有错误时返回错误,并重定向到所需页面,并用数据填写表单.
I have two Validators registered in my Controller. The problem is - InvoiceFormValidator works perfectly, returns errors when there are any, and redirects to desired page, with the form filled out with data.
第二个根本没有重定向,它只是将我重定向到我的错误页面,显示给我:
The second one is not redirecting at all, it is just redirecting me to my error page, showing me:
日期 4 月 25 日星期四 15:22:57 CEST 2019 路径/contractor/update/5cc193e581c7dc75cfb7bcff 错误错误请求状态400 object='contractor' 消息验证失败.错误计数:1
Date Thu Apr 25 15:22:57 CEST 2019 Path /contractor/update/5cc193e581c7dc75cfb7bcff Error Bad Request Status 400 Message Validation failed for object='contractor'. Error count: 1
现在代码:(我只展示代码的重要部分)
Now the code: (I'm presenting just the important part of the code)
@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
:)
This is how it looks on the controller side (for 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
语句.
The problem here is that the code never enters this method, NEVER reaches the if
statement.
现在是 InvoiceFormValidator 的代码端:
Now the code side of 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 看起来像这样:
And the same time, PersonFormValidator looks like this:
@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 模板,用于不工作的部分:
And a small part of the Thymeleaf template here, for the part which is not working:
<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>
WORKING 验证的相同 HTML 略有不同,但差别不大:
Same HTML for the WORKING validation is a bit different, but not that much:
<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>
这种重定向有什么问题?
What is wrong with this redirecting?
推荐答案
注意方法参数顺序的细微差别:
Notice the subtle difference in the order of the method parameters:
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
的参数之后.如果您将方法签名更改为:
The BindingResult
parameter should come right after the parameter with the @Validated
. If you change your method signature to:
public String updateContractor(@PathVariable("id") String id, @ModelAttribute("contractor") @Validated Contractor contractor, BindingResult result, Model model, RedirectAttributes attr) {
您应该能够访问您的方法.如果 BindingResult
参数直接出现在 @ModelAttribute
之后,Spring 会将验证结果放入 BindingResult
并调用方法,您可以在其中手动处理 BindingResult
.否则,Spring 会处理验证并跳过该方法.
You should be able to access your method. If a BindingResult
parameter is present directly after the @ModelAttribute
, Spring puts the validation result in the BindingResult
and calls the method, where you can process the BindingResult
manually. Otherwise, Spring handles the validation and skips the method.
这篇关于一个验证器正确重定向,另一个验证器根本没有重定向?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!