在阅读了教程和文档之后,我仍然不理解在 SpringMVC + hibernate 中绑定某些Object属性的机制。
假设我们有一个班级Poem
:
package com.test.poems.model;
import com.tastyminerals.poems.model.Author;
import com.tastyminerals.poems.model.Genre;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "P_POEM")
public class Poem {
@Id
@GeneratedValue
@Column(name="ID")
private Integer id;
@Column(name="TITLE")
private String title;
@Column(name="BODY")
private String body;
@Column(name="DATE")
private String date;
@ManyToOne
@JoinColumn(name="ID", referencedColumnName="ID_AUTHOR", insertable = false, updatable = false)
private Author author;
@ManyToOne
@JoinColumn(name="ID", referencedColumnName="ID_GENRE", insertable = false, updatable = false)
private Genre genre;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Author getAuthor() {
return author;
}
public Genre getGenre() {
return genre;
}
public void setAuthor(Author author) {
this.author = author;
}
public void setGenre(Genre genre) {
this.genre = genre;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
和一个班级Author
:
@Entity
@Table(name = "AUTHORS")
public class Author {
@Id
@GeneratedValue
@Column(name="ID_AUTHOR")
private Integer id;
@Column(name="NAME")
private String name;
/* getters and setters */
我需要通过hibernate将我的诗提交到mysql数据库。为此,我创建了一个简单的jsp页面,其中包含所有Poem属性的输入字段。
提交后RequestMethod.POST
会返回title
,body
和作者name
的字符串值。
但是,这会产生类似于:Failed to convert property value of type 'java.lang.String' to required type 'com.test.model.Author' for property 'author'
的类型转换错误。
Poem
类期望将Author
对象设置到其中,但改为使用String name
。我想知道为什么Spring没有进行必要的转换,因为我在控制器方法中明确地创建了Author
?页面提交后是否应自动解析并设置其值?
@RequestMapping(value = "/poem/add", method = RequestMethod.GET)
public ModelAndView addPoemPage() {
ModelAndView modelAndView = new ModelAndView("poem-add");
modelAndView.addObject("author", new Author());
modelAndView.addObject("poem", new Poem());
return modelAndView;
}
@RequestMapping(value = "/poem/add", method = RequestMethod.POST)
public ModelAndView addingPoem(@ModelAttribute Poem poem,
@ModelAttribute Author author) {
ModelAndView modelAndView = new ModelAndView("home");
authorService.addAuthor(author);
poem.setAuthor(author);
poemService.addPoem(poem);
return modelAndView;
}
我的jsp页面:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<c:set var="url">${pageContext.request.requestURL}</c:set>
<link
href="${pageContext.request.contextPath}/resources/css/poem-add.css"
rel="stylesheet" />
<title>Writing a poem</title>
</head>
<body>
<h1>New poem</h1>
<p>Here you can write your poem.</p>
<form:form method="POST" commandName="poem"
action="${pageContext.request.contextPath}/poem/add.html">
<table>
<tbody>
<tr>
<td>Title:</td>
<td><input id="" title="Your poem's title" id="title"
name="title" type="text" class="input" /></td>
</tr>
<tr>
<td>Author:</td>
<td><input title="Author's name" id="author" name="author"
type="text" class="input" /></td>
</tr>
<tr>
<td>Date:</td>
<td><input title="Date of creation" id="date" name="date"
type="text" class="input" /></td>
</tr>
<tr>
<td>Text:</td>
<td><textarea title="Your poem goes here" rows="15" cols="50"
class="input"> </textarea></td>
</tr>
</tbody>
</table>
<table class="actions">
<tr>
<td><a
href="${pageContext.request.contextPath}/collection.html"><input
type="button" value="Back" class="button" /></a></td>
<td><a
href="${pageContext.request.contextPath}/collection.html"><input
type="submit" value="Submit" class="button" /></a></td>
</tr>
</table>
</form:form>
</body>
</html>
我知道我需要PropertyEditor
或BeanWrapper
。但我根本不明白我在哪里以及如何实施它们?有什么区别?
总结我的问题,我需要解释正在发生的事情&#34;幕后花絮&#34;在我点击提交按钮后,在hibernate和SpringMVC之间。如果您能为我的案例提供PropertyEditor
或BeanWrapper
的样本,我将无休止地感激不尽。
答案 0 :(得分:2)
我需要解释之间“幕后”的内容 hibernate和SpringMVC
:还没有休眠。您只需使用Spring MVC将普通bean(模型)映射到JSP。
我知道我需要一个PropertyEditor或BeanWrapper。
:您现阶段不需要PropertyEditor。 PropertyEditor用于高级类型转换,例如当您希望将传入日期字符串“dd-mm-yyyy Zone”转换为java.util.Date对象时,反之亦然。
我想知道为什么Spring没有必要 转换,因为我在我的控制器方法中明确地创建了作者? 不应该在页面后自动解析和设置其值 提交?
:如果使用Spring Form标记将JSP字段正确映射到model属性,Spring将自动解析。在您的情况下,JSP表单字段未正确映射到模型,它应如下所示
<form:form method="POST" modelAttribute="poem"
action="${pageContext.request.contextPath}/poem/add.html">
<table>
<tbody>
<tr>
<td>Title:</td>
<td><form:input path="poem.title" title="Your poem's title"
type="text" class="input" /></td>
</tr>
<tr>
<td>Author:</td>
<td><form:input path="poem.author.name" title="Author's name"
type="text" class="input" /></td>
</tr>
<tr>
<td>Text:</td>
<td><form:textarea path="poem.body" title="Your poem goes here" rows="15" cols="50"
class="input" /></td>
</tr>
</tbody>
</table>
<table class="actions">
<tr>
<td><a
href="${pageContext.request.contextPath}/collection.html"><input
type="button" value="Back" class="button" /></a></td>
<td><a
href="${pageContext.request.contextPath}/collection.html"><input
type="submit" value="Submit" class="button" /></a></td>
</tr>
</table>
</form:form>
您可以向模型添加许多属性,但只能将一个模型属性附加到<form>
而不是两个。你的控制器看起来像这样。
@RequestMapping(value = "/poem/add", method = RequestMethod.GET)
public ModelAndView addPoemPage() {
ModelAndView modelAndView = new ModelAndView("poem-add");
Author author = new Author();
Poem poem = new Poem();
poem.setAuthor(author);
modelAndView.addObject("poem", new Poem());
return modelAndView;
}
@RequestMapping(value = "/poem/add", method = RequestMethod.POST)
public ModelAndView addingPoem(@ModelAttribute("poem") Poem poem) {
ModelAndView modelAndView = new ModelAndView("home");
authorService.addAuthor(poem.getAuthor);
poemService.addPoem(poem);
return modelAndView;
}