2010-11-29 110 views
3

对我的代码允许用户下载文件的任何评论。最佳做法response.getOutputStream

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) 
+0

您声明这与tapestry有关,但是在您的问题中没有提及任何tapestry。请解释这是如何挂毯相关或删除标签。 – pstanton 2010-11-29 04:04:45

+0

挂毯服务 – cometta 2010-11-29 04:06:46

回答

4

异常信息是明确的:

无法呈现异常页面:的getOutputStream()有已被调用此响应
java.lang.IllegalStateException:getOutputStream()已被调用此响应
at org.apache.catalina.connector.Response。 的getWriter(Response.java:610)

IOException是被抛出你重新抛出它作为迫使servletcontainer表明将使用getWriter()这个异常页面自定义异常。你应该让任何IOException去,因为这通常是一个不归路。

例如,当客户端中止请求时,可以在作业期间抛出IOException。最佳做法是自己对而不是捕获IOException关于Servlet API。它已经在servlet方法的throws子句中声明。

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 { 
     // ??? 
    } 
} 
3

您正在拨打response.getOutputStream()两次。相反,调用一次并将其分配给本地变量,然后使用该变量进行空检查和您的操作。

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

这不是问题的原因。您可以随意调用`getOutputStream()`和`getWriter()`多次,但** * * * * * * * * *都不是* * *。 – BalusC 2010-11-29 03:13:24

0

答案如何为空?特别是在你已经使用它之后?或者response.getOutputStream()?或fileObject,你已经测试它为非空吗?并用它?这些测试可能会造成更多的伤害。