【发布时间】:2013-12-28 19:12:21
【问题描述】:
在一个使用 hibernate 和 jpa 的 spring mvc 应用程序中,我有一个表单需要存储一个文档,其中包括有关文档的元数据,例如提交表单的当前日期。我已经设置了模型、控制器和 jsp,但是当它运行时,当用户单击按钮将文档提交到数据库时,会返回创建或添加 jsp。该错误表明问题在于代码未处理从 String 到 Blob 的转换。我已经在 processCreationForm() 方法中注明了代码返回 createOrUpdateDocumentForm.jsp 而不是重定向到列表 JSP 的位置,并且我在此帖子的底部包含了错误消息。
如何更改下面的代码,以便在用户单击提交按钮时将文档保存到数据库中?
这是我的 createOrUpdateDocumentForm.jsp:
<body>
<script>
$(function () {
$("#created").datepicker({ dateFormat: 'yy/mm/dd'});
});
</script>
<div class="container">
<jsp:include page="../fragments/bodyHeader.jsp"/>
<c:choose>
<c:when test="${document['new']}">
<c:set var="method" value="post"/>
</c:when>
<c:otherwise>
<c:set var="method" value="put"/>
</c:otherwise>
</c:choose>
<h2>
<c:if test="${document['new']}">New </c:if>
Document
</h2>
<form:form modelAttribute="document" method="${method}"
class="form-horizontal">
<div class="control-group" id="patient">
<label class="control-label">Patient </label>
<c:out value="${document.patient.firstName} ${document.patient.lastName}"/>
</div>
<petclinic:inputField label="Name" name="name"/>
<petclinic:inputField label="Description" name="description"/>
<div class="control-group">
<petclinic:selectField name="type" label="Type " names="${types}" size="5"/>
</div>
<td><input type="file" name="content" id="content"></input></td>
<div class="form-actions">
<c:choose>
<c:when test="${document['new']}">
<button type="submit">Add Document</button>
</c:when>
<c:otherwise>
<button type="submit">Update Document</button>
</c:otherwise>
</c:choose>
</div>
</form:form>
<c:if test="${!document['new']}">
</c:if>
<jsp:include page="../fragments/footer.jsp"/>
</div>
</body>
以下是控制器的相关部分:
@RequestMapping(value = "/patients/{patientId}/documents/new", method = RequestMethod.GET)
public String initCreationForm(@PathVariable("patientId") int patientId, Map<String, Object> model) {
Patient patient = this.clinicService.findPatientById(patientId);
Document document = new Document();
patient.addDocument(document);
model.put("document", document);
return "documents/createOrUpdateDocumentForm";
}
@RequestMapping(value = "/patients/{patientId}/documents/new", method = RequestMethod.POST)
public String processCreationForm(@ModelAttribute("document") Document document, BindingResult result, SessionStatus status) {
document.setCreated();
//THE FOLLOWING LINE PRINTS OUT A VALID DATE FOR document.getCreated()
System.out.println("document.getCreated() is: "+document.getCreated());
new DocumentValidator().validate(document, result);
if (result.hasErrors()) {
System.out.println("result.getFieldErrors() is: "+result.getFieldErrors());
//THIS IS BEING RETURNED BECAUSE result.getFieldErrors() RETURNS WHAT IS BEING
//SHOWN AT THE BOTTOM OF THIS POSTING, BELOW
return "documents/createOrUpdateDocumentForm";
}
else {
this.clinicService.saveDocument(document);
status.setComplete();
return "redirect:/patients?patientID={patientId}";
}
}
这是模型,它是 Document.java 的一部分:
@Entity
@Table(name = "documents")
public class Document {
@Id
@GeneratedValue
@Column(name="id")
private Integer id;
@ManyToOne
@JoinColumn(name = "client_id")
private Patient patient;
@ManyToOne
@JoinColumn(name = "type_id")
private DocumentType type;
@Column(name="name")
private String name;
@Column(name="description")
private String description;
@Column(name="filename")
private String filename;
@Column(name="content")
@Lob
private Blob content;
@Column(name="content_type")
private String contentType;
@Column(name = "created")
private Date created;
public Integer getId(){return id;}
public void setId(Integer i){id=i;}
protected void setPatient(Patient patient) {this.patient = patient;}
public Patient getPatient(){return this.patient;}
public void setType(DocumentType type) {this.type = type;}
public DocumentType getType() {return this.type;}
public String getName(){return name;}
public void setName(String nm){name=nm;}
public String getDescription(){return description;}
public void setDescription(String desc){description=desc;}
public String getFileName(){return filename;}
public void setFileName(String fn){filename=fn;}
public Blob getContent(){return content;}
public void setContent(Blob ct){content=ct;}
public String getContentType(){return contentType;}
public void setContentType(String ctype){contentType=ctype;}
public void setCreated(){created=new java.sql.Date(System.currentTimeMillis());}
public Date getCreated() {return this.created;}
@Override
public String toString() {return this.getName();}
public boolean isNew() {return (this.id == null);}
}
上面的代码可以编译,但是当用户在输入信息上传文档后按下提交按钮时,返回相同的添加或更新表单,而不是重定向到摘要页面。这从上面的控制器方法表明 result.haserrors 为真,即使 system.out.println 检查的所有错误都不为真。 eclipse 控制台不显示错误。但是 result.getFieldErrors() 会打印出以下内容:
[
Field error in object 'document' on field 'content':
rejected value [mydocname.txt];
codes [typeMismatch.document.content,typeMismatch.content,typeMismatch.java.sql.Blob,typeMismatch];
arguments [org.springframework.context.support.DefaultMessageSourceResolvable:
codes [document.content,content];
arguments []; default message [content]];
default message
[
Failed to convert property value of type 'java.lang.String' to required type 'java.sql.Blob' for property 'content';
nested exception is java.lang.IllegalStateException:
Cannot convert value of type [java.lang.String] to required type [java.sql.Blob] for property 'content':
no matching editors or conversion strategy found
]
]
【问题讨论】:
标签: java spring hibernate jsp spring-mvc