Skip to Main Content

Java EE (Java Enterprise Edition) General Discussion

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Servlet for writing Video bytes to response

843842May 15 2009 — edited May 19 2009
Hi there,

Thanks to all who read this.

I have developed an J2EE application that allows people to watch video and can see the application using mobile devices such as the iPhone.

Videos for the iPhone are currently encoded in MP4 format and have been tested to work. When someone hits a video URL we have a Video servlet thats writes the bytes to the response. The code is given below:
private void doGetAndPost(HttpServletRequest req, HttpServletResponse resp)
{
	// Get the URL up to the ? in the location
	logger.debug("doGetAndPost(HttpServletRequest, HttpServletResponse) - BEGIN");
	String requestURI = req.getRequestURI();

	String [] parts = requestURI.split("/");

	// Our filename is always the last item in our URI
	String filename = parts[parts.length-1];

	String trueFilePath  = Manager.getProperty(Manager.CLIP_DIRECTORY_KEY )  +"/"+  filename;
	logger.debug("doGetAndPost(HttpServletRequest, HttpServletResponse) - Getting file: "  +trueFilePath );

	String userAgent = req.getHeader("User-Agent").toLowerCase();
	String mimeType = "application/x-download";
	// if the user is browsing from a Blackberry we need to forward them to
	// the mobile view of things
	// All mobile views are a concatenation of the current views plus mobile such 'done' becomes 'doneMobile'
	if( userAgent.indexOf("blackberry") != - 1 || userAgent.indexOf("iphone") != - 1)
	{
		mimeType="video/mp4";+
	}
	else
	{
	       resp.setHeader("Content-Disposition", "attachment; filename="+  filename );
	}

	try
	{
		// Set the response for our download
		File file = new File(trueFilePath);
		int fileSize = (int)file.length();
		FileInputStream fis = new FileInputStream( file );

		resp.setContentType(mimeType);


		// Set the file size of the download....
		resp.addIntHeader("Content-Length", fileSize );
		resp.flushBuffer();

		OutputStream os = resp.getOutputStream();

		//write to out output stream
		while(true)
		{
                    int bytedata = fis.read();

                    if (bytedata == -1)
                    {
                    	break;
                    }

                    os.write(bytedata);
		}

		// flush and close streams.....
		fis.close();
		os.flush();
		os.close();
	} 
	catch (FileNotFoundException e)
	{
		logger.debug("doGetAndPost(HttpServletRequest, HttpServletResponse) - Unable to find file: " + trueFilePath, e );
	}
	catch (IOException e)
	{
		logger.debug("doGetAndPost(HttpServletRequest, HttpServletResponse) - Unable to get response output stream", e );
	}

	logger.debug("doGetAndPost(HttpServletRequest, HttpServletResponse) - END");
}
This implementation is working fine for desktop browsers but when running it on a mobile device I hit a BrokenPipe SocketException.

What I have noticed is that with mobile devices the servlet gets hit twice - seemingly once as the users selects the link and then the browser decides that it doesn't know what to do with that MIME type then it initialises its own internal media player then the servlet gets hit again to try and play the video.

The broken pipe error seems to occur after the browser has decided it doesn't now how to handle the MIME type and thus any subsequent writes to the response/connection file.

Has anyone experienced anything similar? Can anyone point out where I am going wrong?

Many thanks in advance,

Jimbobegg
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Jun 16 2009
Added on May 15 2009
7 comments
2,228 views