При выборе checkbox и сохранении в базу пишется пустая строка (Thymeleaf)
Небольшой проект на spring+thymeleaf, который пилится в учебных целях по урокам с ютуба (только там шаблонизатор freemarket, поэтому там спрашивать не вариант (замена произведена с целью самостоятельно параллельно разбираться)).
Напоролся на следующую проблему: При простановке checkbox на сайте и отправке, вместо отправки параметров в базу приходит пустая строка - если выбрать новое оно вообще не добавляется, если уже что-то было проставлено - стирает. (конкретно здесь некое подобие админки и проставляются права пользователя - USER или ADMIN, предполагается, что, когда заходишь в редактирование пользователя галка прав уже проставлена в зависимости от текущих прав). При этом, при уже проставленых правах - считывает и ставит чекбоксы верно. Фрагмент шаблона, который ставит чекбоксы верно, но отправляет пустоту:
<form th:action="@{/user}" method="post">
<input type="text" name="username" th:value="${user.username}">
<div th:each="role:${roles}">
<label><input th:type="checkbox"
th:name="${role}"
th:value="${role}"
th:text="${role}"
th:field ="${user.roles}">
</label>
Были попробованы другие варианты, которые верно сохраняют в базу права, но при считывании чекбоксы или всегда не выбраны или всегда выбраны:
<div th:each="role:${roles}">
<input th:type="checkbox"
th:name="${role}"
th:value="${role}"
th:checked="${roles}"> //если убрать - ничего не выбрано
<label th:text="${role}" ></label>
</div>
<div th:each="role:${roles}">
<label><input th:type="checkbox"
th:name="${role}"
th:value="${role}"
th:text="${role}"
th:checked="${roles}">//если убрать - ничего не выбрано
</label>
Как можно решить эту проблему? Спасибо.
Ниже файлы шаблона(userEdit.html) и контроллера (UserController)
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title >Edit user</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<meta charset="UTF-8">
<title>User edition </title>
</head>
<body>
User edition
<form th:action="@{/user}" method="post">
<input type="text" name="username" th:value="${user.username}">
<div th:each="role:${roles}">
<label><input th:type="checkbox"
th:name="${role}"
th:value="${role}"
th:text="${role}"
th:field ="${user.roles}">
</label>
</div>
<input type="hidden" th:value="${user.id}" name="userId">
<button type="submit">Save</button>
</form>
</body>
</html>
Контроллер: package org.studyproject.metagram.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.studyproject.metagram.domain.Role;
import org.studyproject.metagram.domain.User;
import org.studyproject.metagram.repos.UserRepo;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Controller
@RequestMapping("/user")
//@PreAuthorize("hasAuthority('ADMIN')")
public class UserController {
@Autowired
private UserRepo userRepo;
@GetMapping
public String userList(Model model) {
model.addAttribute("users", userRepo.findAll());
return "userList";
}
@GetMapping("{user}")
public String userEditForm(@PathVariable User user, Model model) {
model.addAttribute("user", user);
model.addAttribute("roles", Role.values());
return "userEdit";
}
@PostMapping
public String userSave(
@RequestParam String username,
@RequestParam Map<String, String> form,
@RequestParam("userId") User user
) {
user.setUsername(username);
Set<String> roles = Arrays.stream(Role.values())
.map(Role::name)
.collect(Collectors.toSet());
user.getRoles().clear();
for (String key : form.keySet()) {
if (roles.contains(key)) {
user.getRoles().add(Role.valueOf(key));
}
}
userRepo.save(user);
return "redirect:/user";
}
}
Ответы (1 шт):
Решение простое:
th:checked="${#lists.contains(user.roles, role)}" >