在Spring中使用Thymeleaf显示错误消息时出错

问题描述 投票:0回答:1

当尝试显示错误消息时,我遇到了问题。到目前为止,我有 2 个 Thymeleaf 模板,在其中一个模板上,如果我违反约束规则,我会添加一个新员工,我会收到如下错误消息:

这是预期的行为。我编写了代码,以便如果用户不满足约束规则,他们会停留在同一页面上,并且需要进行必要的更正并再次提交表单。

这是模板:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8" />
    <title>New Employee</title>
</head>
<body>
<div align="center">
    <h1>Add New Employee</h1>
    <br />
    <form action="#" th:action="@{/admin/save}" th:object="${employee}" method="post">

        <table border="0" cellpadding="10">

            <tr>
                <td>Username:</td>
                <td><input type="text" th:field="*{username}" required/></td>
                <td th:each="err : ${#fields.errors('username')}" th:text="${err}" class="error"></td>
            </tr>

            <tr>
                <td>First Name:</td>
                <td><input type="text" th:field="*{firstName}" required/></td>
                <td th:each="err : ${#fields.errors('firstName')}" th:text="${err}" class="error" ></td>
            </tr>

            <tr>
                <td>Last Name:</td>
                <td><input type="text" th:field="*{lastName}" required/></td>
                <td th:each="err : ${#fields.errors('lastName')}" th:text="${err}" class="error"></td>
            </tr>

            <tr>
                <td>Password:</td>
                <td><input type="password" th:field="*{password}" required/></td>
                <td th:each="err : ${#fields.errors('password')}" th:text="${err}" class="error"></td>
            </tr>

            <tr>
                <td>Email:</td>
                <td><input type="email" th:field="*{email}" required/></td>
                <td th:each="err : ${#fields.errors('email')}" th:text="${err}" class="error"></td>
            </tr>

            <tr>
                <td>Department:</td>
                <td>
                    <select th:field="*{department}" required>
                        <option th:value="${null}" th:text="'-----'"></option>
                        <option th:each="dept : ${departmentList}" th:value="${dept.id}" th:text="${dept.name}"></option>
                    </select>
                </td>
            </tr>

            <tr>
                <td>Role:</td>
                <td>
                    <select th:field="*{role}" required>
                        <option th:value="${null}" th:text="'-----'"></option>
                        <option th:each="r : ${roles}" th:value="${r}" th:text="${r}"></option>
                    </select>
                </td>
            </tr>

            <tr>
                <td colspan="2">
                    <button type="submit">Save</button>
                </td>
            </tr>

        </table>

        <div style="position:relative; right:108px; top:25px;">
            <a href="/admin/homepage">Go Back</a>
        </div>


    </form>
</div>
</body>
</html>
    @GetMapping("/save")
    public String showAddEmployeeForm(Model model){
        model.addAttribute("employee", new Employee());
        model.addAttribute("departmentList", departmentService.getAllDepartments());
        model.addAttribute("roles", Role.values());
        return "employeeAddForm";
    }

    @PostMapping("/save")
    public String addEmployee(@Valid @ModelAttribute("employee")Employee employee , BindingResult bindingResult, Model model){
        try {
            if (bindingResult.hasErrors()) {
                model.addAttribute("employee", employee);
                model.addAttribute("departmentList", departmentService.getAllDepartments());
                model.addAttribute("roles", Role.values());
                return "employeeAddForm";
            }
            employee.setDateEmployed(LocalDateTime.now());
            employee.setPassword(passwordEncoder.encode(employee.getPassword())); // triba mi DTO za ove stvari ?
            employeeService.saveEmployee(employee);
            return "redirect:/admin/save";
        } catch (UsernameAlreadyExistsException ex) {
            model.addAttribute("errorMessage", ex.getMessage());
            return "errorpage";
        }
    }

现在我尝试对其他模板执行相同的操作,但由于某种原因,错误消息没有显示,但约束受到尊重,因此,如果用户名太长,则不会更新,并且用户停留在页面上,但他们不这样做不知道出了什么问题。

这是模板:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Edit Employee</title>
</head>
<body>
<div align="center">
    <h1>Edit Employee</h1>
    <br />
    <form action="#" th:action="@{/admin/update}" th:object="${employee}" method="post">

        <table border="0" cellpadding="10">

            <tr>
                <td>Username:</td>
                <td><input type="text" th:field="*{username}"/></td>
                <td th:each="err : ${#fields.errors('username')}" th:text="${err}" class="error"></td>
            </tr>
            <tr>
                <td>Email:</td>
                <td><input type="email" th:field="*{email}"/></td>
                <td th:each="err : ${#fields.errors('email')}" th:text="${err}" class="error"></td>
            </tr>

            <tr>
                <td>First Name:</td>
                <td><input type="text" th:field="*{firstName}"/></td>
                <td th:each="err : ${#fields.errors('firstName')}" th:text="${err}" class="error"></td>
            </tr>

            <tr>
                <td>Last Name:</td>
                <td><input type="text" th:field="*{lastName}"/></td>
                <td th:each="err : ${#fields.errors('lastName')}" th:text="${err}" class="error"></td>
            </tr>


            <tr>
                <td>Department:</td>
                <td>
                    <select th:field="*{department}">
                        <option th:value="${null}" th:text="'-----'"></option>
                        <option th:each="dept : ${departmentList}" th:value="${dept.id}" th:text="${dept.name}"></option>
                    </select>
                </td>
            </tr>

            <tr>
                <td>Role:</td>
                <td>
                    <select th:field="*{role}">
                        <option th:value="${null}" th:text="'-----'"></option>
                        <option th:each="r : ${roles}" th:value="${r}" th:text="${r}"></option>
                    </select>
                </td>
            </tr>


            <input type="hidden" name="id" th:value="${employee.get().getId()}">

            <tr>
                <td><input type="submit" value="Edit"></td>
            </tr>


        </table>

        <div style="position:relative; right:108px; top:25px;">
            <a href="/admin/homepage">Go Back</a>
        </div>


    </form>
