2013-08-22 18 views
3

我想實現這一點:上傳文件時檢查文件擴展名如果不是.zip,上傳將會中斷,並向用戶顯示一條消息,所以我寫了這個:當某些條件不正確時中斷文件上傳

// Implement both receiver that saves upload in a file and 
// listener for successful upload 
class ReportUploader implements Receiver, SucceededListener { 
    public File file; 

    public OutputStream receiveUpload(String filename, String mimeType) { 
     // Create upload stream 
     FileOutputStream fos = null; // Stream to write to 
     String userHome = System.getProperty("user.home"); 

     String ext = filename.substring(filename.lastIndexOf('.')); 
     System.out.println("+++++++++++>" + ext); 
     if (!ext.equals(".zip")) { 
      Notification.show("Could not upload file", Notification.TYPE_ERROR_MESSAGE); 
      return null; 
     } 
     try { 
      file = new File(userHome + "/uploads/report/" + filename); 
      fos = new FileOutputStream(file); 
     } catch (final java.io.FileNotFoundException e) { 
      Notification.show("Could not open file", e.getMessage(), Notification.TYPE_ERROR_MESSAGE); 
      return null; 
     } 
     return fos; 
    } 

    public void uploadSucceeded(SucceededEvent event) { 
     String filename; 
     String basepath; 
     String folderName; 
     String uploadDir; 

     filename = event.getFilename(); 
     basepath = VaadinService.getCurrent().getBaseDirectory().getAbsolutePath(); 
     uploadDir = Utilities.getProperty("uploadDir", basepath + "/WEB-INF/properties/config.properties"); 
     file = new File(uploadDir + filename); 
     folderName = filename.substring(0, filename.length() - 5); 

     Utilities.unZipFolder(uploadDir + filename, uploadDir + folderName); 
     addFilename(folderName); 

     try { 
      Utilities.deleteCompressedReport(file); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     Notification.show("upload finished", Notification.TYPE_HUMANIZED_MESSAGE); 
    } 

    private void addFilename(String sFilename) { 
     reportDirList.add(sFilename); 
     selectDir.addItem(sFilename); 
    } 
} 

當分機沒有名爲.zip,這個錯誤應計:

com.vaadin.server.UploadException: Upload failed 
at com.vaadin.server.communication.FileUploadHandler.streamToReceiver(FileUploadHandler.java:581) 
at com.vaadin.server.communication.FileUploadHandler.handleFileUploadValidationAndData(FileUploadHandler.java:419) 
at com.vaadin.server.communication.FileUploadHandler.doHandleSimpleMultipartFileUpload(FileUploadHandler.java:382) 
at com.vaadin.server.communication.FileUploadHandler.handleRequest(FileUploadHandler.java:267) 
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1329) 
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:236) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164) 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) 
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395) 
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250) 
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188) 
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 
at java.lang.Thread.run(Thread.java:722) 
Caused by: com.vaadin.server.NoOutputStreamException 
at com.vaadin.server.communication.FileUploadHandler.streamToReceiver(FileUploadHandler.java:518) 
... 22 more 

所以如何中斷的上傳和顯示信息?

回答

1

溶液:

實施com.vaadin.ui.Upload.StartedListener.andget其具有擴展的文件名。如果擴展名無效,請調用Upload組件上的方法interruptUpload()。

4

如您所見,您需要調用Upload的interruptUpload方法。其他一些要點:

  • 您的接收器在顯示錯誤後返回空值。我發現這導致了日誌中的堆棧跟蹤,並且如果用戶將鼠標懸停在上傳組件上,則部分堆棧跟蹤對用戶甚至是可見的。我避免的方式是返回一個NullOutputStream而不是null。

  • 如果用戶試圖在沒有首先選擇文件的情況下嘗試上載,則可能還希望在receiveUpload中防止出現異常(再次生成堆棧跟蹤)。檢查空文件名,顯示錯誤,然後返回NullOutputStream。

    下面是一個示例receiveUpload,它具有上述兩種保護。 (注:Utilities.showError只是創建平時Vaadin通知對話框,沒有什麼神奇的存在。)

    public OutputStream receiveUpload(String filename, String mimeType) { 
        if (filename != null && !filename.isEmpty()) { 
         // Create upload stream 
         FileOutputStream fos = null; // Stream to write to 
         try { 
          // Open the file for writing. 
          file = new File(FileHandler.DEST_PATH + filename); 
          fos = new FileOutputStream(file); 
          return fos; 
         } catch (final java.io.FileNotFoundException e) { 
          Utilities.showError("Could not open file<br>", e.getMessage()); 
         } 
        } else { 
         Utilities.showError("You must first select a spreadsheet file to upload."); 
        } 
        uploadControl.interruptUpload(); 
        return new NullOutputStream(); // to prevent a stack trace from being thrown by Vaadin 
    } 
    
  • 另外,你可能需要一個StartedListener爲好。這是檢查文件太大的最簡單的地方 - 你可能不想讓某人用gigabyte文件來攻擊你。這uploadStarted方法可能是這個樣子:

    public void uploadStarted(StartedEvent event) { 
        if (event.getFilename().isEmpty()) { 
         uploadControl.interruptUpload(); 
         Utilities.showError("You must first select a file to upload."); 
        } else if (event.getContentLength() > FileHandler.MAX_UPLOAD_BYTES) { 
         uploadControl.interruptUpload(); 
         Utilities.showError("File is too big. Please check that you selected the correct file."); 
        } else if (!FileHandler.isValidUploadMIMEType(event.getMIMEType())) { 
         uploadControl.interruptUpload(); 
         Utilities.showError("Unexpected file type. Please check that you selected the correct file."); 
        } else { 
         progressBar.setValue(0.0f); 
         progressBar.setVisible(true); 
        } 
    } 
    

一個缺點這種方法是,我通過避免例外避免堆棧跟蹤。這很好,但Upload組件清除了有問題的文件名。如果你拋出異常,你會看到堆棧跟蹤,但用戶可以看到他們選擇的文件,也許可以找出他們做錯了什麼。我認爲這是次要的。