Spring MVC表单验证无效

时间:2014-01-31 10:55:12

标签: spring validation spring-mvc

我正在使用Spring 4。 我的表单包含以下变量:

@NotNull
@Email
private String email;
@NotNull
private String firstName;
@NotNull
private String lastName;
@Digits(fraction = 0, integer = 10)
private String phoneNo;
@NotNull
private String role;

我的控制器:

@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public ModelAndView add(@ModelAttribute("user") @Valid UserBean user, BindingResult result) {
    String message;
    if (result.hasErrors() && user != null)
        return new ModelAndView("userAdd");
    else {
        userService.addUser(user);
        message = "Successfully added user";
    }
    return new ModelAndView("success", "message", message);
    }

    @RequestMapping(value = "/register")
    public ModelAndView register(@ModelAttribute("user") UserBean user, BindingResult result) {
    List<String> roles = new ArrayList<String>();
    roles.add("Receiver");
    roles.add("Resolver");
    roles.add("Logger");
    Map<String, List<String>> model = new HashMap<String, List<String>>();
    model.put("roles", roles);
    return new ModelAndView("userAdd", "model", model);
    }
}

我的jsp:

<c:url var="userAdd" value="user/add.do" />
    <sf:form method="post" action="${userAdd}" modelAttribute="user">
        <table>
            <tr>
                <td>First Name</td>
                <td><sf:input path="firstName" /><br /> <sf:errors
                        path="firstName" cssClass="error" /></td>
            </tr>
            <tr>
                <td>Last Name</td>
                <td><sf:input path="lastName" /><br /> <sf:errors
                        path="lastName" cssClass="error" /></td>
            </tr>
            <tr>
                <td>Email</td>
                <td><sf:input path="email" /><br /> <sf:errors
                        path="email" cssClass="error" /></td>
            </tr>
            <tr>
                <td>Phone No.</td>
                <td><sf:input path="phoneNo" /><br /> <sf:errors
                        path="phoneNo" cssClass="error" /></td>
            </tr>
            <tr>
                <td>Role</td>
                <td><sf:select path="role" items="${model.roles}" /><br /> <sf:errors
                        path="role" cssClass="error" /></td>
            </tr>
            <tr>
                <td><input type="submit" value="Submit" /></td>
            </tr>
        </table>
    </sf:form>

当我将输入留空时,表单不会验证并且不会抛出任何错误。 BindingResult中没有任何错误。

我的图书馆是: Libraries

我的dispatcher-serlvet.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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        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">
    <!-- Scans for annotated @Controllers in the classpath -->
    <context:component-scan base-package="com.mj.cchp.controller">
        <context:include-filter type="annotation"
            expression="org.springframework.stereotype.Controller" />
    </context:component-scan>
    <bean id="myBeansValidator"
        class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
    <mvc:annotation-driven validator="myBeansValidator" />
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/pages/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>
</beans>

我的applicationContext是:

<?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"
    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">
    <!-- Scans for annotated @Controllers in the classpath -->
    <context:component-scan base-package="com.mj.cchp">
        <context:exclude-filter type="annotation"
            expression="org.springframework.stereotype.Controller" />
    </context:component-scan>
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver" />
        <property name="url" value="jdbc:db2://172.16.2.181:60000/CCHP" />
        <property name="username" value="db2inst1" />
        <property name="password" value="db2inst1" />
    </bean> 
</beans>

我的web.xml是:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>CCHP</display-name>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/application-context.xml</param-value>
    </context-param>
    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

8 个答案:

答案 0 :(得分:8)

您需要添加

<bean id="myBeansValidator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />

<mvc:annotation-driven validator="myBeansValidator">

    <!-- Hibernate Validator -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>4.2.0.Final</version>
    </dependency>

应该工作!

答案 1 :(得分:2)

我有一个类似的问题,在我的情况下只需添加hibernate验证器的依赖: org.hibernate:hibernate-validator:5.2.4.Final

验证由 LocalValidatorFactoryBean bean完成,有关它的文档很方便(here)。

