すべてのタイプのUploadedFile
ユーザーアップロードを処理できる1つの汎用フォームがあるユーザーケースを設定しようとしています。クラス階層ごとの単一テーブルの子クラスへの親クラスのキャスト
@Entity(name="UploadedForm")
@Table(name="uploaded_file")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="type",discriminatorType=DiscriminatorType.STRING)
public class UploadedFile implements Serializable{
/**
*
*/
private static final long serialVersionUID = -6810328674369487649L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id")
protected Long id;
@Column(name="name")
protected String name = null;
@Column(name="bytes",unique=true)
@Lob
protected byte[] bytes;
@Column(name="type",nullable=false, updatable=false, insertable=false)
protected String type;
@ManyToOne(fetch=FetchType.LAZY, targetEntity=User.class)
@JoinColumn(name="user_id")
protected User user;
@Column(name="date_submitted")
@Temporal(TemporalType.DATE)
protected Date dateSubmitted;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Date getDateSubmitted() {
return dateSubmitted;
}
public void setDateSubmitted(Date dateSubmitted) {
this.dateSubmitted = dateSubmitted;
}
@PrePersist
@PreUpdate
public void populateDateSubmitted(){
this.dateSubmitted = new java.sql.Date(new java.util.Date().getTime());
}
public byte[] getBytes() {
return bytes;
}
public void setBytes(byte[] bytes) {
this.bytes = bytes;
}
public String getType() {
return type;
}
}
@Entity(name="Document")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorValue(value="Document")
public class DocumentFile extends UploadedFile {
public void setDateSubmitted(Date dateSubmitted) {
this.dateSubmitted = dateSubmitted;
}
@PrePersist
@PreUpdate
public void populateDateSubmitted(){
this.dateSubmitted = new java.sql.Date(new java.util.Date().getTime());
}
public byte[] getBytes() {
return bytes;
}
public void setBytes(byte[] bytes) {
this.bytes = bytes;
}
}
@RequestMapping(value="{type}",method=RequestMethod.GET)
public String showForm(ModelMap model, @PathVariable("type") String type){
UploadedFile form = null;
if((model.get("FORM") == null)){
if(type.equals("document")){
form = new DocumentFile();
}
else if(type.equals("image")){
form = new ImageFile();
}
}else{
form = (UploadedFile)model.get("FORM");
if(form.getClass() == DocumentFile.class)
form = (DocumentFile)form;
else if(form.getClass() == ImageFile.class)
form = (ImageFile)form;
}
model.addAttribute("message", "Please select your file and hit submit.");
model.addAttribute("FORM", form);
model.addAttribute("type", type);
return "upload_form";
}
@RequestMapping(method=RequestMethod.POST)
public String processForm(Model model, @RequestParam(value="type") String type, @ModelAttribute(value="FORM") UploadedFile form,BindingResult result, Principal principal) throws FileSaveException, Exception{
if(!result.hasErrors()){
UploadedFile savedFile = null;
try {
// Find the currently logged in user. There has to be a more eloquent way...
String username = principal.getName();
User user = uService.findByName(username);
// Set the associated user to the UploadedFile
form.setUser(user);
if(type.equals("document"))
form = (DocumentFile)form;
else if(type.equals("image"))
form = (ImageFile)form;
// Persist the file
savedFile = this.saveFile(form);
} catch (Exception e) {
FileSaveException fse = new FileSaveException("Unable to save file: " + e.getMessage());
fse.setStackTrace(e.getStackTrace());
throw fse;
}
model.addAttribute("message", "SUCCESS!");
model.addAttribute("FORM", savedFile);
return "upload_success";
}else{
return "upload_form";
}
}
<%@ include file="/WEB-INF/views/includes.jsp" %>
<%@ page session="false" %>
<%@ include file="/WEB-INF/views/header.jsp" %>
<head>
<title>upload</title>
</head>
<body>
<h1>Upload Stuff -</h1>
${message}
<br />
<br />
<form:form commandName="FORM" action="/upload"
enctype="multipart/form-data" method="POST">
<input type="hidden" name="type" value="${ type }"/>
<table>
<tr>
<td colspan="2" style="color: red;"><form:errors path="*"
cssStyle="color : red;" /> ${errors}</td>
</tr>
<tr>
<td>Name :</td>
<td>
<form:input type="text" path="name" />
</td>
</tr>
<tr>
<td>File:</td>
<td>
<form:input type="file" path="bytes" />
</td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Upload File" />
</td>
</tr>
</table>
</form:form>
<br />
<a href="/">Go home</a>
</body>
<%@ include file="/WEB-INF/views/footer.jsp"%>
そして、私は取得していますエラーは次のとおりです:だから、ここに私のセットアップがある
DocumentFile
に任意のアイデアをオブジェクトUploadedFile
をキャストすることができません
どうして?
UPDATE:私は実際に永続化したいコンクリートクラスを渡す代わりに、UploadedFileを回避しないで回避策を見つけました。私もコントローラ/サービス/ DAOのメソッドを削除し、各UploadedFileの子に1つ作成しなければなりませんでした。これを行うためのより良い方法があるように見えます。あなたの提案をお願いします。前もって感謝します! :)
ええ、それは私がやったことです。私は私の更新メッセージにそれを掲載しました。ちょうどそれをやっているよりクリーンな方法があることを望んでいた。あなたの提案に感謝します。 :) –
"着信要求を変換するときに、春にはのというインスタントを作成する必要があることを知る方法はありません。このステートメントは、フォームに「子」オブジェクトを送信し、フォームフィールドを設定するためにリフレクションが使用されているため、フレームワークが「子」オブジェクトを返すためにフレームワークが理解しているか、「覚えている」コントローラーのそれぞれのPOSTメソッド。 –
Rick
@Rickそして、私はあなたがSpring MVCに失望してしまうのではないかと心配しています。これはASPやJSFと異なり、複雑なビューステートを維持せず、ビューはモデルと疎結合しています。あなたがそのレベルの「知性」を探しているのであれば、春はあなたのために適切ではありません。一方で、より複雑で緊密に結合されたフレームワークは、代わりに他の多くの方法であなたの手を結びつけているので、常にトレードオフがあります。 – pap