1

I've got a problem with getInputStream from doPost request and setting filename before. It's giving me a file with right filename but empty file 0kB. If I'll comment setting fileName than I'll get not empty file.

My process: From android apps I'm archiving PDF file to upload server like http POST. At server doPost is like below method.

How to set filename and get not empty file?

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {    
    String fileName = null;
    //Get all the parts from request and write it to the file on server
    //getFileName return filename
    for (Part part : request.getParts()) {
        fileName = getFileName(part);
    }
    File saveFile = new File(SAVE_DIR + fileName);

    // opens input stream of the request for reading data
    InputStream inputStream = request.getInputStream();

    // opens an output stream for writing file
    FileOutputStream outputStream = new FileOutputStream(saveFile);

    byte[] buffer = new byte[BUFFER_SIZE];
    int bytesRead = -1;

    while ((bytesRead = inputStream.read(buffer)) != -1) {
        outputStream.write(buffer, 0, bytesRead);           
    }
    outputStream.close();
    inputStream.close();

    // sends response to client
    response.getWriter().print("UPLOAD DONE");

}

Edit:

private String getFileName(Part part) {
    String contentDisp = part.getHeader("content-disposition");
    System.out.println("content-disposition header= " + contentDisp);
    String[] tokens = contentDisp.split(";");
    for (String token : tokens) {
        if (token.trim().startsWith("filename")) {
            return token.substring(token.indexOf("=") + 2, token.length() - 1);
        }
    }
    return "";
}

Solution:

//Get the right Part
 final Part filePart = request.getPart("uploadedfile");
 //Writes file to location 
 filePart.write(filePart.getSubmittedFileName());
Stepan
  • 97
  • 2
  • 11
  • 1
    What does your `getFileName(part);` method do? – Kayaman Oct 02 '15 at 09:06
  • 1
    The content of `InputStream` can only be consumed once. This happens in `request.getParts()` I guess, so the stream when accessing it a second time is empty. See also http://stackoverflow.com/questions/8522568/why-is-httpservletrequest-inputstream-empty – hotzst Oct 02 '15 at 09:09
  • 1
    Note that the stream returned from `HttpServletRequest.getInputStream()` is not just the uploaded file. It's the stream of the entire request, including all the part headers. To access just the uploaded file, you need the `getInputStream()` of the specific `Part`. – RealSkeptic Oct 02 '15 at 09:13
  • @Stepan Don't paste code in comments, it's unreadable. Edit your original post to include the code. – Kayaman Oct 02 '15 at 09:16

2 Answers2

3

Part offers a getInputStream() method, so you should use that instead of request.getInputStream(); when you're dealing with parts.

However...

Part.write() is a convenience method to write this uploaded item to disk, so you can just use part.write(SAVE_DIR + part.getSubmittedFileName()); and it's all handled for you (note that getSubmittedFileName() is available only for Servlet 3.1).

Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • Do you have some example how to getPart? How to get the "name" which is at uploaded file? – Stepan Oct 02 '15 at 09:30
  • @Stepan What part of my `part.write(SAVE_DIR + part.getSubmittedFileName());` was unclear? You're already getting the parts in your original code, so how can you ask me "how to do it"? Or is that not your code? – Kayaman Oct 02 '15 at 09:32
  • I mean how I know which name I use in getPart? – Stepan Oct 02 '15 at 09:34
  • @Stepan Well that depends on which name (if any) you're giving it in the POST request. – Kayaman Oct 02 '15 at 09:41
0

Do outputstream.flush() before doing outputstream.close()

Prashant
  • 17
  • 1
  • 6