Reputation: 437
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
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
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