Я получаю ошибку, когда пытаюсь обновить пользователя и не могу показать свои роли пользователей с помощью SpringBoot

#java #spring-boot #spring-mvc

Вопрос:

то, что я пытаюсь сделать после входа в систему, на странице пользователей я пытаюсь показать всех пользователей с их ролями, и когда я нажимаю «Изменить» на одном из них, я попадаю на страницу edit_user, на которой я разрешу редактировать пользователей, но при этом я получаю ошибку, и на странице пользователей я не могу видеть роли пользователей.

СУЩНОСТЬ ПОЛЬЗОВАТЕЛЯ:

 @Entity
@Table(name = "users" ,uniqueConstraints = @UniqueConstraint(columnNames = "userName"))
public class Users {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String userName;
private String password;



@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(
        name = "users_roles",
        joinColumns = @JoinColumn(
                name = "user_id",referencedColumnName ="id"),
        inverseJoinColumns = @JoinColumn(
                name ="role_id" ,referencedColumnName ="id"
        )

)
private Collection<Roles> roles;


public Users(String userName, String password, Collection<Roles> roles) {
    this.userName = userName;
    this.password = password;
    this.roles = roles;
}
public Users()
{
    super();
}
public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getUserName() {
    return userName;
}

public void setUserName(String userName) {
    this.userName = userName;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

public Collection<Roles> getRoles() {
    return roles;
}
 

Регистрация пользователяд

 public class UserRegistrationDto {

private String userName;
private String password;
private Collection<Roles> role;

public UserRegistrationDto(String userName, String password, Collection<Roles> role) {
    this.userName = userName;
    this.password = password;
    this.role = role;
}

public UserRegistrationDto()
{
    super();
}

public String getUserName() {
    return userName;
}

public void setUserName(String userName) {
    this.userName = userName;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

public Collection<Roles> getRole() {
    return role;
}

public void setRole(Collection<Roles> role) {
    this.role = role;
}
 

}

UserController

in this controller layer it responsible for getting,deleting,editing users

 @Controller
public class UserController {

@Autowired
private UserService userService;

@Autowired
private RoleRepository roleRepository;

public UserController(UserService userService, RoleRepository roleRepository) {
    this.userService = userService;
    this.roleRepository = roleRepository;
}

@ModelAttribute("roles")
public List<Roles> initializeRoles(){
    List<Roles> roles = roleRepository.findAll();
    return roles ;
}

@GetMapping("/users/AllUsers")
public String getAllUsers(Model model)
{
    model.addAttribute("user",userService.getAlluser());
    return "Users/users";
}

@GetMapping("/user/edit/{id}")
public String editUserForm(@PathVariable long id, Model model)
{
    model.addAttribute("user",userService.getUserById(id));

    return "Users/edit_user";
}

@RequestMapping(value = "/user/update/{id}",method = RequestMethod.POST)
public String updateUser(@PathVariable Long id, @ModelAttribute("user") UserRegistrationDto registrationDto)
{
    Users userExisting = userService.getUserById(id);

    userExisting.setId(id);

    userExisting.setUserName(registrationDto.getUserName());

    userExisting.setRoles(registrationDto.getRole());

    userService.updateUser(userExisting);

    return "redirect:/users/AllUsers";

}

@GetMapping("/user/delete/{id}")
public String deleteUser(@PathVariable long id)
{
    userService.deleteUser(id);
    return "redirect:/users/AllUsers";
}
 

}

UserService

 //save a user from the userRegistration form that been shown in the class model
public Users save(UserRegistrationDto registrationDto)
{
    //Users user = new Users(registrationDto.getUserName(),passwordEncoder.encode(registrationDto.getPassword()),Arrays.asList(new Roles(registrationDto.setRole(registrationDto.getRole()))));;//Arrays.asList(new Roles("ROLE_USER"))

    Users usersEntity = new Users();

    usersEntity.setUserName(registrationDto.getUserName());
    usersEntity.setRoles(registrationDto.getRole());
    usersEntity.setPassword(passwordEncoder.encode(registrationDto.getPassword()));

    return userRepository.save(usersEntity);
}
@Override
public Users getUserById(Long id) {
    return userRepository.findById(id).get();
}
//we converting roles to authorities
private Collection <? extends GrantedAuthority> mapRolesToAuthorities(Collection<Roles> roles) {
    return roles.stream()
            .map(role -> new SimpleGrantedAuthority(role.getName()))
            .collect(Collectors.toList());
}
 

edit_user.html

       <form th:action="@{/user/update/{id}}" method="post" th:object="${user}">

    <div class="form-group">
      <label class="control-label" for="userName"> Username </label>
      <input id="userName" class="form-control" th:field="*{userName}" required autofocus="autofocus" />
    </div>

    <div class="col-1.5">
      <label th:for="roles"> User Type: </label>
      <select class="form-control form-control-sm" id="roles" name="roles">
        <option value="">Select User Type</option>
        <option th:each = "role: ${roles}"
                th:value="${role.id}"
                th:text="${role.name}"
        >
        </option>
      </select>
    </div>



    <div class="form-group">
      <label class="control-label" for="password"> Password  </label> <input
            id="password" class="form-control" th:field="*{password}" required autofocus="autofocus" type="password" />
    </div>

    <div class="form-group">
      <button type="submit" class="btn btn-success">Submit</button>
    </div>
  </form>
 

users.html где я покажу всем пользователям

 <section class="table_content">

<!--main-container-part-->
<div id="content">

    <!--End-breadcrumbs-->

    <!--Action boxes-->
    <div class ="container">

        <div class = "row">
            <h1> All Users </h1>
        </div>

        <br>
        <br>

        <table class = "table table-striped table-bordered">
            <thead class = "table-dark">
            <tr>
                <th> Name </th>
                <th> Roles </th>
                <th> Edit </th>
                <th> Delete </th>
            </tr>
            </thead>

            <tbody>

            <tr th:each = "user: ${user}"> <!-- this attribute to list up products  -->

                <td th:text="${user.userName}" ></td>
                <td th:text="${user.roles}"></td>

                <td> <center> <a th:href="@{/user/edit/{id}(id=${user.id})}" style="color: green"> Edit </a> </center> </td>

                <td> <center> <a th:href="@{/user/delete/{id}(id=${user.id}) }" style="color: red"> Delete </a> </center> </td>

            </tr>

            </tbody>

        </table>

    </div>
</div>
 

Комментарии:

1. Вы должны предоставить нам немного больше информации об ошибке, которую вы получаете

2. спасибо Луке за это уведомление, я только что отредактировал

Ответ №1:

Первая ошибка, которую вы допустили, заключается в edit_user.html, как говорится в предоставленной вами трассировке стека, конечная точка /пользователь/обновление/{id} не может преобразовать «{id} » в длинный. Это потому, что идентификатор, который вы передаете, — это не идентификатор пользователя, а сама строка » {id}».

в edit_user.html измените это:

  <form th:action="@{/user/update/{id}}" method="post" th:object="${user}">
 

Для

  <form th:action="@{/user/update/{id}(id=${user.id})}" method="post" th:object="${user}">
 

если это все еще не работает, я предлагаю также передать идентификатор пользователя в качестве атрибута в модели.

Что касается второй проблемы, вы не можете визуализировать роли пользователей из-за этой строки в users.html:

 <td th:text="${user.roles}"></td>
 

поскольку User.roles-это коллекция, она не может быть отображена «один раз», вы должны использовать тот же синтаксис, что и в edit_user, следовательно:

 <td>
    <p th:each="role: ${user.roles}" th:text="${role.name}"></p>
</td>
 

Комментарии:

1. thnx Luca это работает, но знаете ли вы, как решить другую проблему, показывая роли для каждого пользователя в users.html стр.

2. @HeshamEldawy Я добавил решение 🙂

3. Лука, можешь подробнее объяснить, как решить вторую проблему, я все еще пытаюсь 🙂