I’m doing a simple file upload in jsp. And i seem to have been stopped by this simple path issue. I’m developing on windows but will propably deploy on a linux machine. so i have the tmpdir and the finaldir under mywebsite/tempfiledir and mywebsite/finalfiledir
so i use this code (snippet of the servlet)
public class SyncManagerServlet extends HttpServlet {
private static final String TMP_DIR_PATH = "/tempfiledir";
private File tempDir;
private static final String DESTINATION = "/finalfiledir";
private File destinationDir;
public void init(ServletConfig config){
try {
super.init(config);
tempDir = new File(getAbsolute(TMP_DIR_PATH));
if(!tempDir.isDirectory()){
throw new ServletException(TMP_DIR_PATH + " is not a Directory");
}
destinationDir = new File(getAbsolute(DESTINATION));
if(!destinationDir.isDirectory()){
throw new ServletException(DESTINATION + " is not a Directory");
}
} catch (ServletException ex) {
Logger.getLogger(OrliteSyncManagerServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String email = request.getParameter("email");
String path = request.getContextPath();
DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
fileItemFactory.setRepository(tempDir);
ServletFileUpload uploadHandler = new ServletFileUpload(fileItemFactory);
try {
List items = uploadHandler.parseRequest(request);
Iterator itr = items.iterator();
while(itr.hasNext()){
FileItem item = (FileItem) itr.next();
if( item.isFormField() && item != null ){
out.println("<html>");
out.println("<head>");
out.println("<body>");
out.println("your email: " + item.getString() + " has been submited and context path is "+ request.getContextPath() );
out.println("</body>");
out.println("</head>");
out.println("</html>");
} else {
out.println("the uploaded file name is : " + item.getName());
out.println("content type is : " + item.getContentType());
out.println("Size is : " + item.getSize());
File file = new File(destinationDir, FilenameUtils.getName(item.getName()));
item.write(file);
}
public String getAbsolute(String relativepath){
return getServletContext().getRealPath(relativepath);
}
//......
}
i’m having this exception
java.io.FileNotFoundException: D:\WORK\java\netbeansProject\Projects\mywebsite-webapp\target\mywebsite\finalfiledir (Access is denied)
i can’t figure out why the relative path is failing.
I’ve noticed in a lot of samples online people uses full path for the tempdir.
So in my case where i have to worry about linux on deployment, what’s the workaround?But first i’ld like to understand why the path i’ve given is wrong.
Thanks for reading this!
so 2 issues here
1 how to solve this path immediate issue?
2 how to do it in a more portable way (with linux privileges in mind)?
thanks!
Paths which starts with a leading slash are not relative to the current working directory. They are absolute and would only in Windows point to the current working disk (where the server is running on and is dependent on how the server is been started).
In your case, the
"/tempfiledir"would in Windows point toC:\tempfiledirwhen Windows and the server is installed onC:\, and in Linux to/tempfiledir. You need to add another check ininit()method which does aFile#exists()check as well to spot the absence of the folder timely.As long as you don’t use Windows-specific disk labels like
C:\and use/as path separator, you don’t need to worry about this.If you really insist in writing the files to the webcontent, then you need to keep two things in mind: 1) When deploying as WAR, it only works when the WAR is expanded by servletcontainer. 2) When redeploying the WAR, everything (all uploaded files) will be erased.
This is how you can convert relative web paths to absolute disk file system paths so that you can use it further in
Fileand consorts:Unrelated to the problem: the
item.getName()would return the full client side path in certain webbrowsers (specifically: the MSIE family). As per the Commons Fileupload FAQ you need to callFilenameUtils#getName()on it before using as filename innew File(), otherwise it will cause havoc there as well.