Daniel
Daniel

Reputation: 437

Servlet to load video file from server

I have the servlet that loads video file from server and send it as response to http get request. Here his code:

protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
{
    System.out.println("Start of doGet");

    FileSystemManager fsManager = null;
    try {
         fsManager = VFS.getManager();
    } catch (FileSystemException e) {

        e.printStackTrace();
    }


    // Get requested image by path info.
    String requestedImage = request.getPathInfo();

    // Check if file name is actually supplied to the request URI.
    if (requestedImage == null) {
        // Do your thing if the image is not supplied to the request URI.
        // Throw an exception, or send 404, or show default/warning image, or just ignore it.
        response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
        return;
    }

    FileObject basePath;

    try {

        basePath = fsManager.resolveFile( imagePath + URLDecoder.decode(requestedImage, "UTF-8"));


    } catch (FileSystemException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();

        return;
    }
    String baseName = basePath.getName().getBaseName();
    String contentType = getServletContext().getMimeType(baseName);
      // Init servlet response.
    response.reset();
    response.setBufferSize(DEFAULT_BUFFER_SIZE);
    response.setContentType(contentType);
    response.setHeader("Content-Length", String.valueOf(basePath.getContent().getSize()));


    // Prepare streams.
    BufferedInputStream input = null;
    BufferedOutputStream output = null;

    int count = 0;
    try {
        // Open streams.
        FileContent fc = basePath.getContent(); 
        InputStream is = (InputStream) fc.getInputStream(); 
        input = new  BufferedInputStream(is, DEFAULT_BUFFER_SIZE);
        output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);

        // Write file contents to response.
        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
        int length;
        while ((length = input.read(buffer)) > 0) {
            output.write(buffer, 0, length);
            count++;
        }
        System.out.println("no exception occurred");

    }
    catch(Exception e){
        System.out.println("while did " + count + " iterations befor exception occurred");
        System.out.println("Catched exception: " + e);
    }
    finally{    
        // Gently close streams.
        System.out.println("closing streams");
         close(input);
         close(output);

    }
}

When i start in google chrome for example http://localhost:8080/MyApp/video/VX-276.ogg I get this output:

Start of doGet

while did 3 iterations befor exception occurred

Catched exception: ClientAbortException: java.net.SocketException: Connection reset by peer: socket write error

closing streams

Start of doGet

while did 4 iterations befor exception occurred

Catched exception: ClientAbortException: java.net.SocketException: Software caused connection abort: socket write error

closing streams

Start of doGet

Start of doGet

while did 224 iterations befor exception occurred

Catched exception: ClientAbortException: java.net.SocketException: Connection reset by peer: socket write error

closing streams

while did 4 iterations befor exception occurred

Catched exception: ClientAbortException: java.net.SocketException: Software caused connection abort: socket write error

closing streams

Start of doGet

while did 12 iterations befor exception occurred

Catched exception: ClientAbortException: java.net.SocketException: Software caused connection abort: socket write error

closing streams

How do i repair my code ?

Upvotes: 1

Views: 3327

Answers (2)

Thilip
Thilip

Reputation: 11

No one ever think about cache issue on the browser.

use this line of code in the beginning of your servlet.

response.addHeader("Cache-Control", "no-transform, max-age=0");

Upvotes: 1

BalusC
BalusC

Reputation: 1108712

ClientAbortException: java.net.SocketException: Connection reset by peer: socket write error

The webbrowser has aborted the connection. Presumably because the enduser pressed esc, or stopped the video, or navigated away to other page, or has shutdown the webbrowser. Or it is after all the webbrowser itself who decided to behave like that for some reason.

There's nothing you can do against this from the server side on. I wouldn't log them anyway.

To minimize the wasted network bandwidth, I'd however strongly recommend to add support for byte range requests (read: download resumes). You can find a basic example here. You could also just delegate the whole job to servletcontainer's builtin default servlet which should already support this. You can do that by mapping the folder with videos as another webapp context. See also this answer.

Upvotes: 1

Related Questions