简体   繁体   中英

Java Servlet FileUpload error

I am learning java servlet programming and I wrote a program to upload files, I'm having a strange problem with the program. when it says it finished uploading the file and when i click the link to see it I get a 404 error and when i check the directory (where the file is supposed to be saved ) its empty. I checked the log and there are no error messages.I got the code from a book I'm using to learn servlet and jsp.

here is my java code

import java.io.*;
import java.util.*;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class FileUpload
 */
@WebServlet("/FileUpload")
public class FileUpload extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public FileUpload() {
        super();
        // TODO Auto-generated constructor stub
    }


    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        response.setContentType("text/html");
        PrintWriter out = response.getWriter();

        out.println("<html>");
        out.print("File upload success. <a href=\"/Project_One/files");
        out.print("\">Click here to browse through all uploaded ");
        out.println("files.</a><br>");

        ServletInputStream sis = request.getInputStream();
        StringWriter sw = new StringWriter();
        int i = sis.read();
        for(;i!=-1 && i!= '\r';i=sis.read())
            {
                sw.write(i);
            }
        sis.read(); //ditch \'n'
        String delimiter = sw.toString();


        while(true)
            {
                StringWriter h = new StringWriter();
                int[] temp = new int[4];
                temp[0] = (byte)sis.read();
                temp[1] = (byte)sis.read();
                temp[2] = (byte)sis.read();
                h.write(temp[0]);
                h.write(temp[1]);
                h.write(temp[2]);

                //read header
                for(temp[3]=sis.read();temp[3]!=-1;temp[3]=sis.read())
                    {
                        if(temp[0] == '\r' &&
                           temp[1] == '\n' &&
                           temp[2] == 'r'  &&
                           temp[3] == '\n')
                            {
                                break;
                            }

                        h.write(temp[3]);
                        temp[0]= temp[1];
                        temp[1]= temp[2];
                        temp[2]= temp[3];   
                    }
                String header = h.toString();

                int StartName = header.indexOf("name=\"");
                int endName = header.indexOf("\"",StartName+6);
                if(StartName == -1|| endName == -1)
                    {
                        break;
                    }
                String name = header.substring(StartName+6,endName);
                if(name.equals("file"))
                    {
                        StartName = header.indexOf("filename=\"");
                        endName = header.indexOf("\"",StartName+10);
                        String filename = header.substring(StartName+10,endName);
                        ServletConfig config = getServletConfig();
                        ServletContext sc = config.getServletContext();

                        //File file = new File(sc.getRealPath("/files"));
                        //file.mkdirs();
                        FileOutputStream fos = new FileOutputStream(sc.getRealPath("/")+"/"+filename);

                        //write the file to disk 
                        int length = delimiter.length();
                        //delimiter ="\r\n"+delimiter;
                        byte[] body = new byte[delimiter.length()];
                        for(int j=0;j<body.length-1;j++)
                            {
                                body[j]=(byte)sis.read();
                                fos.write(body[j]);
                            }

                        //check it wasn't a 0 length file
                        //if(!delimiter.equals(new String (body)))
                            //{
                                int e = body.length-1;
                                i=sis.read();
                                for(;i!=-1;i=sis.read())
                                    {
                                        body[e]=(byte)i;
                                        /*fos.write(body[0]);
                                        for(int l=0;l<body.length-1;l++)
                                            {
                                                body[l]=body[l+1];
                                            }*/
                                        //body[e]=(byte)i;

                                        if(delimiter.equals(new String (body)))
                                            {
                                                break;
                                            }
                                        //length++;
                                        fos.write(body[e]);
                                        for(int k=0;k<body.length-1;k++)
                                            {
                                                body[k]=body[k+1];

                                            }
                                        length++;
                                    }

                        fos.flush();
                        fos.close();
                        out.println("<p><b>Saved File:</b>"+filename+"</p>");
                        out.println("<p><b>Length:</b>"+ length+"</p>");
                    }
                if(sis.read() == '-' && sis.read()=='-')
                    {
                        break;
                    }

                    }
        out.println("</html>");


            }



    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        doPost(request,response);
    }



}

There were few changes made in the code , the changes were given in the book. here is my HTML code

<html>
    <head>
        <title>Test HTML Form</title>
    </head>
    <body>
    <p>Select a file to upload or <a href="/Project_One/files/">browse currently uploaded files.</a></p>
    <form action="http://127.0.0.1/Project_One/FileUpload"
          method="post" enctype="multipart/form-data">
          File:<input type="file" name:"file"><br>
          <input value="Upload File" type="submit">
    </form>
    </body>
</html>

I'm using TomCat sever for this.

well i think this code is a bit complicated to read but there are a few points where the error could be, first of all this part :

    out.println("<html>");
    out.print("File upload success. <a href=\"/Project_One/files");
    out.print("\">Click here to browse through all uploaded ");
    out.println("files.</a><br>");

In this part your link points to Project_One/files but when you write your file :

    FileOutputStream fos = new FileOutputStream(sc.getRealPath("/")+"/"+filename);

you write the file directly in the Project_One folder ( not in the files folder your html points ) , so you could try to see if the file was written in the main folder of your workspace.

Anyway i think you could understand better a code like this :

  MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) req;
  MultipartFile multipartFile = multipartRequest.getFile("file");
  byte[] content =multipartFile.getBytes();
  File archivoParaGuardar= new File("/your_directory/"+multipartFile.getOriginalFilename());
  try {
    baos.write(content);
    FileOutputStream fos = new FileOutputStream(archivoParaGuardar);
    baos.writeTo(fos);
    fos.close();
  } catch (Exception e) {
   logger.error("Error saving file ", e);
  }

Hope this helps you.

Where did you get this code from? From a decade old servlet tutorial/book? This is all unnecessarily overcomplicated. Please make sure that you're reading an up to date tutorial/book which is no older than one year.

Here's how the file upload could be done with the standard servlet 3.0 API:

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

    private static final long serialVersionUID = 1L;

    @Override    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Part filePart = request.getPart("file"); // Retrieves <input type="file" name="file">
        String filename = getFilename(filePart);
        InputStream filecontent = filePart.getInputStream();
        // ... (do your job here)
    }

    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;
    }

}

That's all. It also takes into account that the proper filename is returned. Some browsers such as MSIE namely incorrectly includes the full client side path along the filename. That might be the cause of your problem.

Further there are 2 other problems not directly related:

  1. You should not store the uploaded file in the deploy folder. It will get lost whenever you redeploy the webapp. Store the file in a fixed path somewhere outside the deploy folder. See also for example How I save and retrieve an image on my server in a java webapp .

  2. You should be delegating the job of generating HTML to JSP. In the end of doPost() , forward the request to a JSP:

     request.getRequestDispatcher("/WEB-INF/uploadresult.jsp").forward(request, response); 

See also:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM