Unoffical solution for upload photo to GAE

94 views
Skip to first unread message

Lynn Peng

unread,
Jul 19, 2009, 4:17:18 AM7/19/09
to play-framework
After this post "Upload a photo to GAE faile", i know no offical
solution for upload a file/photo to GAE with Play! but Bort promised
give a patch fufure.

Before this patch out. We can use this method to do this thing.

Firstly, we know GAE recommend us using ServletFileUpload,
FileItemIterator to implements upload file, and store the data to
datastore with Blob.

But ServletFileUpload have to work with original httpservletrequest,
which have wrap to Resquet, and cannot get it back. We have to modify
some code in Play! framework. The easiest way is modify code in
ServletWrapper.java.

1, add a field to Http.Request, called

public HttpServletRequest originalResquest;

2, add a line of code to parseRequest in ServletWrapper.java.

request.originalResquest = httpServletRequest;

okay, the framework modification is finish.

Then the save photo write code as the plain servlet code,

public static void save() {
String info = "";
String contentType = null;
ByteArrayOutputStream out = new ByteArrayOutputStream();
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iterator;
try {
request.contentType = "text/plain";
iterator = upload.getItemIterator
(request.originalResquest);
while (iterator.hasNext()) {
FileItemStream item = iterator.next();
InputStream stream = item.openStream();
if (!item.isFormField()) {
Logger.info("Got an uploaded file: " +
item.getFieldName() + ", name = " + item.getName());
if (item.getName().endsWith("gif")) {
contentType = "image/GIF";
} else if (item.getName().endsWith("jpg")) {
contentType = "image/JPEG";
} else {
info = "Not support this file format.";
render(info);
}
int len;
byte[] buffer = new byte[8192];
while ((len = stream.read(buffer, 0,
buffer.length)) != -1) {
out.write(buffer, 0, len);
}
if (out.size() > 990000) {
info = "File is too big!";
render(info);
}
Long imageStamp = new Date().getTime();
Image image = new Image(imageStamp, contentType,
new Blob(out.toByteArray()));
image.save();
info = "<img src= 'http://layneblog.appspot.com/
show/" + imageStamp + "' />";
render(info);
}
}
} catch (FileUploadException e) {
Logger.error(e, "Cannot open the image file!");
} catch (IOException e) {
Logger.error(e, "IO error when save a photo!");
}
}

Here is the show method for a photo,

public static void show(Long imageStamp) {
List<Image> imageList = Image.findBy("imageStamp",
imageStamp);
if (null == imageList || 0 == imageList.size()) {
Logger.error("No image found by imageStamp: " +
imageStamp);
return;
}
Image image = imageList.get(0);
if (image != null) {
response.contentType = image.contentType;
try {
response.out.write(image.image.getBytes());
} catch (IOException e) {
Logger.error(e, "IO error when show a photo: " +
imageStamp);
}
}
}

and this is the model,

@Entity
public class Image extends JPASupport {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;

public Long imageStamp;

@Enumerated
public Blob image;

public String contentType;

public Image(Long imageStamp, String contentType, Blob image) {
this.imageStamp = imageStamp;
this.contentType = contentType;
this.image = image;

}
}



Of cause, here is a temporary solution before a patch giving out.

Because this solution cannot work in the server provided by Play!
Because parseRequest in HttpHandler.java, use MutableHttpRequest,
which cannot translate to normal HttpServletRequest. So don't so
depression when you run fail in your own machine. upload the code to
GAE, everything will be okay.
Reply all
Reply to author
Forward
0 new messages