Ajax Upload tweaked for grails

While coding a little on gibbon’s five we stumbled upon a nice JavaScript library called file uploader. The first tests we did looked good so we took it into the project. While checking the browser compability I ran into some problems with the Internet Explorer that need to be fixed.

First of all, the return type for the IE has to be a little different – the IE needs text/plain. Also, the data send from the IE to the server looks a little different from the one WebKit and gecko: It’s a CommonsMultipartFile. Therefore I had to do some tweaking on the server side which ended in some code pretty similar to this:

if (params.qqfile instanceof org.springframework.web.multipart.commons.CommonsMultipartFile){
    returnType = 'text/plain'
    content = params.qqfile.getInputStream()
    originalFilename = params.qqfile.originalFilename
    mimeType = params.qqfile.getContentType()
} else {
    returnType = 'application/json'
    content = request.inputStream
    originalFilename = params.qqfile
    mimeType = URLConnection.guessContentTypeFromName(params.qqfile)
}

Furthermore, the plugin has to deal with older browsers and the IE by using iframes (mentioned on the website and explained in the code). This works pretty well until you come across grails, which, for whatever reason, sends pre-tags around the json code. Of course our friend the Internet Explorer is confused and is simply not evaluating the answer. A simple solution to this is to change a few lines of code in the function (fileuploader.js):

_getIframeContentJSON:function (iframe) {
    // iframe.contentWindow.document - for IE<7
    var doc = iframe.contentDocument ? iframe.contentDocument : iframe.contentWindow.document, response;

    this.log("converting iframe's innerHTML to JSON");
    this.log("innerHTML = " + doc.body.innerHTML);

    // Grails is answering with pre-tags. That might confuse the browser script therefore we better remove them.
    var cleanedAnswer = doc.body.innerHTML.replace(/<(\/)*pre>/g, '');
    this.log("grails cleaned: " + cleanedAnswer);

    try {
        response = eval("(" + cleanedAnswer + ")");
    } catch (err) {
        response = {};
    }

    return response;
}

Overall it’s a simple tweak and now it works perfectly within all the browsers we tried :)

Code snippet: json object as http-put request

This is a pretty short function to send a json-object as a http-put request to a given url. I was looking for something like that for a while but most solutions I found are working with streams, so you also have to handle them. This one is pretty straight forward though ;)

public static boolean putJSON(String url, JSONObject json) {
	HttpClient httpClient = new DefaultHttpClient();
	HttpPut putMethod = new HttpPut(url);
	HttpEntity data;
	
	try {
		data = new StringEntity(json.toString());
		putMethod.setEntity(data);
		httpClient.execute(putMethod);
	} catch (Exception e) {
		if(DEBUG)
			Log.e(LOGGER, "Exception while sending data: " + e.getMessage());
		return false;
	} finally {
		putMethod.abort();
	}
	return true;
}