当前位置: 首页 > 知识库问答 >
问题:

如何在servlet中处理多文档打开请求火灾

孔甫
2023-03-14

我正在使用servlet,它用于打开文档,如doc、txt、pdf、ppt等。。

我的代码片段如下。

Documents document = db.getDocument(docCode);
 String contentType = document.getDocMimeType();
 byte[] docContentBytes = document.getDocContentBytes();  

 ServletOutputStream out = response.getOutputStream ();
 response.setHeader("X-UA-Compatible", "IE=8");
 response.setHeader("Content-disposition", "attachment;filename=\"Document\""); 
 response.setHeader("Pragma","private");
 response.setHeader("Cache-Control","must-revalidate, post-check=0, pre-check=0");
 response.setHeader("Content-Transfer-Encoding","binary");

 if(contentType!=null){
     response.setContentType(contentType);
 }else{
     response.setContentType("application/pdf");
 }

 BufferedInputStream bis = null;
 BufferedOutputStream bos = null;
 ByteArrayInputStream bais = null;

 if(docContentBytes != null) {
  try{
         bais = new ByteArrayInputStream(docContentBytes);
         bis = new BufferedInputStream(bais);


         bos = new BufferedOutputStream(out);
         byte[] buff = new byte[2048];
         int bytesRead;
         // Simple read/write loop.
         while(-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
         bos.write(buff, 0, bytesRead);
         }
 }catch(final MalformedURLException e) {
 System.out.println ( "MalformedURLException." );
 throw e;
 } catch(final IOException e) {
 System.out.println ( "IOException." );
 throw e;
 } finally {
     if (bais != null)
         bais.close();

         if (bis != null)
             bis.close();

         if (bos != null)
             bos.close();
 }
 } 

现在,当我试图打开多个文档时,过了一段时间,我会从tomcat服务器上收到断管错误。

我的数据源实现如下。

<Resource name="jdbc/TEST_DS"
                        auth="Container"
                        type="javax.sql.DataSource"
                        driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
                        url="jdbc:sqlserver://hostName;databaseName=TEST"
                        username="test"
                        password="testPwd"
                        maxPoolSize="50" 
                removeAbandoned="true"
                        removeAbandonedTimeout="1000"
                        logAbandoned="true"
                        />

任何人都可以建议我需要在这个代码中修改什么?

共有3个答案

白飞飙
2023-03-14

您不应该关闭响应的输出流。我不确定这是否会导致管道错误,但我肯定会尝试一下。

Documents document = db.getDocument(docCode);
String contentType = document.getDocMimeType();
byte[] docContentBytes = document.getDocContentBytes();

ServletOutputStream out = response.getOutputStream();
response.setHeader("X-UA-Compatible", "IE=8");
response.setHeader("Content-disposition", "attachment;filename=\"Document\"");
response.setHeader("Pragma", "private");
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
response.setHeader("Content-Transfer-Encoding", "binary");

if (contentType != null) {
    response.setContentType(contentType);
} else {
    response.setContentType("application/pdf");
}


if (docContentBytes != null) {
    try {
        ByteArrayInputStream bais = new ByteArrayInputStream(docContentBytes);

        byte[] buff = new byte[2048];

        int bytesRead;
        while (-1 != (bytesRead = bais.read(buff))) {
            out.write(buff, 0, bytesRead);
        }
    } finally {
        out.flush();
    }
}

以下是其他一些建议:

>

  • 缓冲字节数组inputstream没有意义;你的内存中已经有数据了

    关闭缓冲流也会关闭底层流

    关闭字节数组流没有任何作用

    缓冲响应的输出流没有意义,因为您已经在代码中使用了缓冲机制

    在处理流/文件(例如IOUtils)时,第三方库(例如colon-io)非常有用

    发布异常堆栈的(一部分)跟踪您是否发布了有关异常的问题

  • 单于正业
    2023-03-14

    出现该错误有几个原因:

    • 当服务器试图通信时,网络会下降。
    • 用户取消请求。
    • 数据库关闭或拒绝连接。

    您需要做的是按以下顺序关闭:

    finally {
          if(bos != null)
             bos.close();
          if(bis != null)
             bis.close();
          if(bais != null)
             bais.close();
    }
    

    希望这能有所帮助!

    牛景同
    2023-03-14

    从这里的答案来看,似乎关闭的顺序可能是问题的根源。

    改变这个代码...

    finally {
         if (bais != null)
             bais.close();
    
             if (bis != null)
                 bis.close();
    
             if (bos != null)
                 bos.close();
     }
    

    到…

    finally {
             bais.close();
             bos.close();
             bis.close();
     }
    
     类似资料:
    • 问题内容: 我在用Java应用程序服务器处理multipart / form-data请求时非常困难。从我发现的情况来看,servlet 3.0规范提供了诸如HttpServletRequest.getParts()之类的方法,这对于处理上传到我的servlet的表单数据是理想的。 但是,此方法是3.0 Servlet规范的一部分,并且我的应用程序服务器(Tomcat 6)尚不支持此方法。即使具有

    • 问题内容: 有人可以解释什么是每个请求线程和每个连接线程吗?servlet使用哪种模型?如何分配线程来处理HTTP请求?是线程/请求还是连接? 假设我要在自己的方法中异步执行耗时的任务,那么我将使用Java执行程序启动一个新线程,以便在单独的线程中进行冗长的计算并立即发送响应。 现在,这是否可以确保我释放了正在处理我的线程,或者由于子线程仍在运行而仍在使用它? 问题答案: 每个请求意味着在发出HT

    • 问题内容: 我的Flask应用程序必须进行大量计算才能获取特定页面。在Flask执行该功能时,其他用户无法访问该网站,因为Flask忙于进行大量计算。 有什么方法可以使我的Flask应用程序接受来自多个用户的请求? 问题答案: 是的,将应用程序部署在其他WSGI服务器上,请参阅Flask部署选项文档。 Flask随附的服务器组件实际上仅用于开发应用程序时;即使可以将其配置为处理并发请求(从Flas

    • 表模式如下: 表A的主键[ID1(分区键)id2(分区键)id3(群集键)] 表B主键[ID1(分区键)id2(分区键)状态(聚类键)id3(聚类键)] 那么在卡桑德拉我该怎么解决呢?

    • 假设我有一个Employee类。它有很多字段,比如id、名字、姓氏、姓名、年龄、薪水和其他字段。现在,我正在进行一个Get查询,希望使用所有这些字段(required=false)作为请求参数传递。 但问题是,可能有许多组合,如(firstName, age)或(age,工资,lastName)或(指定,年龄,工资,lastName)等等。那么我应该如何处理所有这些筛选器。我必须为每个案例编写每个

    • 问题内容: 单个Servlet如何处理以用户请求形式出现的多个客户端请求?基于单例设计模式,我知道我们创建了一个servlet实例,但是单个servlet如何处理数百万个请求。对其所涉及的线程也感到困惑。 同样,这里提供了任何浏览器规范或设置,可用于跨请求发送请求或生成针对请求发送的线程。 所有框架都相同还是不同(例如,struts v / s springs)? 问题答案: Struts / S