[JAVA] [Introduction to Spring Boot] Form validation check

Purpose

For those who have finished working on the Spring Quickstart Guide, those who have started learning Spring Boot, and those who want to review it.

We will share what we have learned by actually working on the official guide Validating Form Input.

The completed form is here.

There is a form to enter the name and age, スクリーンショット 2020-07-09 14.05.32.png

If the Submit button is pressed with an invalid value entered, an error message will be displayed and スクリーンショット 2020-07-09 14.05.40.png

If a valid value is entered, we will implement it so that you can move to another screen. スクリーンショット 2020-07-09 14.12.54.png

The development environment and the review so far are as follows.

Development environment


OS: macOS Mojave version 10.14.6
Text editor: Visual Studio Code (hereinafter VSCode)
Java: 11.0.2

Click here for a review of the Quickstart Guide Click here for a review of Building a RESTful Web Service Click here for a review of Consuming a RESTful Web Service Click here for a review of Accessing Data with JPA Click here for a review of the Handling Form Submission

1. Start the Spring Boot project!

First, access spring initializr.

  1. Click the ADD DEPENDENCIES button to add Spring Web and Thymeleaf. 2.Artifact, Name changed to validating-form-input.
  2. Change Java to 11.

Then click the GENERATE button to download the Zip file.

スクリーンショット 2020-07-09 14.25.27.png

Extract the downloaded Zip file and you're ready to go.

2. Add code!

Open the previous folder with VS Code. We recommend installing the Java Extension Pack for extensions. It is said that you should install it.

スクリーンショット 2020-06-30 10.08.25.png

Let's create PersonForm.java!

Create a PersonForm.java file in src / main / java / com / example / validatingforminput /.

スクリーンショット 2020-07-09 14.30.13.png

Add the code referring to the formula.

PersonForm.java


package com.example.validatingforminput;

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

public class PersonForm {

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

  @NotNull
  @Min(18)
  private Integer age;

  public String getName() {
    return this.name;
  }

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

