2009年8月23日日曜日

GAE/Jでアップロードした画像をデータストアに保存し、imgタグに出力する

upload.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>TEMPLATE</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
アップロードするファイル : <input type="file" name="imgfile" /><br>
<input type="submit" value="upload" />
</form>
<img src="/indication" alt="imgfile" />
</body>
</html>
UploadTest.javaにアップロードしたファイルをPostリクエストで送信
package org.test;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import java.util.logging.Logger;

import javax.jdo.PersistenceManager;
import org.test.DataStImg;
import org.test.PMF;

public class UploadTest extends HttpServlet {
private static final Logger log =
Logger.getLogger(UploadTest.class.getName());

public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {

PersistenceManager pm = PMF.get().getPersistenceManager();
final int size = 50000;
try{
ServletFileUpload upload = new ServletFileUpload();
upload.setSizeMax(size);//50KBの制限

FileItemIterator iterator = upload.getItemIterator(req);
while (iterator.hasNext()) {
FileItemStream item = iterator.next();
InputStream stream = item.openStream();

if(item.isFormField()){
log.warning("Got a form field: " + item.getFieldName());
} else {
log.warning("Got an uploaded file: " + item.getFieldName() +
", name = " + item.getName());
//ここからが大変だった。
ByteArrayOutputStream out = new ByteArrayOutputStream();
int len;
int i = 0;
byte[] buffer = new byte[1024];
while( (len = stream.read(buffer, 0, buffer.length)) != -1){
out.write(buffer, 0, len);

}
byte[] b = out.toByteArray();

//直す気力ないけどファイル名を取得して
//contentに入れればファイル名をキーに画像を呼び出せる。
String content = "content";
DataStImg ds = new DataStImg(content, b);
pm.makePersistent(ds);
pm.close();

resp.sendRedirect("/html/upload.html");
}
}
}
catch(Exception ex){
throw new ServletException(ex);
}
}
}
package org.test;

import java.util.Date;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.google.appengine.api.datastore.Blob;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class DataStImg {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;

@Persistent
private Blob blob;

@Persistent
private String content;

public DataStImg(String content, byte[] buffer) {
blob = new Blob(buffer);
this.content = content;
System.out.println("In DataStImg");
}

public Long getId() {
return id;
}

public byte[] getImg() {
return blob.getBytes();
}

public String getContent() {
return content;
}

public void setImg(byte[] buffer) {

this.blob = blob;
}

public void setContent(String content) {
this.content = content;
}

}
Google app engineのFAQのところにあったコードを参考に作成。DataStImg.javaに画像データを保存し、再びupload.htmlにリダイレクト。imgタグsrc属性にservletを呼び出すためのURLを指定しておく。IndicationImg.javaにGETリクエストが送信される。
package org.test;

import java.util.List;
import java.io.*;
import javax.servlet.http.*;
import javax.servlet.*;
import javax.jdo.PersistenceManager;
import org.test.DataStImg;
import org.test.PMF;

public class IndicationImg extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
resp.setContentType("image/png");
PersistenceManager pm = PMF.get().getPersistenceManager();

try {
String query = "select from " + DataStImg.class.getName();
List dss = (List) pm.newQuery(query).execute();
if (dss.isEmpty()) {
resp.sendRedirect("/html/upload.html");
} else {
for (DataStImg ds : dss) {
byte[] b = ds.getImg();
BufferedInputStream in = new BufferedInputStream(
new ByteArrayInputStream(b));

ServletOutputStream out = resp.getOutputStream();
int len;
while( (len = in.read(b, 0, b.length)) != -1) {
out.write(b, 0, len);
}

out.close();
in.close();
//まずは何番目の画像とか細かいこと考えず、
//とにかく最初に入れた画像を表示する
break;
}
}
}
catch(Exception e){
e.printStackTrace();
}
finally{
pm.close();
}
}
}
これで画像が表示される。

2 件のコメント:

  1. このコメントは投稿者によって削除されました。

    返信削除
  2. List→List<DataStImg>で動きました.

    返信削除