2014-10-17 77 views
1

我想写一个位于Linux服务器上的java servlet,它可以被客户端用来下载视频文件。它适用于文件大小很小(可能小于2 MB)的情况,但较大的文件大小会返回错误:org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe为什么Java servlet在文件大小大于2 MB时给ClientAbortException?

搜索Google后,当客户端断开连接时出现此错误。在我的情况下,我使用客户端,并且可以确认我没有做任何会破坏连接的事情(至少不是故意的) - 当发生此错误时,浏览器保持打开状态等。

任何想法可能会导致此(以及如何解决)?

public class GetFile extends HttpServlet { 

@Override 
public void init(ServletConfig config) throws ServletException { 
    super.init(config); 
} 

protected void doPost(HttpServletRequest req, HttpServletResponse res) 
    throws ServletException, IOException { 

String filename ="init_java"; 

try { 

    // get user parameters 
    filename = req.getParameter("fileId"); // complete path to video file 
    //res.setContentType("video/mp4"); //not working 
    res.setContentType("application/x-download"); 

    File file=new File(filename); 

    if (file.exists()) { 

     res.setHeader("Content-Disposition", "inline; filename=\""+filename+"\""); 
     res.setHeader("Cache-Control", "cache, must-revalidate"); 
     //res.setHeader("Pragma", "public"); // not sure when to use 
     returnFile(filename, res.getOutputStream()); 

    } else { 
     //error handling goes here 
    }  

} catch (Exception e) { 
    ... 
} finally { 
    ... 
} 
} 


private static void returnFile(String filename, OutputStream out) throws FileNotFoundException, IOException { 
    InputStream in = null; 
    try { 
     in = new BufferedInputStream(new FileInputStream(filename)); 
     byte[] buf = new byte[4 * 1024]; // 4K buffer 
     int bytesRead; 
     while ((bytesRead = in.read(buf)) != -1) { 
      out.write(buf, 0, bytesRead); 
     } 

    } finally { 
     if (in != null) in.close(); 
    } 
} 

} 

UPDATE 1

我看到在mod_jk.log文件以下错误(其从Apache Web服务器以GlassFish应用服务器的请求传送):

[info] init_jk::mod_jk.c (3383): mod_jk/1.2.40 initialized 
[error] ajp_connection_tcp_get_message::jk_ajp_common.c (1313): wrong message format 0xcad5 from ::1:8009 
[error] ajp_get_reply::jk_ajp_common.c (2204): (worker1) Tomcat is down or network problems. Part of the response has already been sent to the client 
[info] ajp_service::jk_ajp_common.c (2673): (worker1) sending request to tomcat failed (recoverable), because of protocol error (attempt=1) 
[info] ajp_process_callback::jk_ajp_common.c (2000): Writing to client aborted or client network problems 
[info] ajp_service::jk_ajp_common.c (2673): (worker1) sending request to tomcat failed (unrecoverable), because of client write error (attempt=2) 
[info] jk_handler::mod_jk.c (2799): Aborting connection for worker=worker1 

它似乎跟踪了我所观察到的,但我不是这里的专家 - 这是否提供了对可能是什么根源的任何洞察?

+0

尝试'.flush()'一切后,输出流已被写入其中。 – 2014-10-17 18:20:12

+0

谢谢@FabianBarney,我在'returnFile()'中的while循环后面添加了'out.flush();'但它没有什么区别。 – user46688 2014-10-17 18:54:01

+0

这可能是一个基础设施问题 - 例如防火墙/路由器会丢弃某种类型和持续时间的连接。 – 2014-10-17 19:17:35

回答

1

这可能是由于您在服务器上设置了一个限制。检查属性文件。我确信有一个说没有大于2MB的文件。

+0

谢谢@andreipuf,你可以更具体的术语“服务器”?例如,你的意思是Apache Web服务器,还是别的?在.htaccess文件等文件大小可以增加? – user46688 2014-10-17 18:21:15

+0

对于Apache文件是php.ini。对于tomcat我知道输入/输出缓冲区被设置为2048字节。你可以在web.xml文件中看到。我不确定是否可以像Apache一样为tomcat全局增加它。 – 2014-10-17 18:46:29

+0

感谢@andreipuf,我没有使用PHP,所以我想这个文件不适用于这里。我正在使用GlassFish,并且会检查是否设置了任何限制。谢谢 – user46688 2014-10-17 18:57:20