The Upload Servlet code is listed below.
packagecom.gaejexperiments.twitter; importjava.io.IOException; importjava.util.Map; importjava.util.logging.Level; importjava.util.logging.Logger; importjavax.mail.Session; importjavax.servlet.ServletException; importjavax.servlet.http.HttpServlet; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importtwitter4j.Status; importtwitter4j.Twitter; importcom.google.appengine.api.blobstore.BlobKey; importcom.google.appengine.api.blobstore.BlobstoreService; importcom.google.appengine.api.blobstore.BlobstoreServiceFactory; @SuppressWarnings("serial")
publicclassUpload extendsHttpServlet { privatefinalstaticLogger _logger = Logger.getLogger(Upload.class.getName()); privateBlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
publicvoiddoPost(HttpServletRequest req, HttpServletResponse res) throwsServletException, IOException {
Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req);
BlobKey blobKey = blobs.get("myTweetPic");
if(blobKey == null) { res.sendRedirect("/"); } else{ String strStatus = ""; try{ String twitter_userid = (String)req.getParameter("twitter_userid"); String twitter_password = (String)req.getParameter("twitter_password"); _logger.info("UserId:"+twitter_userid + " , Password:"+twitter_password);
Twitter twitter = new
String strTweet = "Check out my picture at : "+ "<a href="http://localhost:8888/viewpic.jsp?blob-
key="+blobKey.getKeyString">http://localhost:8888/viewpic.jsp?blob -key="+blobKey.getKeyString</a>();
Status status = twitter.updateStatus(strTweet); strStatus = "Successfully updated the status to ["+ status.getText() + "].";
_logger.info(strStatus); }
catch(Exception ex) {
strStatus = "Could not update Twitter Status : "+ ex.getMessage(); _logger.log(Level.WARNING,strStatus); } finally{ res.sendRedirect("/submitpic.jsp?blob- key="+blobKey.getKeyString() + "&status="+strStatus); } } } }
Let us go through the main points in the Upload Servlet code:
1. The Servlet implementation is the doPost() method. This method was invoked by the Blobstore Service after the blobs were successfully saved in the datastore.
2. As mentioned, the Blobstore Service augments the Request stream with a Map of successfully saved Blobs. It also provides a helper method that we can use to extract out this Map instance from the request stream. The code is shown below:
Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req);
3. The next thing to do is to get the Blob Key for our saved Blob. The Blob Key is unique and will be used to retrieve the Blob as we shall see later on in the viewpic.jsp code. The Key that we will use is the same as the input parameter name for our file blob that we provided in the FORM i.e. index.jsp.
BlobKey blobKey = blobs.get(“myTweetPic”);
4. We do a simple check to verify if the blobKey instance is not null. If not, we create a status update for twitter giving a url that points to the viewpic.jsp page which is passed the blob-key request parameter as shown below:
String strTweet = “Check out my picture at : ” +
Episode 13: Using the Blobstore Java API 166
5. Finally, we using Twitter4J to post out tweet using the twitter id and password that we provided.
The status of our upload and tweet is then displayed by navigating to the submitpic.jsp
page that simply shows the status and the picture that we uploaded.
submitpic.jsp
This JSP file is invoked by our Upload Servlet to display the status of our Tweet to twitter and the image that we uploaded as discussed in the previous section. You will notice an interesting thing over here and that is the <img/> element. The source attribute of the <img/> element is a servlet residing at an endpoint /serve. All it needs is the blob- key request parameter. We shall see this servlet in a moment.
<%@ page import="com.google.appengine.api.blobstore.BlobstoreServiceFactory"%> <%@ page import="com.google.appengine.api.blobstore.BlobstoreService" %> <html> <head>
<title>Tweet My Picture - Submission</title> </head>
<body>
<img src="tweet.png"/> <h1>Tweet My Picture</h1> <hr/>
<h3>Submission Result: <%=request.getParameter("status")%></h3> <%
String blobKey = (String)request.getParameter("blob-key"); if(blobKey != null) {%>
You uploaded : <br/>
<img width="200"height="150"src="<%="<a href="http://localhost:8888/serve?blob-
key="+blobKey">http://localhost:8888/serve?blob-key="+blobKey</a> %>"> <%}%> </body> </html>
Serve Servlet
This Servlet uses another helper function of the BlobStoreService. The method is called
serve and it takes two parameters as shown in the listing below. The blob Key and the HTTP response stream. Note that we pass it the Blob Key that we got after saving our blob. What the serve method will do is that it will automatically retrieve the Blob from the Datastore using the Blob Key that was provided to it. Once it retrieves the Blob
successfully, it will take the content of the Blob, set the correct MIME types and insert that into the HTTP Response stream. You can the use the Response stream to assign it as a source for the HTML <img/> element. We did exactly that in the submitpic.jspfile and we do the same in the viewpic.jsp file that will be invoked when someone clicks on the Twitter post. packagecom.gaejexperiments.twitter; importjava.io.IOException; importjavax.servlet.http.HttpServlet; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importcom.google.appengine.api.blobstore.BlobKey; importcom.google.appengine.api.blobstore.BlobstoreService; importcom.google.appengine.api.blobstore.BlobstoreServiceFactory; @SuppressWarnings("serial")
publicclassServe extendsHttpServlet {
privateBlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
publicvoiddoGet(HttpServletRequest req, HttpServletResponse resp) throwsIOException {
BlobKey blobKey = newBlobKey(req.getParameter("blob-key")); blobstoreService.serve(blobKey, resp);
} }
viewpic.jsp
As discussed earlier, the Tweet that we post has the following format:
Check out my picture at http://localhost:8888/viewpic.jsp?blob-key=A_BLOB_KEY This will invoke the viewpic.jsp file with a request parameter named blob-key which contains the Blob key value. So all we have to do i to create a <img/> element, whose
source attribute will be served via the /serve endpoint as shown below. Simple isn’t it ?
Episode 13: Using the Blobstore Java API 168 <%@ page import="com.google.appengine.api.blobstore.BlobstoreServiceFactory"%> <%@ page import="com.google.appengine.api.blobstore.BlobstoreService" %> <% BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
String blobKey = (String)request.getParameter("blob-key"); %>
<html> <head>
<title>Tweet My Picture - View</title> </head>
<body>
<img width="200"height="150"src="<%="<a href="http://localhost:8888/serve?blob-
key="+blobKey">http://localhost:8888/serve?blob-key="+blobKey</a> %>">
</body> </html>