2012-11-30 48 views
8

安定して動作しないサーブレットを実装しました。時には、ヘッダーをコンテンツに混ぜて同じものを2回書くこともあります。私も上のテストしているサーブレットはヘッダーとコンテンツをミックスし、同じ出力を同じ出力に書き込みますか?

Server: Apache-Coyote/1.1 
: W/"43-1353687036000" 
DatCCoonntenntt--DDiissppoosittiioonn: : atatatacehnmte;n tf;i lfenlaemnea=m20=12201112211127325421_4W1_Wirnkgi_nSgc_Seern.xnlsx 
sx 
Content-Typ-eT: ype: applaipcatciaoti/on/toctestt-rstare 
am 
ConCtoententy-pTeype: appalicatcion/oon/octet-setarm 
m 
CCoonntent-Lnegtht h: 4199 

Date: te: FriF,r i2,3 2No vNo2v0 120162: 215:25 :G4M2T 
.... 
File content bytes ... 

And again same header and content 

UPDATE * この状況はTomcat7に起こる*

、時にはそれがこのようなコンテンツによって混合レスポンスヘッダを含むファイルを返しますTomcat6とJettyの両方の場合、応答内容にHTTPヘッダーは挿入されませんが、HTTPヘッダーは間違っていて、間違ったファイル名を返します。ファイルの内容は正しいファイルです。 戻り転送コードがチャンクされたときにサーブレットから間違ったリターンが発生したことに気付きました。

私はヘッダの内容とバイトの第2部分を削除するとき、それは有効なファイルです。 同期に問題はありますか?ここでUPDATE

は、サーブレットの完全なソースです:

public class ExcelDownloadServlet extends HttpServlet 
{ 
    private static final long serialVersionUID = 1L; 
    private static final Logger LOG = Logger 
      .getLogger (ExcelDownloadServlet.class); 


    @Override 
    protected void doGet (HttpServletRequest request, 
      HttpServletResponse response) throws ServletException, IOException 
    { 
     try 
     { 
      TransactionId transactionId = getTransactionId (request); 
      String fileName = 
        request.getParameter (GlobalConstants.EXCEL_FILE); 
      ExcelDownloadType downloadType = 
        ExcelDownloadType 
          .valueOf (request 
            .getParameter (GlobalConstants.EXCEL_DOWNLOAD_TYPE)); 
      ActionContextFactory actionContextFactory = 
        ApplicationContext.getContext() 
          .getActionContextFactory(); 
      //suppress warning. HttpServletRequest.getLocales does not support generics 
      @SuppressWarnings("unchecked") 
      ActionContext actionContext = 
        actionContextFactory.create (request.getSession() 
          .getId(), Collections.<Locale> list (request 
          .getLocales())); 
      GetExcelDataResponse dataResponse = 
        new GetExcelData (transactionId, fileName, downloadType) 
          .execute (actionContext); 
      writeToResponse (response, dataResponse.getFileName(), 
        dataResponse.getData()); 
     } 
     catch (InvalidSessionException e) 
     { 
      LOG.error ("Invalid session in Excel download", e); 
      throw new ServletException (e); 
     } 
     catch (ActionException e) 
     { 
      LOG.error ("Could not download into excel.", e); 
      throw new ServletException (e); 
     } 
    } 

    protected TransactionId getTransactionId (HttpServletRequest request) 
    { 
     return RequestParameterDeserializer.<TransactionId> deserialize (
       request, GlobalConstants.TRANSACTION_ID); 
    } 

    protected void writeToResponse (HttpServletResponse response, 
      String rawFileName, byte[] data) throws IOException 
    { 
     ServletOutputStream sout = null; 
     try 
     {    
      response.setContentType ("application/octet-stream"); 
      response.setContentLength (data.length); 
      // removing blanks from the file name, since FF cuts file names 
      // otherwise. 
      String fileNameWithTime = rawFileName.replaceAll (" ", "_"); 
      response.setHeader ("Content-Disposition", "attachment; filename=" 
        + fileNameWithTime); 
      sout = response.getOutputStream(); 
      sout.write (data, 0, data.length); 
     } 
     finally 
     { 
      if (sout != null) 
      { 
       sout.close(); 
      } 
     } 
    } 

UPDATE * そして、iframe内に必要なパラメータとセットでサーブレットのURLを生成しているとき、呼び出しはGWTアプリケーションから来ていますサーブレット呼び出しとファイルがダウンロードされています。提案はありますか? *

+2

を削除してみてください、要約します。 –

+0

@ kmb385私が投稿したコードの部分を同期させるべきですか?出力に生成されたファイルのバイト配列を出力するのは非常に単純なサーブレットです。なぜレスポンスヘッダなどが含まれているのか混乱しています。 –

+0

レスポンスとリクエストの新しいインスタンスがサーブレットごとに作成されるため、このコードブロックを同期させます。サーブレットをリクエストするhtmlまたはjsを投稿できますか? –

答えて

2

私はずっと前に同様の問題がありました。 ServletOutputStreamを閉じると、リクエストフローで予期しない動作が発生したことが判明しました。

サーブレットは、提供されたコンテナを閉じるために用意されていません。 もう1つの問題は、手動でコンテンツの長さを設定することです。正しい値を生成するのはコンテナの責任です。

あなたが同期の問題が疑われる場合は、いくつかの同期の問題は、サーブレットで定義されたフィールドによって引き起こされているので、私は、あなたの全体のサーブレットを投稿推薦out.close()response.setContentLength()

+0

私はresponse.setContentLength()を指定しました。私はout.close()を削除しようとしますが、問題はまれに発生し、再現するのが難しいです。 –

関連する問題