Objective: Suppose the client submits a string or text file to the server (Google App Engine) using a web form. I want the server to modify the original file and serve it back to the client.
I think the only way to serve files from GAE is using the Blobstore, right? Then, as we cannot modify blobs, I believe a solution would be:
- Client uploads a file using HttpRequest
- Server reads the uploaded file and copies it to a temp buffer (not sure if is there a method to do this)
- Server deletes original blob
- Server modifies data in the temp buffer
- Server writes the modified buffer to the Blobstore
- Server serves the new blob to the client
Would this work? Could you think about any other solution?
Thanks
I think the only way to serve files from GAE is using the Blobstore, right?
Wrong. A 'file' is just a way of storing data on disk; there's nothing about serving them from a webserver that requires the data come from an actual, writable disk file. You can simply accept the user's data via a form upload, modify it, and serve it back to them, without it having to ever touch disk, the blobstore, or any other permanent storage medium.
This only becomes a problem if the user's data is too large to fit in memory, in which case you will have to store the data somewhere while you work on it, such as in the blobstore.
http://code.google.com/appengine/kb/java.html#fileforms
shows you how to do it for file upload, which has to be performed thro multipart form-data.
Similarly for non-file data, where you read straight from the request stream.
You don't even have to store the file/input stream. Just spit out the processed data into the output response stream, while reading the input FileItemStream or request inputstream.
If your file/input processing requires look-forward, determine the maximum distance of look-forward and use that distance as your buffer size.
Further Edits
To respond to the client with a file type, set the response content-type or mime-type.
e.g., I've had apps which dynamically generated gifs, jpgs, xls, cvs, etc.
There isn't any difference whether source of response stream is a file you read or a stream that you generate dynamically. Because, even if you had a stored file that needs to be sent as response to client, you could still have to convert it into a response stream and flag the content-type appropriately.
For dynamically generated content, unless you need to cache the output, you need not generate the file into a web URL-visible location and then generate a new html page with the link, and send that html page to the browser. You don't need the user's browser to have to refresh itself just to get that link.
You would simply send the "file" directly with the response stream. You could design your GWT client to accept the "file", perhaps in a named frame, where the named frame src url is the app that performs the dynamic generation of the file.
Read http://en.wikipedia.org/wiki/Mime-type to find the content-type you need.
If the target client's browser does not have the content handler set-up for the response's content-type, it would as for a treatment or be treated as a file download.
I had frequently used jsp or jspx to generate dynamically generated charts or spreadsheets. No stored files involved. The response is written to while the request is being read. Let's look at the jsp page directive to set the content-type to invoke MS Excel on a CSV.
<%@ page language="java" contentType="application/vnd-ms-excel; charset=UTF-8"
pageEncoding="UTF-8"%>
For a servlet, ServletResponse.setContentType(String)
is method to set the content-type.