Jsf uploadFile.getInputstream()抛出java.nio.file.NoSuchFileException

Jsf uploadFile.getInputstream()抛出java.nio.file.NoSuchFileException,jsf,file-upload,primefaces,wildfly,Jsf,File Upload,Primefaces,Wildfly,我使用JSF2.2和PrimeFaces5.3。我想把上传的文件保存在磁盘上。下面你可以看到我是如何做到这一点的。当我按下一个Send按钮时,我得到一个java.nio.file.NoSuchFileException异常(在我文章的末尾,我还放了一个完整的stacktrace): 错误[stderr](默认任务-24)java.nio.file.NoSuchFileException:[PATH]\Wildfly\u 10\Wildfly\u HOME\standalone\tmp\Maste

我使用JSF2.2和PrimeFaces5.3。我想把上传的文件保存在磁盘上。下面你可以看到我是如何做到这一点的。当我按下一个
Send
按钮时,我得到一个
java.nio.file.NoSuchFileException
异常(在我文章的末尾,我还放了一个完整的stacktrace):

错误[stderr](默认任务-24)java.nio.file.NoSuchFileException:[PATH]\Wildfly\u 10\Wildfly\u HOME\standalone\tmp\MasterProject.war\endow1357918758070690245upload

当我跟踪stacktrace时,我看到异常是由这行引起的(我认为是这样):

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

这对我来说很奇怪。我可以得到上传文件的名称(通过
uploadFile.getFileName()
),但我不能得到文件的大小(通过
uploadFile.getSize()
),也不能得到
InputStream
(通过
uploadFile.getInputstream()
),在这两种情况下我都得到
NoSuchFileException
异常

附加信息:我必须上传大文件(即200 MB或更多)。当然,我上传小文件时也会遇到同样的例外情况

你知道我为什么会遇到这个异常吗?我如何解决这个问题

这是我上传文件的页面的一部分:

<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>
这是完整的堆栈跟踪:

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)
更新: 我注意到一些新的内容。如果我将
send()
方法的内容移动到
handleFileUpload()
方法(下面的代码)-文件将保存在磁盘上:

@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;
}
但是如果用户按下
Send
按钮,我想将上传的文件保存在磁盘上,而不是更早(即用户按下
Upload
按钮时),因此有必要将文件保存在
Send()
方法中

我还注意到,当我使用
组件的一个简单模式(下面修改的表单)时,一切都正常(即,当用户按下按钮时,文件被保存)。我必须为
DataController
bean中的
uploadFile
对象创建getter和setter以使用
{DataController.uploadFile}
。我也必须将
enctype=“multipart/form data”
属性添加到
组件中(如果没有此属性,则无法工作)


这个解决方案的问题是:我需要
组件的高级模式

我不明白当我使用高级模式时,为什么我不能在
send()
方法中访问上载的文件。我使用
@ViewScoped
范围,所以它应该可以工作

uploadFile.getInputstream()抛出java.nio.file.NoSuchFileException

您的具体问题是因为您试图读取上一个请求中上载的上载文件。当HTTP请求完成时,一个稍微体面的容器将清理与HTTP请求相关的所有临时数据。这显然还包括WildFly中未读取的上载文件(但不知道其他人的行为如何)

如果有必要,最好直接将它们保存在某个临时位置。然后,在最终操作方法中,将它们移动/重命名到所需的永久位置/名称。为了清除“遗忘”文件如果最终用户在上传了一堆文件后从未调用最终操作方法,那么最好的办法是跟踪会话范围bean中的所有
文件
s,并在
@PreDestroy
注释方法中执行
File.delete()

如果上传表单是视图范围,并且您使用的是OmniFaces,那么您也可以使用OmniFaces CDI,当用户通过导航或关闭选项卡/窗口卸载页面时,该CDI的
@PreDestroy
将已经运行。

所选答案的实现 我忘了添加所选答案的实现,所以我现在正在添加。基于@BalusC给出的解决方案之一:

  • 我添加了
    UserFileManager
    bean(下面的代码),它管理未确认的文件,并在会话过期时删除它们
  • 我将
    UserFileManager
    注入
    DataController
    bean
  • 我将
    try catch
    send()
    方法移动到
    handleFileUpload()
    方法,因此当用户按下
    Upload
    按钮时,文件保存在磁盘上
  • 将文件保存到临时文件夹后,我在
    handleFileUpload()
    方法中调用了
    userFileManager.addUnconfirmedUploadedFile(file)
    。现在,如果用户不按下
    发送
    按钮,我们可以确定该文件将被删除(会话到期时)
  • 最后,我在
    send()
    方法中调用了
    userFileManager.confirmUploadedFile(file)
    。现在我们确定用户希望将该文件保留在磁盘上,因此我们将该文件从未确认文件列表中删除
  • 注意:您上传的文件存储在WildFly server的可写
    /standalone/data/upload
    文件夹或
    /standalone/data
    文件夹中,如果在创建
    upload
    文件夹过程中出现问题,则存储在
    /data
    文件夹中

    这是经过修改的
    DataController
    bean:

    @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;
    }
    
    这是@BalusC创建的
    UserFileManager
    bean:

    @SessionScoped
    公共类UserFileManager实现可序列化{
    私有静态最终长serialVersionUID=-5410871255899363212L;
    /**
    *列表的初始化。
    */
    @施工后
    公共void init(){
    unconfirmedUploadedFiles=新建ArrayList();
    }
    /**
    *将未确认的文件添加到列表中。
    *@param unconfirmedUplo
    
    <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>
    
    @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;
    }
    
    @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;
    }