Spring BindingResult

来源:这里教程网 时间:2026-02-17 21:34:04 作者:

Spring BindingResult 教程展示了如何使用 BindingResult 来获取验证结果。

Spring 是用于创建企业应用的流行 Java 应用框架。

BindingResult

BindingResult保存验证和绑定的结果,并包含可能发生的错误。 BindingResult必须紧随经过验证的模型对象之后,否则 Spring 无法验证该对象并引发异常。

Spring BindingResult示例

以下应用验证用户表单,并使用 BindingResult 存储验证结果。

pom.xmlsrc├───main│   ├───java│   │   └───com│   │       └───zetcode│   │           ├───config│   │           │       MyWebInitializer.java│   │           │       WebConfig.java│   │           ├───controller│   │           │       MyController.java│   │           └───form│   │                   UserForm.java│   └───resources│       └───templates│               form.html│               showInfo.html└───test    └───java

这是项目结构。

pom.xml

<?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>    <groupId>com.zetcode</groupId>    <artifactId>bindingresultex</artifactId>    <version>1.0-SNAPSHOT</version>    <packaging>war</packaging>    <properties>        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>        <maven.compiler.source>11</maven.compiler.source>        <maven.compiler.target>11</maven.compiler.target>        <spring-version>5.1.3.RELEASE</spring-version>        <thymeleaf-version>3.0.11.RELEASE</thymeleaf-version>    </properties>    <dependencies>        <dependency>            <groupId>ch.qos.logback</groupId>            <artifactId>logback-classic</artifactId>            <version>1.2.3</version>        </dependency>        <dependency>            <groupId>javax.servlet</groupId>            <artifactId>javax.servlet-api</artifactId>            <version>4.0.1</version>            <scope>provided</scope>        </dependency>        <dependency>            <groupId>org.hibernate.validator</groupId>            <artifactId>hibernate-validator</artifactId>            <version>6.0.10.Final</version>        </dependency>        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-webmvc</artifactId>            <version>5.1.3.RELEASE</version>        </dependency>        <dependency>            <groupId>org.thymeleaf</groupId>            <artifactId>thymeleaf-spring5</artifactId>            <version>{thymeleaf-version}</version>        </dependency>        <dependency>            <groupId>org.thymeleaf</groupId>            <artifactId>thymeleaf</artifactId>            <version>{thymeleaf-version}</version>        </dependency>    </dependencies>    <build>        <plugins>            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-war-plugin</artifactId>                <version>3.2.2</version>            </plugin>            <plugin>                <groupId>org.eclipse.jetty</groupId>                <artifactId>jetty-maven-plugin</artifactId>                <version>9.4.14.v20181114</version>            </plugin>        </plugins>    </build></project>

在pom.xml文件中,我们具有项目依赖项。

<dependency>    <groupId>org.hibernate.validator</groupId>    <artifactId>hibernate-validator</artifactId>    <version>6.0.10.Final</version></dependency>

我们使用hibernate-validator进行验证。

com/zetcode/config/MyWebInitializer.java

package com.zetcode.config;import org.springframework.context.annotation.Configuration;import org.springframework.web.context.WebApplicationContext;import org.springframework.web.servlet.DispatcherServlet;import org.springframework.web.servlet.FrameworkServlet;import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;@Configurationpublic class MyWebInitializer extends        AbstractAnnotationConfigDispatcherServletInitializer {    @Override    protected Class<?>[] getRootConfigClasses() {        return null;    }    @Override    protected Class<?>[] getServletConfigClasses() {        return new Class[]{WebConfig.class};    }    @Override    protected String[] getServletMappings() {        return new String[]{"/"};    }}

MyWebInitializer初始化 Spring Web 应用。 它包含一个配置类:WebConfig。

com/zetcode/config/WebConfig.java

package com.zetcode.config;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.ViewResolver;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import org.thymeleaf.spring5.SpringTemplateEngine;import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;import org.thymeleaf.spring5.view.ThymeleafViewResolver;@Configuration@EnableWebMvc@ComponentScan(basePackages = {"com.zetcode"})public class WebConfig implements WebMvcConfigurer {    @Autowired    private ApplicationContext applicationContext;    @Bean    public SpringResourceTemplateResolver templateResolver() {        var templateResolver = new SpringResourceTemplateResolver();        templateResolver.setApplicationContext(applicationContext);        templateResolver.setPrefix("classpath:/templates/");        templateResolver.setSuffix(".html");        return templateResolver;    }    @Bean    public SpringTemplateEngine templateEngine() {        var templateEngine = new SpringTemplateEngine();        templateEngine.setTemplateResolver(templateResolver());        templateEngine.setEnableSpringELCompiler(true);        return templateEngine;    }    @Bean    public ViewResolver viewResolver() {        var resolver = new ThymeleafViewResolver();        var registry = new ViewResolverRegistry(null, applicationContext);        resolver.setTemplateEngine(templateEngine());        registry.viewResolver(resolver);        return resolver;    }}

