2016-04-08 7 views
1

Ich benutze eine JSF 2.2 und eine Primefaces 5.3. Ich möchte eine hochgeladene Datei auf einer Festplatte speichern. Unten kannst du sehen, wie ich das versuche. Wenn ich einen Send Knopf drücken erhalte ich eine java.nio.file.NoSuchFileException Ausnahme (am Ende meines Posts Ich habe auch eine vollständige Stacktrace):uploadFile.getInputstream() löst java.nio.file.NoSuchFileException

ERROR [Stderr] (Default-Task-24) java.nio.file.NoSuchFileException: [PATH] \ Wildfly_10 \ WILDFLY_HOME \ Standalone \ tmp \ MasterProject.war \ undertow1357918758070690245upload

Wenn ich den Stacktrace verfolgen, wie ich sehe, dass die Ausnahme von dieser Linie verursacht wird (ich glaube so):

try(InputStream input = uploadFile.getInputstream()){

Es ist seltsam für mich. Ich kann den Namen der hochgeladenen Datei (von uploadFile.getFileName()) bekommen, aber ich kann die Größe der Datei nicht bekommen (von uploadFile.getSize()) und ich kann nicht die InputStream (von uploadFile.getInputstream()) bekommen. In beiden Fällen bekomme ich die Ausnahme NoSuchFileException.

Zusätzliche Informationen: Ich muss die großen Dateien hochladen (d. H. 200 MB oder mehr). Natürlich bekomme ich die selbe Ausnahme, wenn ich die kleine Datei hochlade.

Haben Sie eine Idee, warum habe ich diese Ausnahme und wie kann ich dieses Problem beheben?

Dies ist ein Teil der Seite, wo ich die Datei hochladen:

<h:form> 
    <p:growl id="messages" showDetail="true" /> 
    <p:panelGrid id="panel" columns="2" styleClass="ui-noborder" columnClasses="rightalign,leftalign"> 

     <p:outputLabel for="file" value="File:" /> 
     <p:fileUpload id="file" fileLimit="1" 
        fileUploadListener="#{dataController.handleFileUpload}" 
        mode="advanced" dragDropSupport="true" sizeLimit="1000000000" 
        uploadLabel="Upload" cancelLabel="Delete" allowTypes="/(\.|\/)(csv|binetflow)$/" />            
     <p:commandButton id="buttonSend" value="Send" 
         action="#{dataController.send()}" update="messages"/>      

    </p:panelGrid>            
</h:form> 

Dies ist der CDI-Bean, die die Steuerung für die oben genannte Seite lautet:

@Named 
@ViewScoped 
public class DataController implements Serializable { 

    private static final long serialVersionUID = 1383572529241805730L; 

    public void handleFileUpload(FileUploadEvent event){ 

     uploadFile=event.getFile(); 

     FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Successful", event.getFile().getFileName() + " is uploaded")); 
    } 

    public void send(){ 

     try(InputStream input = uploadFile.getInputstream()){ 

      Path folder=Paths.get("F:/Files"); 
      String filename = FilenameUtils.getBaseName(uploadFile.getFileName()); 
      String extension = FilenameUtils.getExtension(uploadFile.getFileName()); 
      Path file = Files.createTempFile(folder, filename + "-", "." + extension); 
      Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING); 

      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Successful", "Uploaded file successfully saved in " + file));   

     } catch (IOException e1) { 
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", null)); 
      e1.printStackTrace(); 
     } 
    } 

    private UploadedFile uploadFile; 
} 

Dies ist die volle Stacktrace:

10:40:45,822 ERROR [stderr] (default task-24) java.nio.file.NoSuchFileException: [PATH]\Wildfly_10\WILDFLY_HOME\standalone\tmp\MasterProject.war\undertow1357918758070690245upload 

10:40:45,823 ERROR [stderr] (default task-24) at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79) 

10:40:45,823 ERROR [stderr] (default task-24) at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97) 

10:40:45,823 ERROR [stderr] (default task-24) at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102) 

10:40:45,823 ERROR [stderr] (default task-24) at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230) 

10:40:45,823 ERROR [stderr] (default task-24) at java.nio.file.Files.newByteChannel(Files.java:361) 

10:40:45,824 ERROR [stderr] (default task-24) at java.nio.file.Files.newByteChannel(Files.java:407) 

10:40:45,824 ERROR [stderr] (default task-24) at java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:384) 

10:40:45,824 ERROR [stderr] (default task-24) at java.nio.file.Files.newInputStream(Files.java:152) 

10:40:45,824 ERROR [stderr] (default task-24) at io.undertow.servlet.spec.PartImpl.getInputStream(PartImpl.java:63) 

