Thymeleaf错误验证: Spring Boot 启动器验证始终显示错误

umuewwlo  于 2023-01-24  发布在  Spring
关注(0)|答案(1)|浏览(174)

构建.gradle文件

dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
        implementation 'org.springframework.boot:spring-boot-starter-security'
        implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
        implementation 'org.springframework.boot:spring-boot-starter-web'
        implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
        runtimeOnly 'org.postgresql:postgresql'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
        testImplementation 'org.springframework.security:spring-security-test'
        implementation 'io.hypersistence:hypersistence-utils-hibernate-60:3.1.1'
        // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation
        implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation', version: '3.0.1'
    }

用户模型文件

import jakarta.persistence.*;
    import jakarta.validation.constraints.NotEmpty;
    import jakarta.validation.constraints.Size;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;
    
    import java.util.*;
    
    @Entity
    @Table(name = "users")
    public class UserModel implements UserDetails {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    
        @NotEmpty()
        private String username;
    
        @NotEmpty(message = "Username not be Empty!")
        @Size(min = 6, max = 50)
        private String password;
    
        private List<String> authorities;
        private boolean isAccountNonExpired;
        private boolean isAccountNonLocked;
        private boolean isCredentialsNonExpired;
        private boolean isEnabled;
    
        public UserModel() {}
        public UserModel(String username, String password, List<String> authorities,boolean isAccountNonExpired, boolean isAccountNonLocked, boolean isCredentialsNonExpired, boolean isEnabled) {
            this.username = username;
            this.password = password;
            this.authorities = authorities;
    
            this.isAccountNonExpired = isAccountNonExpired;
            this.isAccountNonLocked = isAccountNonLocked;
            this.isCredentialsNonExpired = isCredentialsNonExpired;
            this.isEnabled = isEnabled;
        }
    
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
    
            List<GrantedAuthority> authorityList = new ArrayList<>();
    
    
    
            return authorityList;
        }
    
        @Override
        public String getPassword() {
            return password;
        }
    
        @Override
        public String getUsername() {
            return username;
        }
    
        @Override
        public boolean isAccountNonExpired() {
            return isAccountNonExpired;
        }
    
        @Override
        public boolean isAccountNonLocked() {
            return isAccountNonLocked;
        }
    
        @Override
        public boolean isCredentialsNonExpired() {
            return isCredentialsNonExpired;
        }
    
        @Override
        public boolean isEnabled() {
            return isEnabled;
        }    
    }

控制器文件

import com.example.demo.user.UserModel;
import com.example.demo.user.UserModelRepository;
import jakarta.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class TestController {
    private final UserModelRepository userModelRepository;

    public TestController(UserModelRepository userModelRepository) {
        this.userModelRepository = userModelRepository;
    }

    @GetMapping("/register")
    public String showAddUserForm(UserModel userModel) {
        return "register";
    }

    @PostMapping("/register")
    public String addUser(@Valid UserModel userModel, BindingResult result, Model model) {

        if (result.hasErrors()) {
            return "register";
        }

        System.out.println(userModel);
        userModelRepository.save(userModel);

        model.addAttribute("users", userModelRepository.findAll());

        return "home";   // TODO - This will be executed inside of our HTML
    }

}

HTML文件名称:'注册表. html'

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <title>Register</title>

    <style>
        .error {
            color: red;
        }
    </style>
</head>
<body>

    <!-- ${user} Object -->
    <!-- *{username} Object attribute -->

    <form th:action="@{/register}" th:object="${userModel}" method="post" class="form">
        <div>

            <input type="text" th:field="*{username}" id="username" placeholder="username" name="username">
            <!-- <p th:if="${#fields.hasErrors('username')}" th:errorclass="error" th:errors="*{username}" /> -->
            <p th:if="${#fields.hasErrors('username')}" th:errorclass="error" th:errors="*{username}"> </p>

        </div>
        <div>

            <h2> Password </h2>
            <input type="password" th:field="*{password}" >
            <ul>
                <li th:each="error : ${#fields.errors('password')}" th:text="${error}" class="error">
            </ul>

        </div>

        <div th:if="${#fields.hasAnyErrors()}">
            <ul>
                <li th:each="error : ${#fields.allErrors()}" th:text="${error}"></li>
            </ul>
        </div>

        <input type="submit" value="Add me">

    </form>

</body>
</html>

问题每当我填写表单时,单击“提交”时总是显示错误。无论表单是否已填写。为什么总是显示错误?

我猜不知怎么的,虽然我试图呈现一个条件,它总是变成'假'。我只是不知道我做错了什么。

教程我正在学习:https://www.baeldung.com/spring-thymeleaf-error-messages

Result

mzillmmw

mzillmmw1#

问题是UserModel没有提供setter方法,因此不会(甚至不能)进行数据绑定。
要解决这个问题,请添加setter方法,告诉Spring使用直接字段绑定。
通过在控制器中添加以下方法,可以实现直接的字段绑定/访问。

@InitBinder
public void initBinder(WebDataBinder binder) {
  binder.initDirectFieldAccess();
}

上面的代码将使用字段而不是属性(getter/setter对)来进行绑定,这样你就可以不修改UserModel而仍然应用数据绑定。

相关问题