2012-11-30 33 views
8

Tôi đã triển khai servlet hoạt động không ổn định, đôi khi nó trộn tiêu đề trong nội dung và viết hai lần.Servlet trộn tiêu đề và nội dung và viết hai lần giống nhau trong đầu ra?

và đôi khi nó đang trở lại tập tin trong đó có tiêu đề phản ứng lẫn lộn bởi nội dung như thế này:

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 

CẬP NHẬT * Tình trạng này xảy ra trên Tomcat7 *

Tôi đã thử nghiệm cũng trên Tomcat6 và Jetty, trong cả hai trường hợp không có việc tiêm HTTP-Header để phản hồi nội dung nhưng HTTP-Header sai và trả về tên tệp sai, nội dung tệp là tệp chính xác. Tôi đã nhận thấy rằng trở về sai từ servlet xảy ra khi trả về mã hóa chuyển được chia nhỏ.

Khi tôi xóa nội dung tiêu đề và phần thứ hai của byte, đó là tệp hợp lệ. Có thể đó là vấn đề đồng bộ hóa không?

CẬP NHẬT Đây là nguồn đầy đủ các servlet:

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(); 
      } 
     } 
    } 

CẬP NHẬT * Cuộc gọi đến từ ứng dụng GWT khi đang tạo URL của servlet với các thông số cần thiết và lặn ở IFrame, sau đó các cuộc gọi và tệp của servlet đang được tải xuống. Có đề xuất nào không? *

+2

Nếu bạn nghi ngờ một vấn đề đồng bộ hóa Tôi muốn giới thiệu đăng toàn bộ servlet của bạn, vì một số vấn đề đồng bộ hóa được gây ra bởi các lĩnh vực quy định tại các servlet. –

+0

@ kmb385 Tôi có nghĩa là tôi nên đồng bộ hóa một phần mã mà tôi đã đăng không? Nó là servlet rất đơn giản, viết cho mảng byte của tập tin được tạo ra trong đầu ra, và tôi đang nhầm lẫn tại sao nó chứa header trả lời… –

+0

Vì một thể hiện mới của một đáp ứng và yêu cầu được tạo ra cho mỗi servlet, tôi không thấy cần phải đồng bộ hóa khối mã này. Bạn có thể đăng html hoặc js yêu cầu servlet không. –

Trả lời

2

Tôi đã gặp sự cố tương tự từ lâu rồi. Hóa ra là việc đóng ServletOutputStream đã kích hoạt một hành vi không mong muốn trên luồng yêu cầu.

Servlets không được phép đóng vùng chứa OutputStream. Một vấn đề khác có thể được thiết lập theo cách thủ công độ dài nội dung, đó là trách nhiệm của các container sản xuất giá trị chính xác.

Để tóm tắt, hãy thử gỡ bỏ out.close()response.setContentLength()

+0

Tôi đã chỉ định response.setContentLength(), tôi sẽ cố gắng loại bỏ out.close(), sự cố xảy ra không thường xuyên và khó tái tạo, cảm ơn câu trả lời –

Các vấn đề liên quan