2010-11-29 8 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); 
} 

ほとんどの場合、私は以下のエラーにはなりません。しかし、一度、しばらく、私はあなたが二回response.getOutputStream()を呼び出しているエラー

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

あなたはこれがタペストリーと関係があると述べていますが、あなたの質問ではタペストリーへの言及はありません。これがタペストリーにどのように関連しているか説明してください。 – pstanton

+0

タペストリーサービス – cometta

答えて

4

を例外メッセージは明確である。)のgetOutputStream(あり:

例外ページを提示することができません。この応答のために既に呼び出されている
java.lang.IllegalStateException:この応答に対してgetOutputStream()が既に呼び出されている
org.apache.catalina.connector.Responseの。 にgetWriter(Response.java:610)

IOExceptionがスローされた、あなたは、このためのgetWriter()を使用する例外ページを表示するservletcontainerを強制カスタム例外として、それを再スローしています。あなたは実際にはIOExceptionに行かなければなりません。なぜなら、それは通常は返されないからです。

IOExceptionは、クライアントがリクエストを中止したときにジョブ中にスローされる可能性があります。ベストプラクティスはで、ではなく、Servlet APIのIOExceptionを自分でキャッチします。これはすでにサーブレットメソッドの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

を取得します。その代わりに一度呼び出すと、それをローカル変数に代入して、その変数をヌルチェックと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

これは問題の原因ではありません。あなたは 'getOutputStream()'と 'getWriter()'をあなたが望む回数だけ呼び出すことができますが、**同じ*応答では**両方ではありません。 – BalusC

0

レスポンスはどのようにnullになりますか?特にあなたはすでにそれを使用した後に?またはresponse.getOutputStream()?またはnullでないことを既にテストした後のfileObject?それを使った?これらのテストは良いよりも害を及ぼしているかもしれません。

+1

これはコメントであって、答えではありませんでした。それはすなわち質問に答えない。 – BalusC

+0

私は同意しません。最後の文を参照してください。 – EJP