但与此同时值得一提的是,只要您使用@EnableWebMvc注释,就不必显式实例化 LocalValidatorFactoryBean http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-config-validation

  

默认情况下使用@EnableWebMvc或   自动在Spring MVC中注册Bean Validation支持   Bean验证提供程序时的LocalValidatorFactoryBean   在类路径上检测到Hibernate Validator。

希望这有帮助。

答案 2 :(得分:1)

我不确定您是否找到了解决此问题的方法。我也面临同样的问题。我设法解决了它。我的设置问题完全是手动的,我将整个hibernate-validator-5.1.3.Final-dist.zip放在lib文件夹中,这是一个很大的错误。

所以我做的是在dist文件夹中的“hibernate-validator-5.1.3.Final-dist.zip”中找到这6个文件并将其放在web应用程序库中。

  • 同学-1.0.0.jar
  • 冬眠验证器-5.1.3.Final.jar
  • javax.el-2.2.4.jar
  • javax.el-API-2.2.4.jar
  • 的JBoss-测井3.1.3.GA.jar
  • 验证-API-1.1.0.Final.jar

这解决了我的问题。

答案 3 :(得分:0)

我也面临同样的问题,即我的整个代码都已正确编写。

问题是我正在使用的不同版本的jar文件。

我有hibernate-validator-cdi-5.0.7.Final和hibernate-validator-6.0.2.Final。

确保您的jar文件版本相同。

当我保留所有相同版本的罐子时,我的问题得到了解决。我希望这会对你有所帮助。

答案 4 :(得分:0)

在我的情况下,hibernate-validator jar在运行时不可用。我已将它们复制到... / WEB-INF / lib /然后它正常工作。

答案 5 :(得分:0)

我遇到了同样的问题。我通过在dispatcher-serlvet.xml文件中添加以下语句来解决。

<mvc:annotation-driven />

答案 6 :(得分:0)

我添加了您所做的常用内容(pom 中的库、RequestBody 上的 @Valid 等)

<dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.1.3.Final</version>
        </dependency>
        <dependency>
        <groupId>org.glassfish</groupId>
        <artifactId>javax.el</artifactId>
        <version>3.0.1-b11</version>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>2.0.1.Final</version>
        </dependency>

Spring 文档(和许多博客)的微妙之处在于 Spring 会寻找一个退出点来抛出错误,但如果该退出点不存在,它将回复 404。在阅读了很多之后,尤其是这个 { {3}},添加这个类让 Spring 识别 @Valid 并找到一个退出点来抛出错误

    @RestControllerAdvice
    @Order(1) 
    public class RestControllerExceptionHandler {

    @RequestMapping(value = { "error/404" }, method = RequestMethod.GET)
    @ExceptionHandler(Exception.class)
    public String handleUnexpectedException(Exception e) {
        return "views/base/rest-error";         
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public String handlemethodArgumentNotValid(MethodArgumentNotValidException exception) { //
        // TODO you can choose to return your custom object here, which will then get transformed to json/xml etc.
        return "Sorry, that was not quite right: " + exception.getMessage();
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(ConstraintViolationException.class)
    public String handleConstraintViolation(ConstraintViolationException exception) { //
        // TODO you can choose to return your custom object here, which will then get transformed to json/xml etc.
        return "Sorry, that was not quite right: " + exception.getMessage();
    }

    
}

答案 7 :(得分:0)

我花了将近 2 天的时间解决了同样的问题,最终找到了一个解决方案,如果您仍然有这个问题,我想建议您一个答案,就我而言,我尝试使用 hibernate-validator-5.1.3.Final -dist.zip,5.2.4.Final-dist.zip, 7.0.0.Final-dist.zip 但这些都不适合我,但是当我使用 hibernate-validator-6.2.0.Final-dist< /em>,它支持 jarkarta 验证,但它可以完美运行,尽管人们说因为 Jakarta Bean 验证它在 hibernate-validator 的版本 post 5 中不起作用。它奇迹般地工作,相信我,它也可能对你有用。