阅读完教程和文档后,我仍然不明白在 SpringMVC + hibernate 中绑定(bind)某些对象属性背后的机制。
假设我们有一个类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;
}
}
和一个类作者
:
@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
的字符串值。
但是,这会产生类型转换错误,例如:无法将类型“java.lang.String”的属性值转换为属性“author”所需的类型“com.test.model.Author”
。
Poem
类期望将 Author
对象设置到其中,但获取字符串 name
。我想知道为什么 Spring 不进行必要的转换,因为我在 Controller 方法中显式创建了 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
。但我根本不明白在哪里以及如何实现它们?有什么区别?
总结我的问题,我需要在单击提交按钮后立即解释 hibernate 和 SpringMVC 之间“幕后”发生的情况。如果您能为我的案例提供 PropertyEditor
或 BeanWrapper
示例,我将不胜感激。
最佳答案
I need an explanation of what is going on "behind-the-scenes" between hibernate and SpringMVC
:还没有 hibernate 。您只需使用 Spring MVC 将普通 bean(模型)映射到 JSP。
I know that I need a PropertyEditor or BeanWrapper.
:现阶段您不需要 PropertyEditor。 PropertyEditor 用于高级类型转换,例如当您希望将传入的日期字符串“dd-mm-yyyy Zone”转换为 java.util.Date 对象时,反之亦然。
I wonder why doesn't Spring make the necessary conversions since I explicitely create Author in my controller method? Shouldn't its values be automatically resolved and set after the page submission?
:如果使用Spring Form标签将JSP字段正确映射到模型属性,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>
而不是两个。你的 Controller 看起来像这样。
@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;
}
关于java - Spring MVC 中如何在页面提交时绑定(bind)对象属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23877884/