Spring Boot 2 + Thymeleaf: form field binding, form submission processing

Some usage of Thymeleaf in Spring Boot for form processing:
(1) use th:field attribute: to bind form fields
(2) using ids object: generally used for the use of lable with radio or checkbox
(3) form submission

Development environment: IntelliJ idea February 2, 2019
Spring Boot version: 2.1.8

Create a new Spring Boot project named demo.
pom.xml dependencies are as follows:

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

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

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

I. use th:field attribute

th:field attribute is often used to bind form fields. In addition to automatically generating id and name attributes, there will be different generation logic for different node types.
For example, input will generate the value attribute again, textarea will automatically set the text, select will automatically select the corresponding option, if it is the same form attribute, the id of radio and checkbox will grow automatically globally.
Remarks:
(1) when using the th:field attribute, if the corresponding attribute already exists in the html node, it will not be generated separately.
(2) the th:field attribute needs to use the asterisk expression * {...}, that is, first use th:object to declare the form object, and then use th:field = * {...} to process the single table field.

1,src/main/java/com/example/demo/User.java

package com.example.demo;

public class User {
    String name;
    Integer sex;
    String[] MyColors;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getSex() {
        return sex;
    }
    public void setSex(Integer sex) {
        this.sex = sex;
    }
    public String[] getMyColors() {
        return MyColors;
    }
    public void setMyColors(String[] myColors) {
        MyColors = myColors;
    }
}

2,src/main/java/com/example/demo/FieldController.java

package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.HashMap;
import java.util.Map;

@Controller
public class FieldController {
    @RequestMapping("/field")
    public String field(Model model){
        //Set user object
        User user = new User();
        user.setName("Xiaohong");
        user.setSex(0);
        model.addAttribute("user", user);
        //Gender setting
        Map<String, Object> sexes = new HashMap<String, Object>();
        sexes.put("male", 1);
        sexes.put("female", 0);
        model.addAttribute("sexes", sexes);
        return "field";
    }
}

3,src/main/resources/templates/field.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Use th:field attribute</title>
</head>
<body>
    <form th:object="${user}">
        <input type="text" th:field="*{name}" id="name1" />
        <input type="text" th:field="*{name}" />
        <input type="text" th:field="*{name}" />
        <textarea th:field="*{name}"></textarea>
        <textarea th:field="*{name}"></textarea>
        <select th:field="*{sex}">
            <option th:each="sex : ${sexes}" th:value="${sex.value}" th:text="${sex.key}"></option>
        </select>
        <select th:field="*{sex}">
            <option th:each="sex : ${sexes}" th:value="${sex.value}" th:text="${sex.key}"></option>
        </select>
        <input type="checkbox" th:field="*{name}" value="*{name}"/>
        <input type="checkbox" th:field="*{name}" value="*{name}"/>
        <input type="radio" th:field="*{name}" value="*{name}"/>
        <input type="radio" th:field="*{name}" value="*{name}"/>
    </form>
</body>
</html>

After starting the service, the browser accesses http://localhost:8080/field, and the source code of the web page is as follows:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Use th:field attribute</title>
</head>
<body>
    <form>
        <input type="text" id="name1" name="name" value="Xiaohong" />
        <input type="text" id="name" name="name" value="Xiaohong" />
        <input type="text" id="name" name="name" value="Xiaohong" />
        <textarea id="name" name="name">Xiaohong</textarea>
        <textarea id="name" name="name">Xiaohong</textarea>
        <select id="sex" name="sex">
            <option value="0" selected="selected">female</option>
            <option value="1">male</option>
        </select>
        <select id="sex" name="sex">
            <option value="0" selected="selected">female</option>
            <option value="1">male</option>
        </select>
        <input type="checkbox" value="*{name}" id="name1" name="name"/><input type="hidden" name="_name" value="on"/>
        <input type="checkbox" value="*{name}" id="name2" name="name"/><input type="hidden" name="_name" value="on"/>
        <input type="radio" value="*{name}" id="name3" name="name"/>
        <input type="radio" value="*{name}" id="name4" name="name"/>
    </form>
</body>
</html>

 

II. Using ids objects

You can use the seq method of an ids object to generate an incremental id for a specified name.
For the id generated automatically by radio and checkbox, you need to know this id when using with the label node. You can use the prev and next methods of ids objects.

1,src/main/java/com/example/demo/IdsController.java

package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class IdsController {
    @RequestMapping("/ids")
    public String ids(Model model){
        User user = new User();
        user.setName("Xiaohong");
        user.setSex(0);
        model.addAttribute("user", user);
        return "ids";
    }
}

2,src/main/resources/templates/ids.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Use ids object</title>
</head>
<body>
    <form th:object="${user}">
        <input type="text" th:field="*{name}" th:id="${#ids.seq('tname')}" />
        <input type="text" th:field="*{name}" th:id="${#ids.seq('tname')}" />

        <input type="radio" th:field="*{name}" value="*{name}" th:id="${#ids.seq('rname')}"/>
        <input type="radio" th:field="*{name}" value="*{name}" th:id="${#ids.seq('rname')}"/>

        <input type="checkbox" th:field="*{name}" value="*{name}" th:id="${#ids.seq('cname')}" />
        <input type="checkbox" th:field="*{name}" value="*{name}" th:id="${#ids.seq('cname')}"/>

        <input type="radio" th:field="*{name}" value="*{name}" />
        <label th:for="${#ids.prev('name')}" th:text="Single election A"></label>
        <input type="radio" th:field="*{name}" value="*{name}" />
        <label th:for="${#ids.prev('name')}" th:text="Single election B"></label>

        <label th:for="${#ids.next('name')}" th:text="Multiple selection A"></label>
        <input type="checkbox" th:field="*{name}" value="*{name}" />
        <label th:for="${#ids.next('name')}" th:text="Multiple selection B"></label>
        <input type="checkbox" th:field="*{name}" value="*{name}" />
    </form>