  public Integer getAge() {
    return age;
  }

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

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

We will dig deeper into the added code.

@ Not Null and @ Size

PersonForm.java


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

Two validation annotations are added when declaring a String type name variable.

@NotNull does not allow ** null **. Please note that nulls are not allowed, empty strings and spaces are allowed.

@Size verifies whether it is ** min or more ** and ** max or less ** specified in(). This time, it is @Size (min = 2, max = 30), so an error will occur if it is not 2 or more and 30 or less.

@Min

PersonForm.java


@NotNull
@Min(18)
private Integer age;

Two validation annotations are added when declaring an Integer type age variable. (One is @ NotNull mentioned above)

@Min is verified whether it is smaller than the value described in(). This time, it is @ Min (18), so less than 18 will result in an error.

③ Getter / setter, toString method

PersonForm.java


public String getName() {
  return this.name;
}

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

public Integer getAge() {
  return age;
}

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

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

It defines getter / setter methods for getting and changing the values of variables name and age. It also defines a toString method to display name and age as strings. (I don't think I'm using it this time, but is it for debugging?)

Let's add validation dependency to pom.xml!

Although it was not mentioned in the official guide, when Spring Boot 2.3 or higher, ʻImport javax.validation.constraints. 〇〇 of PersonForm.java` will result in an error. (Spring Boot2.3 Relealse Notes)

Add the following to dependencies.

pom.xml


<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

スクリーンショット_2020-07-09_15_38_58.png

Let's create WebController.java!

Create a WebController.java file in src / main / java / com / example / validatingforminput /.

スクリーンショット 2020-07-09 15.41.24.png

Add the code referring to the formula.

WebController.java


package com.example.validatingforminput;

import javax.validation.Valid;

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.WebMvcConfigurer;


@Controller
public class WebController implements WebMvcConfigurer {

  @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";
  }
}

We will dig deeper into the added code.

① WebMvcConfigurer interface and addViewControllers method

WebController.java


@Controller
public class WebController implements WebMvcConfigurer {

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

 //The following is omitted
}

Implements the WebMvcConfigurer interface, overriding the addViewControllers method.

It is interpreted that the URL http: // localhost: 8080 / results is set to refer to the template ** results.html **. It seems that the URL and template are mapped. The implementation of results.html will be done later.

② showForm method

WebController.java


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

@GetMapping is an annotation to call the showForm method when there is a GET request athttp: // localhost: 8080 /. I am receiving a PersonForm as an argument. PersonForm can be associated with the form attribute of form.html, which is the return value of the method. We will implement form.html later.

③ checkPersonInfo method

WebController.java


@PostMapping("/")
public String checkPersonInfo(@Valid PersonForm personForm, BindingResult bindingResult) {

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

  return "redirect:/results";
}

@PostMapping is an annotation to call the checkPersonInfo method when there is a POST request athttp: // localhost: 8080 /. The first argument, @Valid PersonForm personForm, validates the input data. The second argument, BindingResult bindingResult, is an annotation to hold the input data and the validation result (whether there is an error).

In the if statement where bindingResult.hasErrors () is written, it is checked whether there is an error. If there is an error, redraw form.html with the error message and the value entered.

If there are no errors, you will be redirected to http: // localhost: 8080 / results.

Let's create form.html!

Create a form.html file in src / main / resources / templates /.

スクリーンショット 2020-07-10 10.18.06.png

Add the code referring to the formula.

form.html


<html xmlns:th="http://www.thymeleaf.org">
  <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>

It's a form screen for entering name and age.

We will dig deeper into the description of thymeleaf in the added code.

thymeleaf is a template engine that can be handled by springboot. Described as th: 〇〇. [Thymeleaf tutorial] written in Japanese (https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf_ja.html#thymeleaf%E3%81%AE%E7%B4%B9%E4%BB% There is also 8B)!

th:action

Replaces the content of the action attribute of the form tag. The description method is th: action =" @ {} ". Since method = "post", the checkPersonInfo method of WebController is called when the Submit button is pressed.

th:object

The object is specified by th: object. This allows you to refer to variables in objects like * {name} instead of personForm.name.

th:field

Write th: field =" * {variable name} " to display the variables in the object specified by th: object. This time, since there are name and age in the PersonForm class, it will be th: field =" * {name} ", th: field =" * {age} ". In addition, the variable name described in th: field =" * {variable name} " is the id attribute and name attribute of input.

th:if

Write th: if = condition. If true, the tag and child elements are displayed. This condition will be true if there is an error.

th:errors

Write th: errors =" * {variable name} ". An error message will be displayed if there is an error. It feels like you have secured an area to display error messages by checking for errors with th: if and th: errors.

Let's create results.html!

Create a results.html file in src / main / resources / templates /.

スクリーンショット 2020-07-10 11.11.36.png

Add the code referring to the formula.

results.html


<html>
  <body>
    Congratulations! You are old enough to sign up for this site.
  </body>
</html>

If no invalid value is entered on the form screen, the screen will change to this screen.

3. Let's run it!

Now that the application is ready to run, let's check.

Enter the following command in the terminal and press Enter.

Terminal


$ ./mvnw spring-boot:run

Then, when you access http: // localhost: 8080 /, you should see the form screen below. (Form.html is displayed)

スクリーンショット 2020-07-09 14.05.32.png

** Enter one letter for name and a number less than 18 for age and press the Submit button to display an error message. ** **

スクリーンショット 2020-07-10 13.38.34.png

スクリーンショット 2020-07-10 13.38.46.png

** If you press the Submit button without entering anything in age, an error message will be displayed. ** **

スクリーンショット 2020-07-10 13.41.09.png

** Enter 2 or more characters for name and 18 or more for age, and press the Submit button to display the result screen (result.html). ** **

スクリーンショット 2020-07-10 13.45.01.png

スクリーンショット 2020-07-10 13.45.07.png

Thank you for your hard work! done!

Reference site

** Verification of input value with Spring Boot ** ** If it's a Controller that just returns the view name, you don't need a separate Controller! ** ** Validation and Error Messages **

Recommended Posts

[Introduction to Spring Boot] Form validation check
Introduction to Spring Boot ① ~ DI ~
Introduction to Spring Boot ② ~ AOP ~
Introduction to Spring Boot Part 1
[Introduction to Spring Boot] Submit a form using thymeleaf
Spring Boot Form
Form class validation test with Spring Boot
An introduction to Spring Boot + in-memory data grid
[Java] Article to add validation with Spring Boot 2.3.1.
[Introduction to Spring Boot] Authentication function with Spring Security
Try Spring Boot from 0 to 100.
Introduction to Ratpack (7) --Guice & Spring
Spring Boot validation message changes
How to set Spring Boot + PostgreSQL
Get validation results with Spring Boot
Check date correlation with Spring Boot
How to use ModelMapper (Spring boot)
Upgrade spring boot from 1.5 series to 2.0 series
Introduction to Spring Boot x OpenAPI ~ OpenAPI made with Generation gap pattern ~
Story when moving from Spring Boot 1.5 to 2.1
Changes when migrating from Spring Boot 1.5 to Spring Boot 2.0
Changes when migrating from Spring Boot 2.0 to Spring Boot 2.2
How to split Spring Boot message file
Add spring boot and gradle to eclipse
[Spring Boot Actuator] How to manually register your own health check process
Introduction to Java development environment & Spring Boot application created with VS Code
Introduction to Ruby 2
Book introduction: Spring Boot Recommended reference book for beginners!
Spring Fox ① Introduction
How to use MyBatis2 (iBatis) with Spring Boot 1.4 (Spring 4)
How to use built-in h2db with spring boot
Introduction to SWING
How to make Spring Boot Docker Image smaller
How to use Spring Boot session attributes (@SessionAttributes)
The story of raising Spring Boot 1.5 series to 2.1 series
Let's check the feel of Spring Boot + Swagger 2.0
Try to implement login function with Spring Boot
Challenge Spring Boot
Spring Data REST HAL Browser to check Spring REST operation
How to add a classpath in Spring Boot
Introduction to web3j
Introduction to Micronaut 1 ~ Introduction ~
[Java] Introduction to Java
Introduction to migration
How to bind to property file in Spring Boot
Try to automate migration with Spring Boot Flyway
I wanted to gradle spring boot with multi-project
Introduction to java
Apply Twitter Bootstrap 4 to Spring Boot 2 using Webjars
Spring Boot Memorandum
gae + spring boot
Introduction to Doma
[Spring Boot] How to refer to the property file
Spring Boot --How to set session timeout time
Plans to support JDK 11 for Eclipse and Spring Boot
How to set Dependency Injection (DI) for Spring Boot
How to write a unit test for Spring Boot 2
Automatically map DTOs to entities with Spring Boot API
If you want to separate Spring Boot + Thymeleaf processing
A memorandum of addiction to Spring Boot2 x Doma2
05. I tried to stub the source of Spring Boot