spring boot 1.3.5 form:errors not showing for jsp

时间:2016-07-11 19:34:54

标签: validation jsp spring-mvc spring-boot

I am upgrading a spring-mvc web app from spring 4.X to be a spring boot war.

The page serves, the form is posted, the validation is executed (and records an error) but the jsp does show any errors in form:errors

THe same jsp works fine outside of spring-boot.

To be sure I'm setting my spring boot jsp app correctly I've simply added a form post to the existing "spring-boot-sample-web-jsp" (see https://github.com/spring-projects/spring-boot/tree/1.3.x/spring-boot-samples )

Here is the model object

  package sample.jsp;
  import java.io.Serializable;
  public class EmailHolderPageModel implements Serializable {
    private String emailAddress;

    public EmailHolderPageModel() {
        super();
    }

    public EmailHolderPageModel(String emailAddress) {
        super();
        this.emailAddress = emailAddress;
    }


    public String getEmailAddress() {
        return emailAddress;
    }

    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
    }

}

Here is the server side:

@Autowired
private EmailSaveValidator emailSaveValidator;

@RequestMapping("/saveEmail.html")
public ModelAndView processEmail(@ModelAttribute("myModel") EmailHolderPageModel pageModel, BindingResult result){

    ModelAndView modelAndView = null;

    emailSaveValidator.validate(pageModel, result);

    if(result.hasErrors()){
        modelAndView = new ModelAndView("enterEmail");
        EmailHolderPageModel pm = new EmailHolderPageModel("");
        modelAndView.addObject("myModel", pm);
        System.err.println("!!!Failed Validation!!!");

    } else {

        modelAndView = new ModelAndView("thankyou");
        ThankyouPageModel thankYoupageModel = new ThankyouPageModel();
        modelAndView.addObject("thankyouModel", thankYoupageModel);
    }

    return modelAndView;
}

Here is the validator

@Component
public class EmailSaveValidator implements Validator {

    public boolean supports(Class candidate) {
        return EmailHolderPageModel.class.isAssignableFrom(candidate);
    }

    public void validate(Object obj, Errors errors) {

        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "emailAddress", "emailRequired", "required field");

    }
}

Here is the jsp (truncated a little because stackoverflow is getting confused)

<%@ page session="false"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>

<html>
<head>
    <title>test entering email</title>
</head>
<body>

    <form:form commandName="myModel" method="POST" action="saveEmail.html" >
        <form:errors path="emailAddress"  htmlEscape="false" />
        <div id="formIntro">
            <spring:message  text="enter email address" />
            <p><strong><label>
                <spring:message  text="email address:" /> </label><form:input path="emailAddress" size="35" maxlength="200"/>
                </label>
            </strong></p>
        </div>
        <input type="submit" value="Submit" />
    </form:form>

</body>
</html>

The pom file is (unmodified from spring-boot-sample-web-jsp)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <!-- Your own application should inherit from spring-boot-starter-parent -->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-samples</artifactId>
        <version>1.3.6.BUILD-SNAPSHOT</version>
    </parent>
    <artifactId>spring-boot-sample-web-jsp</artifactId>
    <packaging>war</packaging>
    <name>Spring Boot Web JSP Sample</name>
    <description>Spring Boot Web JSP Sample</description>
    <url>http://projects.spring.io/spring-boot/</url>
    <organization>
        <name>Pivotal Software, Inc.</name>
        <url>http://www.spring.io</url>
    </organization>
    <properties>
        <main.basedir>${basedir}/../..</main.basedir>
        <m2eclipse.wtp.contextRoot>/</m2eclipse.wtp.contextRoot>



    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>




        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
        </dependency>



    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <useSystemClassLoader>false</useSystemClassLoader>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

==============

And the solution is do not create a new model object on error (though works fine when not a spring boot app):

@RequestMapping("/saveEmail.html")
public ModelAndView processEmail(@ModelAttribute("myModel") EmailHolderPageModel pageModel, BindingResult result){

    ModelAndView modelAndView = null;

    emailSaveValidator.validate(pageModel, result);

    if(result.hasErrors()){
        modelAndView = new ModelAndView("enterEmail");
        // !! SOLUTION !!
        // DO NOT CREATE A NEW MODEL OBJECT
        // !! SOLUTION !!
        // EmailHolderPageModel pm = new EmailHolderPageModel("");
        modelAndView.addObject("myModel", pageModel);
        System.err.println("!!!Failed Validation!!!");

    } else {

        modelAndView = new ModelAndView("thankyou");
        ThankyouPageModel thankYoupageModel = new ThankyouPageModel();
        modelAndView.addObject("thankyouModel", thankYoupageModel);
    }

    return modelAndView;
}

1 个答案:

答案 0 :(得分:0)

你的commandName应该是你的模型类的名称:例如。

public class EmailHolderPageModel{}...

在你的控制器中任何功能:

public ModelAndView anythink(@Valid EmailHolderPageModel email...)

所以,在你的jsp表格应该是:

<form:form commandName="emailHolderPageModel" />...