WebConfig配置 Thymeleaf 模板引擎。 Thymeleaf 模板文件位于类路径的templates子目录中。

com/zetcode/form/UserForm.java

package com.zetcode.form;import javax.validation.constraints.Email;import javax.validation.constraints.NotBlank;import javax.validation.constraints.Size;public class UserForm {    @NotBlank    @Size(min=2)    private String name;    @NotBlank    @Email    private String email;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getEmail() {        return email;    }    public void setEmail(String email) {        this.email = email;    }}

这是一个表单 bean。 它包含一些验证注释。

@NotBlank@Size(min=2)private String name;

name 属性不能为空,并且必须至少包含 2 个字符。

@NotBlank@Emailprivate String email;

email 属性不能为空,并且必须是格式正确的电子邮件。

com/zetcode/controller/MyController.java

package com.zetcode.controller;import com.zetcode.form.UserForm;import org.springframework.stereotype.Controller;import org.springframework.validation.BindingResult;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.ModelAttribute;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.servlet.mvc.support.RedirectAttributes;import javax.validation.Valid;@Controllerpublic class MyController {    @GetMapping(value = "/")    public String form(UserForm userForm) {        return "form";    }    @PostMapping("/")    public String checkForm(@Valid UserForm userForm, BindingResult bindingResult,                            RedirectAttributes atts) {        if (bindingResult.hasErrors()) {            return "form";        }        atts.addAttribute("name", userForm.getName());        atts.addAttribute("email", userForm.getEmail());        return "redirect:/showInfo";    }    @GetMapping("/showInfo")    public String showInfo(@ModelAttribute("name") String name,                           @ModelAttribute("email") String email) {        return "showInfo";    }}

MyController包含请求路径到处理程序方法的映射。

@GetMapping(value = "/")public String form(UserForm userForm) {    return "form";}

主页返回一个包含表单的视图。 UserForm bean 正在支持表单。 它将使用来自表单的数据进行填充。

@PostMapping("/")public String checkForm(@Valid UserForm userForm, BindingResult bindingResult,                        RedirectAttributes atts) {...

我们用@Valid验证UserForm bean。 验证结果存储在BindingResult中。

if (bindingResult.hasErrors()) {    return "form";}

如果绑定结果包含错误,我们将返回表格。

atts.addAttribute("name", userForm.getName());atts.addAttribute("email", userForm.getEmail());return "redirect:/showInfo";

遵循发布后重定向模式,成功验证后,我们将重定向到showInfo视图。 为了不丢失输入,我们将它们存储在RedirectAttributes中。

@GetMapping("/showInfo")public String showInfo(@ModelAttribute("name") String name,                        @ModelAttribute("email") String email) {    return "showInfo";}

@ModelAttribute将请求属性 nad 放入模型对象,然后将其发送到showInfo视图。

resources/templates/form.html

<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><head>    <meta charset="UTF-8">    <title>User form</title>    <link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/semantic.min.css"          rel="stylesheet"></head><body><section class="ui container">    <form action="#" class="ui form" th:action="@{/}" th:object="{userForm}" method="post">        <div class="field">            <label>Name:</label>            <input type="text" th:field="*{name}">            <span th:if="{#fields.hasErrors('name')}" th:errors="*{name}">Name Error</span>        </div>        <div class="field">            <label>Email:</label>            <input type="text" th:field="*{email}">            <span th:if="${#fields.hasErrors('email')}" th:errors="*{email}">Email Error</span>        </div>        <button class="ui button" type="submit">Submit</button>    </form></section></body></html>

根页面包含表单。

<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/semantic.min.css"    rel="stylesheet">

表单使用语义 UI 设置样式。

<form action="#" class="ui form" th:action="@{/}" th:object="${userForm}" method="post">

th:object引用用户表单 bean。 这不是一个类名,而是一个 Spring bean 名称。 因此它是小写的。

<input type="text" th:field="*{name}">

输入被映射到userForm的name属性。

<span th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</span>

此行显示可能的验证错误。

resources/templates/showInfo.html

<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><head>    <meta charset="UTF-8">    <title>Show info</title></head><body><p>    Successfully added user <span th:text="{name}" th:remove="tag"></span> with email    <span th:text="{email}" th:remove="tag"></span></p></body></html>

此视图显示输入的信息。

在本教程中,我们在验证表单时使用了BindingResult。

相关推荐