在春季mvc應用程序,利用hibernate和jpa,我有一個表單需要存儲文檔,包括有關文檔的元數據,如提交表單時的當前日期。我建立了模型,控制器和jsp,但運行時,當用戶單擊按鈕將文檔提交到數據庫時,會返回創建或添加jsp。該錯誤表明問題在於代碼沒有處理從字符串到Blob的轉換。我沒有注意到processCreationForm()
的位置代碼返回createOrUpdateDocumentForm.jsp
的方法如果不想將列表重定向到JSP列表,並且我在此列表底部包含了錯誤消息。錯誤從字符串轉換爲blob在春天mvc休眠應用程序
如何在下面更改我的代碼,以便在用戶單擊提交按鈕時將文檔保存到數據庫?
這裏是我的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);}
}
上面的代碼編譯,但是當用戶按提交butto n在輸入信息以上傳文檔後,將返回相同的添加或更新表單,而不是重定向到摘要頁面。這從上面的控制器方法中指出,即使system.out.println檢查的錯誤沒有一個爲真,result.haserrors也是如此。 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
]
]
謝謝。如果我告訴你,添加enctype =「multipart/form-data」會導致錯誤消息,說明:java.lang.IllegalArgumentException:期望的MultipartHttpServletRequest:是否配置了MultipartResolver? – CodeMed
請參閱我的更新 –
謝謝,但這並沒有真正的幫助。我發現了額外的必需依賴項,並且我做了一個maven更新,但現在問題是上面使用SessionFractory對象管理blob的代碼部分正在返回空會話。我將它置於一個新問題中,以使事情變得簡單,但同樣的最終問題是如何將數據塊存入數據庫。你有解決方案嗎?這裏是鏈接:http://stackoverflow.com/questions/20509801/calling-session-object-from-spring-petclinic-using-jpa – CodeMed