【发布时间】:2021-09-05 00:02:46
【问题描述】:
我有一个包含 2 个实体的场景:
1)学生:
@Entity
@Table(name = "student_registration")
public class Student
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column
private String firstName;
@Column
private String lastName;
@OneToMany(mappedBy = "student", cascade = CascadeType.ALL)
private List<Hobby> hobbies;
//constructors (default, all params), getters and setters
}
2)爱好:
@Entity
@Table(name = "hobby")
public class Hobby
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "hobby_id")
private Student student;
@Column
private String name;
//contructors (default, Hobby(name, student), getters and setters)
}
我想从一组复选框中输入每个复选框选项作为一种爱好,其名称等于复选框的值
这是我上面的 JSP 部分:
<div class="form">
<form:form action="success" modelAttribute="student" onsubmit="return validate()">
<div class="row">
<div class="label">First Name</div>
<div class="field">
<form:input path="firstName" />
</div>
</div>
<div class="row">
<div class="label">Last Name</div>
<div class="field">
<form:input path="lastName" />
</div>
</div>
<div class="row">
<div class="label">Hobbies</div>
<div class="field">
<form:checkbox path="hobbies" id="hobby1Checkbox" value="Hobby 1" />
<label class="sublabel" for="hobby1Checkbox">Hobby 1</label>
<form:checkbox path="hobbies" id="hobby2Checkbox" value="Hobby 2" />
<label class="sublabel" for="hobby2Checkbox">Hobby 2</label>
<form:checkbox path="hobbies" id="hobby3Checkbox" value="Hobby 3" />
<label class="sublabel" for="hobby3Checkbox">Hobby 3</label>
</div>
</div>
</form:form>
</div>
这是我的控制器:
@Controller
public class StudentController {
@Autowired
StudentService stuServ;
@RequestMapping("/")
public String index() {
return "index";
}
@GetMapping("/registration")
public String registrationRedirect(ModelMap studentModel)
{
studentModel.addAttribute("student", new Student());
studentModel.addAttribute("hobby", new Hobby());
return "registration";
}
@PostMapping("/success")
public String sayHello(@ModelAttribute("registeredStudent") Student student) {
stuServ.addStudent(student);
return "success";
}
}
我知道我所做的不正确,因为我无法将复选框中的字符串值映射到对象列表 (List) 但是我无法找到实现相同目标的方法。我正在寻找使用 Converter 或 PropertyEditor 的可能解决方案,但我是 Spring MVC 的新手,我很困惑。
*更新:
我观察到,在仅将名称作为参数的 Hobby 类中添加参数化构造函数后,我可以使用复选框直接将值传递给 Hobby 对象,因为复选框的 String 值已初始化为通过上述构造函数的爱好名称。
如果我只是将爱好名称用于注册成功视图,则此方法有效,但是另一个明显的问题是爱好类的学生字段永远不会被初始化,因为只有构造函数 爱好(名称) 被调用,因此关系不是双向的。在 Hobby 类中,学生字段保持为空。
请以适当的方式处理这种情况。我想不出可以让 Spring 知道我将复选框选择的爱好分配给哪个学生的方法。
根据我之前提供的答案进行编辑:
如果我为 Hobby 实体创建存储库,则会出现另一个问题:
public interface HobbyRepository extends JpaRepository<Hobby, Integer>
{
boolean findByName(String hobby);
}
爱好的复选框字符串值初始化不再起作用。早些时候,带有名称参数的 Hobby 实体的构造函数完成了这项工作,但是在添加 Hobby 存储库时,我收到了以下预期错误:
出现意外错误(类型=错误请求,状态=400)。 object='registeredStudent' 的验证失败。错误计数:1 org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 个错误 字段 'hobbies' 上的对象 'registeredStudent' 中的字段错误:拒绝值 [唱歌、素描、游泳];代码 [typeMismatch.registeredStudent.hobbies,typeMismatch.hobbies,typeMismatch.java.util.List,typeMismatch];参数 [org.springframework.context.support.DefaultMessageSourceResolvable:代码 [registeredStudent.hobbies,hobbies];论据 [];默认消息[爱好]];默认消息[无法将类型“java.lang.String[]”的属性值转换为属性“爱好”所需的类型“java.util.List”;嵌套异常是 org.springframework.core.convert.ConversionFailedException:无法从类型 [java.lang.String] 转换为类型 [java.lang.Integer] 以获取值“Singing”;嵌套异常是 java.lang.NumberFormatException: For input string: "Singing"]
差不多,名称 = 复选框的字符串值的爱好不再能够初始化。我已经尝试删除 Hobby 存储库,它运行良好。 任何进一步的见解将不胜感激,因为目前唯一可能的解决方案似乎是在我的 Student POJO 类中添加一个额外的 List
【问题讨论】:
标签: forms spring-boot spring-mvc jsp spring-data-jpa