Sep 14 2009

SWFUpload using jsp/struts/java

Swfupload is a great tool for uploading files to your server if you want to use a Flash uploader instead of the default HTML file uploader. It’s a small Javascript/Flash library which gives you a lot of options to customize the upload, a file progress bar being the most useful. Although a great tool, but it works best with php/asp, and not java/struts. The developers of this tool are definitely not java guys either.

Anyway, I tried implementing an swfupload upload for my struts web application, and faced a lot of problems which are outlined:

1) Swfupload won’t send the cookies (it’s a flash problem rather than swfupload’s), so my session could not be validated on the server side. I was using firefox/safari on mac. Doesn’t really matter because it was Flash who was sending the request and not the browser itself. Use firebug, and verify for yourself :)

2) “post_params” would not be sent along with the request. So any hope of capturing the form data were gone.

So I decided to solve the problem myself, and here is the solution:

For the cookies not being sent to the server, I had to send the JSESSIONID along with the URL. Simple enough, in the JSP, just send

JSESSIONID:"<%=session.getId()%>"

. But on the server side, getting a JSESSIONID is not good enough to get the session, because getSessionContext() is deprecated, and returned a null session

 request.getSession().getSessionContext().getSession
    (request.getParameter("JSESSIONID"));

So, I decided to manage these sessions myself, so that any user session could be obtained just by using the “JSESSIONID”. For this, I had to add a session listener to the webapp which actively monitors the user sessions, and stores the session in an application level hashmap. Doing this is straightforward, go to your web.xml and add the following code:

<listener>
 <listener-class>
 com.anujrathi.pc.filters.SessionListener
 </listener-class>
 </listener>

And add this class implementing HttpSessionListener:

package com.anujrathi.pc.filters;

import java.util.HashMap;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class SessionListener implements HttpSessionListener{
 Log log = LogFactory.getLog(SessionListener.class);

 public void init(ServletConfig config){
 log.info("initialed sessionlistener");
 }

 /**
 * Adds sessions to the context scoped HashMap when they begin.
 */
 public void sessionCreated(HttpSessionEvent event){
 HttpSession session = event.getSession();
 ServletContext context = session.getServletContext();
 HashMap<String, HttpSession> users =  (HashMap)context.getAttribute("users");
 users.put(session.getId(), session);
 log.info("setsession: "+session.getId());
 context.setAttribute("users", users);
 }

 /**
 * Removes sessions from the context scoped HashMap when they expire
 * or are invalidated.
 */
 public void sessionDestroyed(HttpSessionEvent event){
 HttpSession    session = event.getSession();
 ServletContext context = session.getServletContext();
 HashMap users = (HashMap)context.getAttribute("users");
 users.remove(session.getId());
 log.info("removed session: "+session.getId());
 }

}

Go to next page to view the rest of the solution:


Sep 4 2009

Photographer of the year competition

Better photography, a well known photography magazine of India organizes the “Photographer of the year” competition every year. And year after year, they have organized it successfully offline, accepting entries from the best photographers across India and abroad. This year, however they decided to take this online and canvera.com being the associate partner had to come up with a web application that would enable photographers to submit their entries through a brand new site.

Three weeks was the allotted time for the completion of the project in which the design (and its thousand iterations), development, and QA and all the tweaks would all had to be completed. And my team, i.e. Mayur (a.k.a the designer), Kanupriya (product manager) and myself (sole developer) were given the responsibility for the web application. It was definitely a roller coaster ride; new designs being discussed daily, new functional requirements and the architecture slowly but surely building up.

I had an option of choosing Ruby on Rails or php or Java EE to build this application, and for a two weeks time frame the former two would have definitely been faster. But we decided for Java, and built the entire application using jsp/struts/spring/hibernate. It’s a standard web application: A home page which briefly introduces the application, some static pages which explain the competition in the detail, a registration page (with forgot password functionality), login, user profile page, category page, theme page and upload image page. Image storage and thumbnail generation have been given a lot of importance, and is pretty scalable.

A javascript library is needed in every modern application, and although a big fan of YUI I decided on jquery this time. And I am amazed by the variety and support in jquery plugins, and slowly becoming my favorite. Although this is the first application where I hadn’t used any AJAX in the whole application, the whole experience is pretty smooth in my opinion. The image upload could have been a little smoother(and it will be, I promise :) ) with the flash uploader. Some more small features like an ajax feedback modal dialog box and editing image details might follow soon.

All in all, it was a very fulfilling experience developing the application, which is arguably the one in which the best Indian photographers, young photographers and wedding photographers will upload their best shots! I hope that the best photographers in India would find participating in the contest simple and enjoyable.


Sep 4 2009

First post!

Just owned this awesome domain name, and I’m thinking of putting up a technical blog here.
Setting up wordpress on dreamhost was a piece of cake, and so is managing domain/hosting. Highly recommended.
Anyway, I hope to update this blog at least once a week, and put up some quality technical posts in here. So stay tuned :)


Sep 4 2009

Hello world!

This is the first post on this blog, just toying around:

request.getAttribute("info");