Oops Null Pointer

Java programming related

Category Archives: Browsers

Debugging Javascript in IE6

Quick note here on debugging Javascript in IE6 as I found a few handy tips

  • Use firebug lite – my IE fails if you call firebug twice, so load up you page and then click the bookmarklet
    • My IE6 crashes on the firebug lite page so I use another browser to get the bookmarklet code
  • Using firebug lite you can use console.log(‘a msg’) to log to the console
  • Use .toString() on a function when you want to see the function’s code
  • If you can, get the pretty / uncompressed version of the js lib you are debugging (for me it was Highcharts)

Sending PDF files in the response

To send PDF files so that most browsers will display them I’ve found the following headers work:

  • Content-Disposition: inline; filename=sample.pdf or Content-Disposition: attachment; filename=sample.pdf
  • Expires: 0
  • Cache-Control: must-revalidate, post-check=0, pre-check=0
  • Pragma: public
  • Content-Type: application/pdf
  • Content-Length: <number of bytes>

Here is some rough Java to stream an input stream to the HttpServletResponse.

public static void streamInputToResponse(HttpServletResponse resp, boolean isInline, String contentType, String filename,
		InputStream in, int length) throws IOException {
	ServletOutputStream outstr = null;
	
	try {
		if (length > Integer.MAX_VALUE) {
			throw new IOException("File to large to stream");
		}
		
		outstr = resp.getOutputStream();
		
		// Setting required headers
		resp.setContentLength(length);
		resp.setContentType(contentType);
		String inlineOrAttachment = isInline ? "inline;" : "attachment;";
		resp.setHeader("Content-Disposition", inlineOrAttachment + " filename=" + filename);
		
		// setting some extra response headers to sooth browser issues
		resp.setHeader("Expires", "0");
		resp.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
		resp.setHeader("Pragma", "public");

		IOUtils.copy(in, outstr);
		outstr.flush();
	}
	catch (IOException e) {
		String errorStr = "Error Streaming data to servlet output stream" + ": " + e.getMessage();

		try {
			if (outstr != null) {
				outstr.print(errorStr);
				outstr.flush();
			}
		}
		catch (IOException e1) {
			logger.warn("Error flushing servlet output stream: " + e1.getMessage());
		}
		
		throw e;
	}
	finally {
		IOUtils.closeQuietly(in);
		IOUtils.closeQuietly(outstr);
	}
}

Update:
The Restlet framework has some issues with PDFs when used in JBoss / Tomcat. Tomcat is appending a charset=UTF8 that appears to stop chrome’s built in PDF reader from loading (Chrome 11). Not setting the content length appeared to help while surprisingly not breaking IE.
Also with JBoss and authentication a no-cache header is added and the Restlet framework doesn’t remove it (even if you add your own Cache-Control header). See here for a way to disable this behaviour.

Chrome returning null content type on file upload

Chrome (up to at least 8.0.552.215) has issues with content types of files. For me it was if the file did not have an extension.

See here for the old (unfixed issue) and here for the new issue.

Note: I’m using struts 2.0.14 with the FileUploadInterceptor (uses ServletFileUpload and JakataMultipartRequest) and if I upload a file without an extension then struts throws a null pointer exception. If I take the same file and add any extension (e.g. .bin) then it will upload correctly.

Looking at the code for struts 2.2.1 or the current trunk (line 275) it still looks like this is a problem.

Firefox defaults to “application/octet-stream” which, in this case, works.

Anyone else had this issue or has a workaround? Maybe allow the setting of a default content type in the FileUploadInterceptor?

Update: This appears to be fixed in the code base – waiting for word on when it will get into a release.