开发者

Spring MVC: FileNotFoundException "\Uploads\MyUploads\loading.gif (The system cannot find the path specified)"

Problem Context:

I am trying to persist a file, uploaded by the user, to file system.

Description:

Actually, I am using Spring MVC (3.0) and this is how I am trying to persist the file,

String orgName = file.getOriginalFilename();
String filePath = "/Uploads/MyUploads/"+ new Date().getTime()+orgName;// Unique Image Name
File dest 开发者_JAVA技巧= new File(filePath);
file.transferTo(dest);

I have a folder Uploads\MarketplaceUploads, at the root of my application. But still I am getting FileNotFoundException "\Uploads\MyUploads\loading.gif (The system cannot find the path specified)".

Below is the directory structure:

Spring MVC: FileNotFoundException "\Uploads\MyUploads\loading.gif (The system cannot find the path specified)"


You should not store uploaded files in public web content.

  • It will not work in any way when the WAR is not expanded by the container (this is configureable at server level and not controllable whenever it's a 3rd party host). You simply can't write the uploaded file to it in any way.
  • All uploads will get lost whenever you redeploy (an update) of the WAR. You need to remember to backup them everytime.
  • In some servers, all uploads will also get lost whenver the server is restarted. You have no control over this whenever it's a 3rd party host.

Store them outside the server's webapps folder. Provide the root of this location as an absolute disk file system path to your webapp, e.g. by a properties file or a VM argument. An alternative is to store them in a database, this is often the only solution if it's a 3rd party host which doesn't offer access to a fixed location outside the web content.


Ensure you add the web-app context path before using the file

String orgName = file.getOriginalFilename();
String filePath = getServletContext().getRealPath("/") + "/Uploads/MyUploads/"+ new Date().getTime()+orgName;// Unique Image Name
File dest = new File(filePath);
file.transferTo(dest);

From the javadoc of getRealPath()

Gets the real path corresponding to the given virtual path. For example, if path is equal to /index.html, this method will return the absolute file path on the server's filesystem to which a request of the form http://://index.html would be mapped, where corresponds to the context path of this ServletContext. The real path returned will be in a form appropriate to the computer and operating system on which the servlet container is running, including the proper path separators. Resources inside the /META-INF/resources directories of JAR files bundled in the application's /WEB-INF/lib directory must be considered only if the container has unpacked them from their containing JAR file, in which case the path to the unpacked location must be returned. This method returns null if the servlet container is unable to translate the given virtual path to a real path.


Try this instead,

String orgName = file.getOriginalFilename();
// the leading slash is important
String filePath = "/Uploads/MyUploads/"+ new Date().getTime()+orgName; 
File dest = new File(req.getServletContext().getResource(filePath).toURI());
file.transferTo(dest);

Using getRealPath() is, indeed, a bad idea. Simply, because you are trying to read a resource which actually resides inside the application. Therefore, we need not use getRealPath(). Furthermore, if the application is being run from a bundled .war file, getRealPath() will return null.

Resources:

  • Similar problem is being discussed over here, Why does getRealPath() return null when deployed with a .war file?
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