java - 一个 validator 正确重定向,另一个 validator 根本不重定向?

标签 java spring spring-boot validation thymeleaf

我在 Controller 中注册了两个 validator 。问题是 - InvoiceFormValidator 工作正常,出现错误时返回错误,并重定向到所需页面,并在表单中填写数据。

第二个根本没有重定向,它只是将我重定向到错误页面,向我显示:

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

现在是代码:(我只展示代码的重要部分)

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

这就是它在 Controller 端的样子(对于 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>

用于 WORKING 验证的相同 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>

此重定向有什么问题?

最佳答案

请注意方法参数顺序的细微差别:

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 会处理验证并跳过该方法。

关于java - 一个 validator 正确重定向,另一个 validator 根本不重定向?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55850511/

相关文章:

java - Gradle 未将 WebJar 内容放入我的 Jar 文件中的正确位置

java - Spring集成DSL : PublishSubscribeChannel order

java - 单例在 Spring 最新版本中不起作用

java - Spring Security MultiHttpSecurity Configuration 以便我可以执行两种类型的身份验证。 JWT token 和 session Cookie

hibernate - 加速 LocalSessionFactoryBean dropDatabaseSchema、createDatabaseSchema

javascript - SpringBoot Angular 应用程序不提供所有 js 文件

java - MustUnderstand 属性不只是设置为 false。

java - 异步关闭套接字 channel

java - java中有没有一种方法可以唯一标识对象

java - org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker 循环引用 Spring Boot 2.1.3