Spring4 MVC 表单验证 result.hasErrors() 始终为 false

Spring4 MVC form validation result.hasErrors() is always false

我正在使用 validation-api-1.1.0.Final.jar 来验证 Spring 4 MVC 中的表单输入。但我被困在这里,result.hasErrors() 似乎总是错误的(这意味着 @Valid 不能正常工作)。我遵循了本指南Validating Form Input,但该指南使用 Spring Boot.我使用 Tomcat 8 而不是 Spring Boot.我对此进行了很多搜索,但问题仍然存在。 寻求帮助。 谢谢!

项目结构:

UserController.java

package com.ro.user.controller;

import com.ro.user.model.UserModel;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.validation.Valid;

@Controller
public class UserController {
    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public UserModel user(Model model) {

        UserModel userModel = new UserModel();
        model.addAttribute("userModel", userModel);

        return userModel;
    }

    @RequestMapping(value = "/userLogin", method = RequestMethod.POST)
    public String userLogin(@Valid @ModelAttribute("userModel") UserModel userModel, BindingResult bindingResult) {
        System.out.println("Before: bindingResult.hasErrors()");
        if (bindingResult.hasErrors()) {
            System.out.println("After: bindingResult.hasErrors()");
            return "user";
        }

        return "result";
    }
}

UserModel.java

package com.ro.user.model;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class UserModel {

    @NotNull
    @Size(min = 6, max = 12)
    private String username;

    @Size(min = 8, max = 16)
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

user.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<html>
<head>
    <title>Spring MVC Form Handling</title>
    <style>
        .error {
            color: #ff0000;
        }

        .errorblock {
            color: #000;
            background-color: #ffEEEE;
            border: 3px solid #ff0000;
            padding: 8px;
            margin: 16px;
        }
    </style>
</head>
<body>

<h2>User Information</h2>
<form:form action="userLogin" modelAttribute="userModel" method="POST">
    <form:errors path="*" cssClass="errorblock" element="div"/>
    <table>
        <tr>
            <td><form:label path="username">Username:</form:label></td>
            <td><form:input path="username"/></td>
            <td><form:errors path="username" cssClass="error"/></td>
        </tr>
        <tr>
            <td><form:label path="password">Password:</form:label></td>
            <td><form:input path="password"/></td>
            <td><form:errors path="username" cssClass="error"/></td>
        </tr>
        <tr>
            <td colspan="3">
                <input type="submit" value="Submit"/>
            </td>
        </tr>
    </table>
</form:form>
</body>
</html>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>UserLogin</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>UserLogin</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

用户登录-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <mvc:annotation-driven/>

    <context:component-scan base-package="com.ro.user.controller"/>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <bean class="org.springframework.context.support.ResourceBundleMessageSource" id="messageSource">
        <property name="basename" value="com.ro.user.model.error"/>
    </bean>

</beans>

这个问题是由于缺少Hibernate Validator 的依赖造成的。应该将所有Jars添加到项目的lib中名为required的文件夹中(从官方网站下载zip并解压缩,你会看到这个文件夹)。不仅仅是 hibernate-validator.jar 和 validation-api.jar.

我猜你已经创建了一个自定义的 HandlerAdapter,然后你需要手动初始化 webBinding。

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="webBindingInitializer">
        <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
            <property name="validator" ref="validator"/>
        </bean>
    </property>
</bean>

我遇到了同样的问题。我通过更改休眠验证程序版本解决了它。就我而言,它适用于 6.2 版,但不适用于 7 版。