代码之家  ›  专栏  ›  技术社区  ›  cometta

最佳实践响应.getOutputStream

  •  3
  • cometta  · 技术社区  · 15 年前

    关于允许用户下载文件的任何评论。

    if(fileObject !=null)
    response.setHeader("Content-disposition", "attachment; filename=\""+fileObject.getFilename()+"\"");
    response.setContentType(fileObject.getFiletype());
    response.setContentLength((int)fileObject.getFilesize().intValue());
    try {
     if(response !=null && response.getOutputStream() !=null &&fileObject!=null && fileObject.getBinData() !=null ){
        OutputStream out = response.getOutputStream();
        out.write(fileObject.getBinData());
     }
    
    
    } catch (IOException e) {
        throw new ApplicationRuntimeException(e);
    }
    

    大多数时候,我不会犯错误。但偶尔,我会犯错

    29 Nov 2010 10:50:41,925 WARN [http-2020-2] - Unable to present exception page: getOutputStream() has already been called for this response
    java.lang.IllegalStateException: getOutputStream() has already been called for this response
     at org.apache.catalina.connector.Response.getWriter(Response.java:610)
    
    4 回复  |  直到 15 年前
        1
  •  4
  •   BalusC    15 年前

    异常消息是明确的:

    无法显示异常页 :已为此响应调用getOutputStream()
    java.lang.IllegalStateException:已为此响应调用getOutputStream()
    点击org.apache.catalina.connector.Response。 获取写入程序 (回复:java:610)

    一个 IOException 已被抛出,您正在将其作为自定义异常重新引发,该异常迫使servletcontainer显示将使用的异常页 getWriter() 为了这个。事实上你应该 IOException公司 去吧,因为那通常是一个无法回头的地方。

    一个 IOException公司 例如,可以在客户端中止请求时在作业期间引发。最好的做法是 抓住 IOException公司 在ServletAPI上。已经申报了 throws servlet方法的子句。

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        FileObject fileObject = getItSomehow();
        if (fileObject != null && fileObject.getBinData() != null) {
            response.setHeader("Content-disposition", "attachment; filename=\"" + fileObject.getFilename() + "\"");
            response.setContentType(fileObject.getFiletype());
            response.setContentLength((int)fileObject.getFilesize().intValue());
            response.getOutputStream().write(fileObject.getBinData());
        } else {
            // ???
        }
    }
    
        2
  •  3
  •   highlycaffeinated    15 年前

    你在打电话 response.getOutputStream() 两次。相反,只调用一次并将其分配给一个局部变量,然后将该变量用于空检查和 write 操作。

    try {
     OutputStream out = response.getOutputStream();
     if(response !=null && out !=null &&fileObject!=null && fileObject.getBinData() !=null ){
        out.write(fileObject.getBinData());
     }
    } catch (IOException e) {
      throw new ApplicationRuntimeException(e);
    }
    
        3
  •  0
  •   user207421    15 年前

    如何使响应为空?尤其是在你已经用过之后?或者response.getOutputStream()?或者fileObject,在您已经测试过它是否为非空之后?用过了吗?这些测试可能弊大于利。

        4
  •  0
  •   doylecentral    15 年前