我使用JSF 2.2和Primefaces 5.3。我想将上传的文件保存在磁盘上。下面你可以看到我是如何尝试这样做的。当我按下Send
按钮时,我得到一个java.nio.file.NoSuchFileException
异常(在我的帖子末尾我也放了一个完整的堆栈跟踪):
错误[stderr](默认任务-24)java.nio.file.NoSuchFileException:[PATH] \ Wildfly_10 \ WILDFLY_HOME \ standalone \ tmp \ MasterProject.war \ undertow1357918758070690245upload
当我跟踪堆栈跟踪时,我发现异常是由这一行引起的(我想是这样):
try(InputStream input = uploadFile.getInputstream()){
对我来说很奇怪。我可以获取上传文件的名称(uploadFile.getFileName()
),但我无法获得文件的大小(uploadFile.getSize()
),而我无法获得{{1} (InputStream
)。在这两种情况下,我都会得到uploadFile.getInputstream()
例外。
其他信息:我上传大文件(即200 MB或更多)。当然,当我上传小文件时,我得到了相同的异常。
您是否知道为什么我会遇到此异常?如何解决此问题?
我上传文件的页面的一部分:
NoSuchFileException
这是CDI bean,它是上述页面的控制器:
<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>
这是完整的堆栈跟踪:
@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;
}
我发现了一些新的东西。如果我将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
按钮时),那么我想将上传的文件保存在磁盘上,以便#&# 39;必须以Upload
方法保存文件。
我还注意到,当我使用send()
组件的简单模式(下面的修改后的表单)时,一切正常(即用户按下按钮时保存文件)。我必须为<p:fileUpload>
bean中的uploadFile
对象创建getter和setter才能使用DataController
。我必须将#{dataController.uploadFile}
属性添加到enctype="multipart/form-data"
组件中(没有此属性,它不起作用)。
<h:form>
此解决方案的问题是:我需要<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>
组件的高级模式。
我不明白为什么在使用高级模式时无法使用<p:fileUpload>
方法访问上传的文件。我使用send()
范围,因此它应该可以工作。
答案 0 :(得分:4)
uploadFile.getInputstream()抛出java.nio.file.NoSuchFileException
您的具体问题是由于您尝试阅读上一个请求中上传的上传文件而导致的。当HTTP请求完成时,一个有点像容器将清除与HTTP请求关联的所有临时数据。在WildFly的情况下,这显然也涵盖了非读取的上传文件(不知道其他人的表现如何)。
你最好的选择是直接保存它们,如果有必要,可以在一些临时位置。然后,在最终操作方法中,将它们移动/重命名为所需的永久位置/名称。为了清理&#34;忘记&#34;在上传了一堆文件之后,最终用户永远不会调用最终操作方法的情况下的文件,最好的办法是跟踪会话范围bean中的所有File
并在file.delete()
中执行@PreDestroy
{1}}带注释的方法。可在此处找到具体示例:How to handle and delete "forgotten" uploaded files?
如果上传表单是视图范围的,并且您正在使用OmniFaces,那么您也可以使用OmniFaces CDI @ViewScoped
,当用户通过a卸载页面时,@PreDestroy
已经运行导航或关闭标签/窗口。
答案 1 :(得分:1)
我忘了添加所选答案的实现,所以我现在就这样做了。根据@BalusC给出的解决方案之一:
UserFileManager
bean(下面的代码),如果会话过期,则删除它们。 UserFileManager
注入DataController
bean。 try catch
从send()
方法移至handleFileUpload()
方法,因此当用户按下Upload
按钮时,文件会保存在磁盘上。 userFileManager.addUnconfirmedUploadedFile(file)
方法中调用了handleFileUpload()
。现在,如果用户没有按下Send
按钮,我们确定该文件将被删除(会话过期时)。userFileManager.confirmUploadedFile(file)
方法中调用send()
。现在我们确定用户想要将文件保留在磁盘上,以便我们从未确认的文件列表中删除该文件。注意:如果在创建/standalone/data/upload
文件夹期间出现问题,您上传的文件将存储在WildFly服务器的可写/standalone/data
文件夹或upload
文件夹中。
这是修改后的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 here创建的UserFileManager
bean:
@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;
}