</div>
</body>
</html>
    @GetMapping("/edit/{id}")
    public String showEditEmployeeForm(@PathVariable UUID id, Model model){

        Optional<Employee> employee = Optional.ofNullable(employeeService.findById(id)
                .orElseThrow(() -> new UsernameNotFoundException("Username not found")));

        model.addAttribute("employee", employee);
        model.addAttribute("departmentList", departmentService.getAllDepartments());
        model.addAttribute("roles", Role.values());

        return "employee-edit";
    }

    @PostMapping("/update")
    public String saveEditedEmployee(@Valid @ModelAttribute("employee") Employee employee, BindingResult bindingResult, Model model){

        // skuzit zasto u onome gore employee-u poslanom nije moga vidit Id
        Optional<Employee> dbEmployee = Optional.ofNullable(employeeService.findById(employee.getId())
                .orElseThrow(() -> new EmployeeNotFoundException("Employee not found")));

        // hidden mozda jebe, moram stavit od DbEMployee da bi radilo ioako imaju isti id
        if (bindingResult.hasErrors()) {
            model.addAttribute("employee", dbEmployee);
            model.addAttribute("departmentList", departmentService.getAllDepartments());
            model.addAttribute("roles", Role.values());
            return "employee-edit";
        }

        employeeService.updateEmployee(dbEmployee, employee);
        return "redirect:/admin/homepage";

    }

我在控制台中没有收到任何错误,所以我不知道我做错了什么。

我不知道这是否重要,这是我通过用户名搜索员工然后显示它们并有编辑它们的选项的代码。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Find By Username</title>
</head>
<body>

    <div align="left">

        <h3>Find Employee By Username</h3>
        <form action="#" th:action="@{/admin/employee}" method="post">
            <input type="text" name="username" placeholder="enter username..">
            <input type="submit" value="Search">
        </form>
    </div>


</body>
</html>
    @GetMapping("/employee")
    public String showFindEmployeeByUsernameForm(){
        return "employeeFindByUsername";
    }

    @PostMapping("/employee")
    public String showEmployee(@RequestParam("username") String username, Model model){

        Optional<Employee> employee = Optional.ofNullable(employeeService.findByUsername(username)
                .orElseThrow(() -> new EmployeeNotFoundException("Employee with username " + username + " can't be found.")));

        model.addAttribute("employee", employee);
        return "displayEmployee";

    }
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Display Employee</title>
</head>
<body>
    <div align="center">
        <h2>Employee Data</h2>
        <table border="1" cellpadding="10">
            <thead>
            <tr>
                <th>Username</th>
                <th>Email</th>
                <th>First Name</th>
                <th>Last Name</th>
                <th>Role</th>
                <th>Department</th>
                <th>Date Employed</th>
            </tr>
            </thead>
            <tbody>
            <tr>
                <td th:text="${employee.get.getUsername()}"></td>
                <td th:text="${employee.get.getEmail()}"></td>
                <td th:text="${employee.get.getFirstName()}"></td>
                <td th:text="${employee.get.getLastName()}"></td>
                <td th:text="${employee.get.getRole()}"></td>
                <td th:text="${employee.get.getDepartment().getName()}"></td>
                <td th:text="${#temporals.format(employee.get.dateEmployed, 'dd-MMMM-yyyy')}"></td>
                <td><a th:href="@{/admin/edit/{id}(id=${employee.get.getId()})}">Edit</a></td>

            </tr>
            </tbody>
        </table>

        <div style="position:relative; right:180px; top:27px;">
            <a href="/admin/employee">Find Another Employee</a>
        </div>

        <div style="position:relative; right:180px; top:27px;">
            <a href="/admin/homepage">Back To HomePage</a>
        </div>

    </div>
</body>
</html>
java spring spring-boot rest spring-mvc
1个回答
0
投票

在 update 方法中的第二种形式中,您将返回从数据库检索的 dbEmployee 实例,而不是原始的 Model 对象员工。不幸的是,如果返回模型的不同实例,spring 将删除 BindingResult (错误)。这发生在 Spring 的 BindingAwareModelMap 类中。将您的更新方法更改为

@PostMapping("/update")
    public String saveEditedEmployee(@Valid @ModelAttribute("employee") Employee employee, BindingResult bindingResult, Model model){

        // skuzit zasto u onome gore employee-u poslanom nije moga vidit Id
        Optional<Employee> dbEmployee = Optional.ofNullable(employeeService.findById(employee.getId())
                .orElseThrow(() -> new EmployeeNotFoundException("Employee not found")));

        // hidden mozda jebe, moram stavit od DbEMployee da bi radilo ioako imaju isti id
        if (bindingResult.hasErrors()) {
            model.addAttribute("employee", employee);
            model.addAttribute("departmentList", departmentService.getAllDepartments());
            model.addAttribute("roles", Role.values());
            return "employee-edit";
        }

        employeeService.updateEmployee(dbEmployee, employee);
        return "redirect:/admin/homepage";

    }
© www.soinside.com 2019 - 2024. All rights reserved.