10:40:45,824 ERROR [stderr] (default task-24) at org.primefaces.model.NativeUploadedFile.getInputstream(NativeUploadedFile.java:45) 

10:40:45,824 ERROR [stderr] (default task-24) at com.system.controller.DataController.send(DataController.java:163) 

10:40:45,824 ERROR [stderr] (default task-24) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 

10:40:45,825 ERROR [stderr] (default task-24) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 

10:40:45,825 ERROR [stderr] (default task-24) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 

10:40:45,825 ERROR [stderr] (default task-24) at java.lang.reflect.Method.invoke(Method.java:498) 

10:40:45,825 ERROR [stderr] (default task-24) at javax.el.ELUtil.invokeMethod(ELUtil.java:308) 

10:40:45,825 ERROR [stderr] (default task-24) at javax.el.BeanELResolver.invoke(BeanELResolver.java:415) 

10:40:45,825 ERROR [stderr] (default task-24) at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:256) 

10:40:45,825 ERROR [stderr] (default task-24) at com.sun.el.parser.AstValue.invoke(AstValue.java:285) 

10:40:45,825 ERROR [stderr] (default task-24) at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304) 

10:40:45,826 ERROR [stderr] (default task-24) at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40) 

10:40:45,826 ERROR [stderr] (default task-24) at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50) 

10:40:45,826 ERROR [stderr] (default task-24) at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40) 

10:40:45,826 ERROR [stderr] (default task-24) at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50) 

10:40:45,826 ERROR [stderr] (default task-24) at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) 

10:40:45,826 ERROR [stderr] (default task-24) at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87) 

10:40:45,826 ERROR [stderr] (default task-24) at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) 

10:40:45,827 ERROR [stderr] (default task-24) at javax.faces.component.UICommand.broadcast(UICommand.java:315) 

10:40:45,827 ERROR [stderr] (default task-24) at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790) 

10:40:45,827 ERROR [stderr] (default task-24) at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282) 

10:40:45,827 ERROR [stderr] (default task-24) at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) 

10:40:45,827 ERROR [stderr] (default task-24) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 

10:40:45,827 ERROR [stderr] (default task-24) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198) 

10:40:45,828 ERROR [stderr] (default task-24) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658) 

10:40:45,828 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) 

10:40:45,828 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) 

10:40:45,828 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) 

10:40:45,829 ERROR [stderr] (default task-24) at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78) 

10:40:45,829 ERROR [stderr] (default task-24) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 

10:40:45,829 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) 

10:40:45,829 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) 

10:40:45,829 ERROR [stderr] (default task-24) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 

10:40:45,830 ERROR [stderr] (default task-24) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) 

10:40:45,830 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) 

10:40:45,830 ERROR [stderr] (default task-24) at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) 

10:40:45,830 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) 

10:40:45,831 ERROR [stderr] (default task-24) at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50) 

10:40:45,831 ERROR [stderr] (default task-24) at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) 

10:40:45,831 ERROR [stderr] (default task-24) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 

10:40:45,831 ERROR [stderr] (default task-24) at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) 

10:40:45,831 ERROR [stderr] (default task-24) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 

10:40:45,832 ERROR [stderr] (default task-24) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 

10:40:45,832 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:284) 

10:40:45,832 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:263) 

10:40:45,832 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) 

10:40:45,833 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:174) 

10:40:45,833 ERROR [stderr] (default task-24) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202) 

10:40:45,833 ERROR [stderr] (default task-24) at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:793) 

10:40:45,833 ERROR [stderr] (default task-24) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 

10:40:45,833 ERROR [stderr] (default task-24) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 

10:40:45,834 ERROR [stderr] (default task-24) at java.lang.Thread.run(Thread.java:745) 

Aktualisierung:

Mir ist etwas neues aufgefallen. Wenn ich den Inhalt des send() Verfahrens zum handleFileUpload() Verfahren (der Code unten) bewegen - die Datei auf der Festplatte gespeichert:

@Named 
@ViewScoped 
public class DataController implements Serializable { 

    private static final long serialVersionUID = 1383572529241805730L; 

    public void handleFileUpload(FileUploadEvent event){ 

     uploadFile=event.getFile(); 

     try(InputStream input = uploadFile.getInputstream()){ 

      Path folder=Paths.get("F:/Files"); 
      String filename = FilenameUtils.getBaseName(uploadFile.getFileName()); 
      String extension = FilenameUtils.getExtension(uploadFile.getFileName()); 
      Path file = Files.createTempFile(folder, filename + "-", "." + extension); 
      Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING); 

      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Successful", "Uploaded file successfully saved in " + file));   

     } catch (IOException e1) { 
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", null)); 
      e1.printStackTrace(); 
     } 

     FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Successful", event.getFile().getFileName() + " is uploaded")); 
    } 

    public void send(){ 

    } 

    private UploadedFile uploadFile; 
} 

Aber ich mag die hochgeladene Datei auf der Festplatte speichern, wenn der Benutzer Drücken Sie die Send Taste, nicht früher (dh nicht, wenn der Benutzer die Upload Taste drücken), so ist es notwendig, die Datei in send() Methode zu speichern.

Ich bemerkte auch, dass, wenn ich einen einfachen Modus der <p:fileUpload> Komponente (das modifizierte Formular unten) verwenden, alles funktioniert (d. H. Die Datei wird gespeichert, wenn der Benutzer die Taste drücken). Ich musste Getter und Setter für das uploadFile Objekt in der DataController Bean erstellen, um #{dataController.uploadFile} zu verwenden. Ich musste das enctype="multipart/form-data" Attribut zur <h:form> Komponente entweder hinzufügen (ohne dieses Attribut ist es nicht Arbeit).

<h:form enctype="multipart/form-data"> 
    <p:growl id="messages" showDetail="true" /> 
    <p:panelGrid id="panel" columns="2" styleClass="ui-noborder" columnClasses="rightalign,leftalign"> 

     <p:outputLabel for="file" value="File:" /> 
     <p:fileUpload id="file" value="#{dataController.uploadFile}" mode="simple" skinSimple="true" sizeLimit="1000000000" allowTypes="/(\.|\/)(csv|binetflow)$/"/> 
     <p:commandButton value="Submit" ajax="false" actionListener="#{dataController.send()}" disabled="false" />                                   

    </p:panelGrid>            
</h:form> 

Das Problem dieser Lösung ist: Ich brauche den erweiterten Modus der <p:fileUpload> Komponente.

Ich verstehe nicht, warum ich nicht auf die hochgeladene Datei in der send() Methode zugreifen kann, wenn ich den erweiterten Modus verwenden. Ich benutze den @ViewScoped Bereich, damit es funktionieren sollte.

Antwort

2

uploadFile.getInputstream() throws java.nio.file.NoSuchFileException

Ihr konkretes Problem verursacht, weil Sie versuchen, eine hochgeladene Datei zu lesen, die in einer früheren Anfrage hochgeladen wurde. Ein bisschen anständiger Container bereinigt alle temporären Daten, die mit einer HTTP-Anfrage verbunden sind, wenn die HTTP-Anfrage beendet ist. Dies deckt offenbar auch nicht gelesene hochgeladene Dateien im Falle von WildFly ab (nicht sicher, wie sich andere verhalten).

Ihre beste Wette ist, sie sofort zu speichern, wenn nötig an einem temporären Ort. Verschieben/benennen Sie sie dann in der endgültigen Aktionsmethode an den gewünschten permanenten Speicherort/Namen. Um "vergessene" Dateien für den Fall zu bereinigen, dass der Endbenutzer niemals die endgültige Aktionsmethode aufruft, nachdem er eine Reihe von Dateien hochgeladen hat, ist es am besten, all diese File s in einer sitzungsspezifischen Bean zu verfolgen und file.delete() in @PreDestroy zu kommentieren Methode. Ein konkretes Beispiel ist hier zu finden: How to handle and delete "forgotten" uploaded files?

Wenn das Upload-Formular ist Ansicht scoped, und Sie verwenden OmniFaces, dann können Sie alternativ auch OmniFaces CDI @ViewScoped deren @PreDestroy bereits ausgeführt verwenden, wenn der Benutzer die Seite durch ein leert Navigation oder Schließen von Tab/Fenster.

+0

