1. 程式人生 > 程式設計 >Spring Boot構建的Web專案如何在服務端校驗表單輸入

Spring Boot構建的Web專案如何在服務端校驗表單輸入

本文首發於個人網站:Spring Boot構建的Web專案如何在服務端校驗表單輸入

這個例子用於演示在Spring Boot應用中如何驗證Web 應用的輸入,我們將會建立一個簡單的Spring MVC應用,來讀取使用者輸入並使用validation註解來檢查,並且當使用者輸入錯誤時,應用需要再螢幕上顯示錯誤資訊提示使用者重新輸入。

首先構建Maven專案,該專案的pom檔案內容如下:

<?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>org.example</groupId> <artifactId>validating-form-input</artifactId> <version
>
1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </parent> <properties> <java.version
>
1.8</java.version> </properties> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <dependencies> <!-- thymeleaf模板,用於前段渲染 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- 用於輸入驗證 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> </dependency> <!-- 用於支援嵌入式tomcat --> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-el</artifactId> </dependency> <!-- 用於spring boot應用的測試 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project> 複製程式碼

Spring Boot Maven外掛提供了很多方便的特性:

  1. 它將該專案中需要的各個Jar包收集起來,並打包成可直接執行的Jar包,以更方便得部署和傳輸;
  2. 它會搜尋包含“public static void main()”方法的類,該類就是可執行Jar包的啟動類;
  3. 它提供了內在的支援,去匹配Spring Boot的版本號。

Form物件

建立一個Form物件,用於對應HTML頁面中輸入的物件——PersonForm,

package hello;

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

/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2017/2/28
 * Time: 21:53
 */
public class PersonForm {

    @NotNull
    @Size(min = 2,max = 30)
    private String name;

    @NotNull
    @Min(18)
    private Integer age;

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String toString() {
        return "Person(Name: " + this.name + ",Age: " + this.age + ")";
    }
}
複製程式碼

在這裡,@NotNull註解表示該屬性不能為空、@Size(min=2,max=30)表示name屬性的長度在[2,30]之間,@Min(18)表示age屬性最小值為18。

web控制器

編寫一個web控制器,引用為:src/main/java/hello/WebController.java,程式碼如下:

package hello;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import javax.validation.Valid;

/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2017/3/2
 * Time: 14:07
 */
@Controller
public class WebController extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/results").setViewName("results");
    }

    @GetMapping("/")
    public String showForm(PersonForm personForm) {
        return "form";
    }

    @PostMapping("/")
    public String checkPersonInfo(@Valid PersonForm personForm,BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return "form";
        }

        return "redirect:/results";
    }
}
複製程式碼

在這個控制器中,GET方法和POST方法都對映到“/”url下,showForm方法會返回“form”字串,表示模板的名稱,檢視控制器根據這個字串查詢模板檔案form.html,在showForm的方法簽名中定義了PersonForm引數,以便模板將屬性繫結到PersonForm物件的屬性中,checkPersonFormInfo方法定義了兩個入參:(1)person物件,在這個引數前用@Valid修飾,用於檢查從form頁面提交過來的屬性值;(2)bindingResult物件,用於存放@Valid註解檢查的結果。

可以從PersonForm表格中提取屬性值,並存入PersonForm物件。@Valid註解會檢查這些屬性的有效性,如果有錯也會把錯誤資訊渲染到模板中並顯示到頁面上。

如果所有的屬性都通過校驗,該方法會將瀏覽器重定向到results頁面。

構建thymeleaf頁面

spring boot預設從src/main/resources/templates目錄下查詢html頁面,form.html和results.html都放在這裡。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Spring Boot Thymeleaf Hello World Example</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
    <form action="#" th:action="@{/}" th:object="${personForm}" method="post">
        <table>
            <tr>
                <td>Name:</td>
                <td><input type="text" th:field="*{name}" /></td>
                <td th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</td>
            </tr>
            <tr>
                <td>Age:</td>
                <td><input type="text" th:field="*{age}" /></td>
                <td th:if="${#fields.hasErrors('age')}" th:errors="*{age}">Age Error</td>
            </tr>
            <tr>
                <td><button type="submit">Submit</button></td>
            </tr>
        </table>
    </form>
</body>
</html>
複製程式碼

form.html頁面包含一個簡單的form表格,這個表格和post方法繫結。th:object表示該表格和後端的person物件繫結,這就是bean-backed form,在PersonForm物件中,可以看到th:field="*{name}"th:field=*{age}。在form表格中,緊挨著name和age標籤,有兩個用於顯示錯誤資訊的標籤。頁面的最後有個Submit按鈕,如果使用者輸入的name和age不合法,頁面會顯示錯誤提示資訊,如果使用者輸入的name和age不合法,頁面會被路由到下一個頁面。

results.html內容如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8" />
    <title>Title</title>
</head>
<body>
    Congratulations! You are old enough to sign up for this site.
</body>
</html>
複製程式碼

建立程式啟動類

建立一個Application類,用於啟動Spring Boot應用,

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2017/3/2
 * Time: 15:50
 */
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}
複製程式碼

@SpringBootApplication註解也為Thymeleaf提供了預設配置:預設情況下會從resources/templates目錄下查詢模板檔案,並將*.html檔案中的字尾忽略掉後剩下的檔名稱解析為檢視。可以通過在application.properties裡設定相關屬性來修改Thymeleaf的配置,這裡我們不再細說。

演示的程式碼:github.com/duqicauc/va…

Spring Boot 1.x系列

  1. Spring Boot的自動配置、Command-line-Runner
  2. 瞭解Spring Boot的自動配置
  3. Spring Boot的@PropertySource註解在整合Redis中的使用
  4. Spring Boot專案中如何定製HTTP訊息轉換器
  5. Spring Boot整合Mongodb提供Restful介面
  6. Spring中bean的scope
  7. Spring Boot專案中使用事件派發器模式
  8. Spring Boot提供RESTful介面時的錯誤處理實踐
  9. Spring Boot實戰之定製自己的starter
  10. Spring Boot專案如何同時支援HTTP和HTTPS協議
  11. 自定義的Spring Boot starter如何設定自動配置註解
  12. Spring Boot專案中使用Mockito
  13. 在Spring Boot專案中使用Spock測試框架
  14. Spring Boot專案中如何定製攔截器
  15. Spring Boot專案中如何定製PropertyEditors

本號專注於後端技術、JVM問題排查和優化、Java面試題、個人成長和自我管理等主題,為讀者提供一線開發者的工作和成長經驗,期待你能在這裡有所收穫。

javaadu