-1

The following servlet handles uploading of a photo and a caption for that photo. The servlet was working fine (uploading the photos to the requested directory) until the logic to handle the text-field of the same from was added. Now it neither uploads the photo nor submits the caption to the database. The form has the enctype of multipart/form-data.

HTML

    <form method="post" action="UploadHandler" enctype="multipart/form-data">
        <table>

            <tr>
                <td> <strong> Browse photo to submit </strong> </td>
                <td> <input type="file" name="ImageToUpload" value="Upload Photo"/> </td>
            </tr>

            <tr>
                <td> <strong> Give a Caption to this photo </strong>  </td>
                <td> <input type="text" name="CaptionBox" size="40" /></td>
            </tr>

            <tr>
                <td> <strong> Tags &nbsp;<a href="#"> <i> Browse tags </i> </a> </strong> </td>
                <td> <input type="text" size="20" value="Tags" id="tagfield" style="color: #A0A0A4; font-size:16px;" onfocus="emptyTheDefaultValue()"> </td>
            </tr>
            <tr colspan="2">
                <td> <input type="submit" value="submit photo"/> </td>
            </tr>

        </table>
 </form>

Servlet that handles uploading

package projectcodes;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.File;
import java.util.List;
import java.util.Iterator;
import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;
import NonServletFiles.HandleCaption;
import NonServletFiles.ChangePartToString;

public class UploadHandler extends HttpServlet {
@Override
public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException {
    response.setContentType("text/plain");
    String path = request.getParameter("ImageToUpload"); 
    // Now handle the caption
    // Note : They have a multipart/form-data request
    // Using the servlet API 3.0
    ChangePartToString cpts = new ChangePartToString(request.getPart("CaptionBox")); // get the CaptionBox part 
    String caption = null;

        try {
            caption = cpts.getValue();
            System.out.println(caption); // <<-------- I get this value fine
        }catch(Exception exc) {
            exc.printStackTrace();
            System.out.println(exc);
        }

    PrintWriter writer = response.getWriter();
    try {
        Boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if(!isMultipart) {
            Boolean AttemptToUploadFile = true;
            RequestDispatcher rd = request.getRequestDispatcher("portfolio_one.jsp");
            request.setAttribute("UploadAttempt", AttemptToUploadFile);
            rd.forward(request, response);
        } else {
            DiskFileItemFactory diskFileItem = new DiskFileItemFactory();
            ServletFileUpload fileUpload = new ServletFileUpload(diskFileItem);
            List list = null;

            try {
                list = fileUpload.parseRequest(request);
            }catch(Exception exc) {
            //                    Boolean AttemptToUploadFile = true;
            //                    RequestDispatcher rd = request.getRequestDispatcher("portfolio_one.jsp");
            //                    request.setAttribute("UploadAttempt", AttemptToUploadFile);
            //                    rd.forward(request, response);
                exc.printStackTrace();
                System.out.println(exc);
            }

            Iterator iterator = list.iterator();
            while(iterator.hasNext()) {
                String emailOfTheUser = null;
                FileItem fileItem = (FileItem)iterator.next();
                if(!fileItem.isFormField()) {
                    String fieldName = fileItem.getFieldName();
                    String fileName = FilenameUtils.getName(fileItem.getName());
                    HttpSession session = request.getSession();
                    if(!session.isNew()) {
                        emailOfTheUser = (String)session.getAttribute("Email");
                    }
                    File file = new File("/home/non-admin/project uploads/project users/" + emailOfTheUser ,fileName);
                    fileItem.write(file);
                    // now since the file has been uploaded , upload the caption to the photo  
                    System.out.println("THE CAPTION :" + caption);
                    HandleCaption hc = new HandleCaption(caption,emailOfTheUser,fileName);
                    hc.SubmitCaptionToTheDatabase(); // This calls invokes a method that submits a caption to the database
                    RequestDispatcher rd = request.getRequestDispatcher("portfolio_one.jsp");
                    String message = "File Uploaded successfully !";
                    request.setAttribute("SuccessMessage", message);
                    rd.forward(request, response);
                }
            }
        }
    }catch(Exception exc) {
        exc.printStackTrace();
        System.out.println(exc);
    }
}

}

The caption string is returned fine. What could be the reason that file is not uploading. I don't see any exception thrown in the server log.

Suhail Gupta
  • 22,386
  • 64
  • 200
  • 328
  • Do you have any exceptions in your log files? – ilalex Apr 27 '12 at 09:27
  • @ilya no. I mentioned in my question. I just see the startup info and the caption that i made to print using _System.out.println(caption)_ – Suhail Gupta Apr 27 '12 at 09:29
  • i think there is a problem with `if(!fileItem.isFormField()) `. you are handling a text field and a file field of _multipart/form-data_ using _org.apache.commons_ – saplingPro Apr 27 '12 at 10:09
  • If i remove the logic to handle the text-field with name="CaptionBox" photo uploads fine – Suhail Gupta Apr 27 '12 at 10:47

1 Answers1

2

You're mixing Servlet 3.0 builtin multipart parser with Apache Commons FileUpload. You should not do that. Once a request body is parsed by one API, it cannot be parsed anymore by another API. The client ain't going to resend the same request body multiple times as the server needs to parse it.

Remove Apache Commons FileUpload. You don't need it when already utilizing Servlet 3.0 builtin multipart parser. You only need to add @MultipartConfig annotation to the servlet class in order to get the multipart parser to work correctly for both plain form fields and file fields. You should also not use getParameterXxx() methods. See also How to upload files to server using JSP/Servlet?

Here's the necessasry rewrite of your code so that you get the both values:

@WebServlet("/UploadHandler")
@MultipartConfig
public class UploadHandler extends HttpServlet {

    @Override
    public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException {
        Part imageToUpload = request.getPart("ImageToUpload");
        String imageFilename = getFilename(imageToUpload);
        InputStream imageContent = imageToUpload.getInputStream();
        String captionBox = getValue(request.getPart("CaptionBox"));

        // ...
    }

    private static String getFilename(Part part) {
        for (String cd : part.getHeader("content-disposition").split(";")) {
            if (cd.trim().startsWith("filename")) {
                String filename = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
                return filename.substring(filename.lastIndexOf('/') + 1).substring(filename.lastIndexOf('\\') + 1); // MSIE fix.
            }
        }
        return null;
    }

    private static String getValue(Part part) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(part.getInputStream(), "UTF-8"));
        StringBuilder value = new StringBuilder();
        char[] buffer = new char[1024];
        for (int length = 0; (length = reader.read(buffer)) > 0;) {
            value.append(buffer, 0, length);
        }
        return value.toString();
    }

}
Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • what is the method to handle the text-field _(of type multipart)_ using apache commons. I think i should use apache commons instead of servlet 3.0 API ! – Suhail Gupta Apr 28 '12 at 05:04
  • Do it in the `else` of your original `if(!fileItem.isFormField())` block. See also http://stackoverflow.com/questions/2422468/how-to-upload-files-in-jsp-servlet/2424824#2424824 You should make sure that you're **nowhere** calling `request.getParameter()` or `request.getPart()` beforehand, otherwise Apache Commons FileUpload will get nothing to parse. – BalusC Apr 28 '12 at 12:35
  • thank you ! It worked. I appreciate the effort you put for each question. – Suhail Gupta Apr 28 '12 at 15:02