thymeleaf:向用户应用角色时出现字段错误(一对多关系)

rfbsl7qr  于 2021-06-29  发布在  Java
关注(0)|答案(1)|浏览(299)

我试图使一个thymeleaf应用程序,可以注册一个附加的角色,是在注册过程中选择的帐户。这是一个形象。我将尽可能多地添加相关代码,以便更好地了解正在发生的事情,然后解释问题。
用户.java:

package com.example.demo.model;

<imports>

@Entity
@Table(name = "user", uniqueConstraints = @UniqueConstraint(columnNames = "account"))
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    private String account;

    private String password;

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="role_id", nullable=false)
    private Role role;

    @OneToMany(mappedBy = "user")
    private Collection<Comment> comments;

    public User() {

    }

    public User(String firstName, String lastName, String account, String password, Role role,
            Collection<Comment> comments) {
        super();
        this.firstName = firstName;
        this.lastName = lastName;
        this.account = account;
        this.password = password;
        this.role = role;
        this.comments = comments;
    }

    <getters and setters>

}

角色.java:

package com.example.demo.model;

<imports>

@Entity
@Table(name = "role")
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToMany(fetch=FetchType.LAZY, mappedBy = "role")
    private Set<User> users = new HashSet<User>(0);

    public Role() {

    }

    public Role(String name, Set<User> users) {
        super();
        this.name = name;
        this.users = users;
    }

    <getters and setters>
}

注解.java:

<not important>

userrepository.java文件:

package com.example.demo.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.example.demo.model.User;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    User findByAccount(String account);

}

角色存储.java:

package com.example.demo.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.example.demo.model.Role;

@Repository
public interface RoleRepository extends JpaRepository<Role, Long> {

}

用户服务.java:

package com.example.demo.service;

<imports>

@Service("userService")
public class UserService {

    private UserRepository userRepository;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    public UserService(UserRepository userRepository) {
        super();
        this.userRepository = userRepository;
    }

    public User findByAccount(String account) {
        return userRepository.findByAccount(account);
    }

    public void saveUser(User user) {
        userRepository.save(user);
    }
}

角色服务.java:

package com.example.demo.service;

<imports>

@Service
public class RoleService {

    private RoleRepository roleRepository;

    public RoleService(RoleRepository roleRepository) {
        super();
        this.roleRepository = roleRepository;
    }
}

userregistrationcontroller.java:

package com.example.demo.web;

<imports>

@Controller
@RequestMapping("/registration")
public class UserRegistrationController {

    private UserService userService;

    @ModelAttribute("user")
    public User user() {
        return new User();
    }

    @Autowired
    RoleRepository roleRepository;

    @GetMapping
    public String showRegistrationForm(Model model) {
        model.addAttribute("roles", roleRepository.findAll());
        return "registration";
    }

    @PostMapping
    public String registerUserAccount(User user) {
        System.out.println();
        userService.saveUser(user);
        return "redirect:/registration?success";
    }
}

securityconfiguration.java(以防万一):

package com.example.demo.config;

<imports>

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers(
            "/registration**",
            "/js/**",
            "/css/**",
            "/img/**").permitAll().anyRequest().authenticated().
            and().formLogin().loginPage("/login").permitAll().
            and().logout().invalidateHttpSession(true).clearAuthentication(true)
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/login?logout")
            .permitAll();
    }

}

registration.html中的相关代码段:

<form th:action="@{/registration}" method="post" th:object="${user}">
    <div class="form-group">
        <label class="control-label" for="firstName">First name</label> <input
            id="firstName" class="form-control" th:field="*{firstName}"
            required autofocus="autofocus" />
    </div>

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

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

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

    <div class="form-group">
        <label class="control-label" for="role">Role</label> 
        <select class="form-control" th:field="*{role}" id="role">
            <option th:each="role: ${roles}" th:value="${role}" th:text="${role.name}"></option>
        </select>
    </div>

    <div class="form-group">
        <button type="submit" class="btn btn-success">Register</button>
        <span>Already registered? <a href="/" th:href="@{/login}">Login
                here</a></span>
    </div>
</form>

问题:每当我尝试使用所选角色创建用户时,都会出现以下错误:
字段“role”上的对象“user”中存在字段错误:拒绝值[com.example.demo.model]。role@6e32df30]; 代码[typemismatch.user.role,typemismatch.role,typemismatch.com.example.demo.model.role,typemismatch];参数[org.springframework.context.support.defaultmessagesourceresolvable:代码[user.role,role];参数[];默认消息[角色]];默认消息[未能将类型为'java.lang.string'的属性值转换为属性'role'所需的类型'com.example.demo.model.role';嵌套异常为org.springframework.core.convert.conversionfailedexception:未能将值'com.example.demo.model'的类型[java.lang.string]转换为类型[java.lang.long]。role@6e32df30'; 嵌套异常是java.lang.numberformatexception:对于输入字符串:“com.example.demo.model。role@6e32df30"]]
因此,我想我的代码应该做的是使用从表单(${role})获得的role值,并将其应用于user.java中的role变量,在关系中连接它们。取而代之的是,它没有获取角色值,而是从表单中获取字符串值“com.example.demo.model.role@[random id]”。
我对春靴和百里香还很陌生。有人知道有什么问题吗?我已经找了好几个小时来解决这个问题,但还是找不到任何对我有帮助的方法。提前谢谢。

czq61nw1

czq61nw11#

好吧,我又四处看看,终于自己找到了解决办法。结果我必须传递th:value=“${role.id}”,而不是“${role}”。以下是我所做的改变:
userregistrationcontroller.java:

package com.example.demo.web;

<imports>

@Controller
@RequestMapping("/registration")
public class UserRegistrationController {

    private UserService userService;

    public UserRegistrationController(UserService userService) {
        super();
        this.userService = userService;
    }

    @Autowired
    RoleRepository roleRepository;

    @GetMapping
    public String showRegistrationForm(Model model, User user) {
        model.addAttribute("roles", roleRepository.findAll());
        return "registration";
    }

    @PostMapping
    public String registerUserAccount(@Valid @ModelAttribute("user") User user, BindingResult result) {
        userService.saveUser(user);
        return "redirect:/registration?success";
    }
}

registration.html中的相关代码段:

<form th:action="@{/registration}" method="post" th:object="${user}">
    <div class="form-group">
        <label class="control-label" for="firstName">First name</label> <input
            id="firstName" class="form-control" th:field="*{firstName}"
            required autofocus="autofocus" />
    </div>

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

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

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

    <div class="form-group">
        <label class="control-label" for="role">Role</label> 
        <select class="form-control" th:field="*{role}" id="role">
            <option th:each="role: ${roles}" th:value="${role.id}" th:text="${role.name}"></option>
        </select>
    </div>

    <div class="form-group">
        <button type="submit" class="btn btn-success">Register</button>
        <span>Already registered? <a href="/" th:href="@{/login}">Login
                here</a></span>
    </div>
</form>

希望这能帮助那些同样困惑的人。

相关问题