Vielen Dank für Ihre Hilfe! Ich habe Ihre [first] (http://stackoverflow.com/q/27833140) Lösung für mein Projekt bereitgestellt und es funktioniert perfekt. – Robert

+0

Gern geschehen. – BalusC

1

Die Umsetzung der ausgewählten Antwort

Ich habe vergessen, die Umsetzung der ausgewählten Antwort hinzuzufügen, so dass ich es jetzt tue. Basierend auf einem der Lösung von @BalusC gegeben:

  1. ich hinzugefügt, um die UserFileManager Bohne (der Code unten), die die nicht bestätigten Dateien verwaltet und löscht sie, wenn die Sitzung abgelaufen ist.
  2. Ich injizierte die UserFileManager an die DataController Bohne.
  3. Ich bewegte try catch von send() Methode auf die handleFileUpload() Methode, so dass im Moment die Datei auf der Festplatte gespeichert wird, wenn der Benutzer die Upload Taste drückt.
  4. Nach dem Speichern der Datei im temporären Ordner - ich rief userFileManager.addUnconfirmedUploadedFile(file) in handleFileUpload() Methode. Jetzt sind wir sicher, dass die Datei gelöscht wird (wenn die Sitzung abläuft), wenn der Benutzer nicht die Taste Send drückt. Am Ende habe ich userFileManager.confirmUploadedFile(file) in send() Methode aufgerufen. Jetzt sind wir sicher, dass der Benutzer die Datei auf dem Datenträger behalten möchte, damit wir diese Datei aus der Liste der unbestätigten Dateien löschen.

Hinweis: Ihre hochgeladenen Dateien gespeichert sind, in Wildfly Server des beschreibbar /standalone/data/upload Ordner oder in /standalone/data Ordner, wenn etwas bei der Erstellung des upload Ordner falsch gelaufen ist.

Dies ist die modifizierte DataController Bohne:

@Named 
@ViewScoped 
public class DataController implements Serializable { 

    private static final long serialVersionUID = 1383572529241805730L; 

    public void handleFileUpload(FileUploadEvent event){ 

     uploadFile=event.getFile();  

     try(InputStream input = uploadFile.getInputstream()){ 

      Path folder=Paths.get(System.getProperty("jboss.server.data.dir"),"upload"); 

      if(!folder.toFile().exists()){ 
       if(!folder.toFile().mkdirs()){ 
        folder=Paths.get(System.getProperty("jboss.server.data.dir")); 
       } 
      } 

      String filename = FilenameUtils.getBaseName(uploadFile.getFileName()); 
      String extension = FilenameUtils.getExtension(uploadFile.getFileName()); 
      Path filePath = Files.createTempFile(folder, filename + "-", "." + extension); 
      Files.copy(input, filePath, StandardCopyOption.REPLACE_EXISTING); 

      userFileManager.addUnconfirmedUploadedFile(filePath.toFile()); 

      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Successful", event.getFile().getFileName() + " is uploaded")); 

     } catch (IOException e1) { 

      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR I/O", "Code of the error: DC1")); 
      e1.printStackTrace(); 
     } 
    } 

    public void send(){ 

     userFileManager.confirmUploadedFile(filePath.toFile()); 

     FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "The data has been added.", "")); 
    } 

    @Inject 
    private UserFileManager userFileManager; 
    private UploadedFile uploadFile; 
} 

Dies ist die UserFileManager Bohne, die von @BalusC here erstellt wurde:

@SessionScoped 
public class UserFileManager implements Serializable { 

    private static final long serialVersionUID = -5410871255899363212L; 

    /** 
    * Initialization of list. 
    */ 
    @PostConstruct 
    public void init(){ 
     unconfirmedUploadedFiles = new ArrayList<>(); 
    } 

    /** 
    * Adding the unconfirmed file to the list. 
    * @param unconfirmedUploadedFile unconfirmed file. 
    */ 
    public void addUnconfirmedUploadedFile(File unconfirmedUploadedFile) { 
     unconfirmedUploadedFiles.add(unconfirmedUploadedFile); 
    } 

    /** 
    * Deleting the confirmed file from the list. 
    * @param confirmedUploadedFile confirmed file. 
    */ 
    public void confirmUploadedFile(File confirmedUploadedFile) { 
     unconfirmedUploadedFiles.remove(confirmedUploadedFile); 
    } 

    /** 
    * Deleting unconfirmed files from the disk if the session is expired. 
    */ 
    @PreDestroy 
    public void destroy() { 
     for (File unconfirmedUploadedFile : unconfirmedUploadedFiles) { 
      unconfirmedUploadedFile.delete(); 
     } 
    } 

    //The list which stores the unconfirmed files. 
    private List<File> unconfirmedUploadedFiles; 
} 
+1

'Paths.get (" F:/Wildfly/Files ")' - kennst du 'System.getProperty (" jboss.server.data.dir ")'? Benutze es besser. Er stellt den absoluten Pfad zum schreibbaren '/ standalone/data'-Ordner des JBoss-Servers dar, ohne dass er fest codiert werden muss. Sie können den Ordner '/ Files' einfach über' File # mkdirs() 'erstellen, wenn er nicht existiert. Siehe auch a.o. http://stackoverflow.com/q/18664579 – BalusC

+0

Danke für Ihren Rat. Ich habe das gerade bereitgestellt und ich habe meine Antwort aktualisiert. Wie Sie vorgeschlagen haben, habe ich 'File # mkdirs()' verwendet, um den 'upload'-Ordner im schreibbaren'/standalone/data'-Ordner des WildFly-Servers für meine hochgeladenen Dateien zu erstellen, also habe ich schließlich 'Paths.get (System. getProperty ("jboss.server.data.dir"), "upload") '. – Robert