Issue
Glassfish seems to be adding extra to the path I want to save my image file too, is there some way to use only the absolute path my servlet gets with
String appPath = request.getServletContext().getRealPath("");
?
I have spent days trying different methods to upload an image file and have a servlet save it to disk.
I used this example: http://www.codejava.net/java-ee/servlet/how-to-write-upload-file-servlet-with-servlet-30-api
Using debug I can see the file name and path information is collected correctly but the code fails at `part.write(savePath + File.separator + fileName);``
And glassfish's exception report is:
exception
java.io.FileNotFoundException: C:\Program Files\glassfish-3.1.2.2\glassfish\domains\domain1\generated\jsp\com.onemore_onemore-web_war_1.0-SNAPSHOT\D:\Dropbox\Git\Brian_JEE\onemore\onemore\onemore-web\target\onemore-web-1.0-SNAPSHOT\image\screengrab_all_products.jpg (The filename, directory name, or volume label syntax is incorrect)
I can see the correct path as part of this exception D:\Dropbox\Git\Brian_JEE\onemore\onemore\onemore-web\target\onemore-web-1.0-SNAPSHOT\image\screengrab_all_products.jpg
JSP
<form action="${pageContext.request.contextPath}/imageupload" method="post" enctype="multipart/form-data" name="productForm" id="productForm">
<input type="file" name="file" id="file">
<input type="submit" name="Submit" value="Submit"></td>
</form>
Servlet
@WebServlet(name = "UploadImageServlet", urlPatterns = {"/imageupload"})
@MultipartConfig(fileSizeThreshold = 1024 * 1024 * 2, // 2MB
maxFileSize = 1024 * 1024 * 10, // 10MB
maxRequestSize = 1024 * 1024 * 50) // 50MB
public class UploadImageServlet extends HttpServlet {
/**
* Name of the directory where uploaded files will be saved, relative to the
* web application directory.
*/
private static final String SAVE_DIR = "image";
/**
* handles file upload
*/
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// gets absolute path of the web application
String appPath = request.getServletContext().getRealPath("");
// constructs path of the directory to save uploaded file
String savePath = appPath + File.separator + SAVE_DIR;
// creates the save directory if it does not exists
File fileSaveDir = new File(savePath);
if (!fileSaveDir.exists()) {
fileSaveDir.mkdir();
}
for (Part part : request.getParts()) {
String fileName = extractFileName(part);
part.write(savePath + File.separator + fileName);
}
request.setAttribute("message", "Upload has been done successfully!");
getServletContext().getRequestDispatcher("/WEB-INF/jsp/newproduct.jsp").forward(
request, response);
}
/**
* Extracts file name from HTTP header content-disposition
*/
private String extractFileName(Part part) {
String contentDisp = part.getHeader("content-disposition");
String[] items = contentDisp.split(";");
for (String s : items) {
if (s.trim().startsWith("filename")) {
return s.substring(s.indexOf("=") + 2, s.length() - 1);
}
}
return "";
}
}
Solution
Never use getRealPath()
You should not save uploaded files in the deploy folder. I have explained this so many times before. One of those explanations can be found in this answer: Uploaded image only available after refreshing the page.
Any JSP/Servlet code snippet found on some blog/article which ever uses the getRealPath()
method should be taken with a huge bag of salt. Its quality and the knowledge of the author should strongly be questioned. There is namely no sensible real world use case for that method.
Save uploaded files in a fixed path outside the deploy folder. See also How do I set the folder for storing file uploads using Commons FileUpload.
Answered By - BalusC
Answer Checked By - Pedro (JavaFixing Volunteer)