2

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 "";
    }
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
chris loughnane
  • 2,648
  • 4
  • 33
  • 54

2 Answers2

4

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.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • thank you for your answer. I've read many of your posts, I now have my images out side the deploy folder and set a new property `alternatedocroot_1` in `glassfish-web.xml` which correctly maps the images for display. Unfortunately my `part.write` insists on writing files to the wrong folder no matter what path I enter. Could you please show me how to get `write.part` to save a file to the folder I set. thank you – chris loughnane Feb 13 '13 at 14:57
  • Make sure that the path starts with a leading slash: `part.write("/path/to/filename.ext")`. – BalusC Feb 13 '13 at 15:00
  • 1
    thank you. After reading up on @MultipartConfig annotations I found I could set the path with `location="****"` The file successfully uploads to my desired folder and then glassfish reports an exception (File Access Denied). Though at least the file is going to the right place. – chris loughnane Feb 13 '13 at 15:40
  • That represents the temporary storage folder for the case the file is larger than file upload memory configuration can hold and is absolutely not intented as permanent storage location. It will be cleaned at timed intervals. It defaults to `System.getProperty("java.io.tmpdir")` which should be perfectly fine in most cases. You're still going in the wrong path. Please don't ignore my advice and write it to the desired location **yourself** using an **absolute disk file system path**, as answered. – BalusC Feb 13 '13 at 15:42
  • Thank you for all your help. After two weeks of 14 hr days I simply do not have the time and energy for this any more. Exams are looming and this is only part of one course. My team mates are telling me to just can the idea. I tried putting in a leading slash on a path and I end up back with the old error (The system cannot find the path specified). We are getting no support here with this project and every single step is a struggle. With out people like you we would be completely screwed. – chris loughnane Feb 13 '13 at 15:58
  • Oh. I am no longer using .getServletContext().getRealPath("") – chris loughnane Feb 13 '13 at 15:59
  • @chrisloughnane: glassfish does not support absolute file paths in `Part.write()` apparently : see [here](http://stackoverflow.com/questions/19738244/glassfish-part-write-no-absolute-paths-workaround) – Mr_and_Mrs_D Nov 02 '13 at 02:11
0

Use the following code. I resolved this error using these codes.Write it into your doPost method.

Part filePart = request.getPart("file");
String fileName = 
Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); 
InputStream inputStream = filePart.getInputStream();
String uploadPath = getServletContext().getRealPath("") + File.separator + "uploaded_file";
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
            uploadDir.mkdir();
        }
FileOutputStream outputStream = new FileOutputStream(uploadPath + 
File.separator + fileName);
        int read = 0;
        final byte[] bytes = new byte[1024];
        while ((read = inputStream.read(bytes)) != -1) {
            outputStream.write(bytes, 0, read);
        }

\\

Vikas
  • 9
  • 3