</body>
</html>

After starting the service, the browser accesses http://localhost:8080/ids, and the source code of the web page is as follows:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Use ids object</title>
</head>
<body>
    <form>
        <input type="text" id="tname1" name="name" value="Xiaohong" />
        <input type="text" id="tname2" name="name" value="Xiaohong" />

        <input type="radio" value="*{name}" id="rname1" name="name"/>
        <input type="radio" value="*{name}" id="rname2" name="name"/>

        <input type="checkbox" value="*{name}" id="cname1" name="name" /><input type="hidden" name="_name" value="on"/>
        <input type="checkbox" value="*{name}" id="cname2" name="name"/><input type="hidden" name="_name" value="on"/>

        <input type="radio" value="*{name}" id="name1" name="name" />
        <label for="name1">Single election A</label>
        <input type="radio" value="*{name}" id="name2" name="name" />
        <label for="name2">Single election B</label>

        <label for="name3">Multiple selection A</label>
        <input type="checkbox" value="*{name}" id="name3" name="name" /><input type="hidden" name="_name" value="on"/>
        <label for="name4">Multiple selection B</label>
        <input type="checkbox" value="*{name}" id="name4" name="name" /><input type="hidden" name="_name" value="on"/>
    </form>
</body>
</html>

 

III. submission of forms

After submission, use @ ModelAttribute to map the form object in the controller method.

1,src/main/java/com/example/demo/FormController.java

package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Controller
public class FormController {
    @RequestMapping("/form")
    public String form(Model model){
        setConstant(model);
        User user = new User();
        user.setName("Xiao Ming");
        user.setSex(1);
        user.setMyColors(new String[]{"white", "black"});
        model.addAttribute("user", user);
        return "form";
    }

    @PostMapping("/submit")
    public String submit(@ModelAttribute User user, Model model){
        setConstant(model);
        model.addAttribute("user", user);
        System.out.println("Full name:" + user.getName());
        System.out.println("Gender:" + (user.getSex().intValue() == 1 ? "male" : "female"));
        System.out.println("Favorite colors:" + Arrays.toString(user.getMyColors()));
        //return "redirect:/form";
        return "form";
    }

    //Set constants
    private void setConstant(Model model){
        Map<String, Object> sexes = new HashMap<String, Object>();
        sexes.put("male", 1);
        sexes.put("female", 0);
        model.addAttribute("sexes", sexes);
        String[] colors = new String[]{"red", "white", "black"};
        model.addAttribute("colors", colors);
    }
}

2,src/main/resources/templates/form.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Submission of form</title>
</head>
<body>
    <form method="post" th:action="@{/submit}" th:object="${user}">
       <table>
           <tr>
               <td>User name:</td>
               <td><input type="text" th:field="*{name}" /></td>
           </tr>
           <tr>
               <td>Gender:</td>
               <td><select th:field="*{sex}">
                       <option th:each="sex : ${sexes}" th:value="${sex.value}" th:text="${sex.key}"></option>
                    </select>
               </td>
           </tr>
           <tr>
               <td>Favorite colors:</td>
               <td>
                   <span th:each="color : ${colors}">
                       <input type="checkbox"  th:field="*{myColors}" th:value="${color}" />
                       <label th:for="${#ids.prev('myColors')}" th:text="${color}"></label>
                   </span>
               </td>
           </tr>
           <tr>
               <td colspan="2">
                   <input type="submit" value="Submission" />
               </td>
           </tr>

       </table>



    </form>
</body>
</html>

After starting the service, the browser accesses http://localhost:8080/from, as shown in the following figure:

 

The source code of the web page is as follows:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Submission of form</title>
</head>
<body>
    <form method="post" action="/submit">
       <table>
           <tr>
               <td>User name:</td>
               <td><input type="text" id="name" name="name" value="Xiao Ming" /></td>
           </tr>
           <tr>
               <td>Gender:</td>
               <td><select id="sex" name="sex">
                       <option value="0">female</option>
                       <option value="1" selected="selected">male</option>
                    </select>
               </td>
           </tr>
           <tr>
               <td>Favorite colors:</td>
               <td>
                   <span>
                       <input type="checkbox"  value="red" id="myColors1" name="myColors" /><input type="hidden" name="_myColors" value="on"/>
                       <label for="myColors1">red</label>
                   </span><span>
                       <input type="checkbox"  value="white" id="myColors2" name="myColors" checked="checked" /><input type="hidden" name="_myColors" value="on"/>
                       <label for="myColors2">white</label>
                   </span><span>
                       <input type="checkbox"  value="black" id="myColors3" name="myColors" checked="checked" /><input type="hidden" name="_myColors" value="on"/>
                       <label for="myColors3">black</label>
                   </span>
               </td>
           </tr>
           <tr>
               <td colspan="2">
                   <input type="submit" value="Submission" />
               </td>
           </tr>

       </table>



    </form>
</body>
</html>

Click submit to output the IDEA console:

Name: Xiao Ming
Gender: Male
Favorite colors: [white, black]

Keywords: Java Attribute Spring Thymeleaf

Added by teongkia on Sun, 20 Oct 2019 21:57:16 +0300