Multiple files upload using REST

14,430

The following is the solution that works for me. The request parts in case of a multipart/formdata request can be accessed using the input stream in the part. I wanted to send a string and some files to my REST web service.I found a ServletFileUpload/ FIleItem example posted at a couple of web sites but I could not retrieve the string( I think it gives an exception if all data is not of file type). Hence I modified my web service to the following and not I can do the processing of a string and some files:

    private static  Logger   logger = Logger.getLogger("UploadFiles");
@POST
@Path("savefile")
public void createObjects(@Context HttpServletRequest request)
{
    try
    {
        FileHandler f;
        f = new FileHandler(new File (getClass().getResource("/" +getClass().getName().substring(
                0, getClass().getName().indexOf("."))).getPath()).getParent().replaceAll("\\\\", "\\\\\\\\")  + "/mylog.log");
        logger.addHandler(f);

    }
    catch (SecurityException e1)
    {
        logger.info(e1.getMessage());

    }
    catch (IOException e1)
    {
        logger.info(e1.getMessage());
    }
    ApplicationConstants.ROOTPATH = new File (getClass().getResource("/" +getClass().getName().substring(
            0, getClass().getName().indexOf("."))).getPath()).getParent().replaceAll("\\\\", "\\\\\\\\") ;
    ApplicationConstants.ROOTPATH = ApplicationConstants.ROOTPATH.substring
    (0, ApplicationConstants.ROOTPATH.indexOf("\\") + 2);
    String user = request.getParameter("username");
    logger.info("ApplicationConstants.ROOTPATH" + ApplicationConstants.ROOTPATH);
    logger.info("username" + user);
    try
                {
        for (Part part : request.getParts())
        {

                    logger.info("part = " + part.getName());
                    if (!part.getName().equalsIgnoreCase("username"))
                    {
                        try {
                        BufferedInputStream in = new BufferedInputStream(part.getInputStream());
                        String filename = getFilename(part);
                        boolean success = (new File(ApplicationConstants.ROOTPATH + user + "\\")).mkdir();
                        if (success) {
                        System.out.println("Directory: " + ApplicationConstants.ROOTPATH + user .trim()+ "\\" + " created");
                        }  
                        else
                        {
                            System.out.println("not created");
                        }
                        FileOutputStream out = new FileOutputStream(ApplicationConstants.ROOTPATH + user  + "\\" + filename);

                        byte[] data = new byte[1000];
                        int bytesRead = 0;
                        int offset = 0;
                        while (offset < part.getSize())
                        {
                          bytesRead = in.read(data);
                          if (bytesRead == -1)
                          {
                              break;
                          }
                          offset += bytesRead;
                           out.write(data);
                        }

                        in.close();

                        if (offset != part.getSize())
                        {
                          throw new IOException("Only read " + offset + " bytes; Expected " + part.getSize() + " bytes");
                        }
                        out.flush();
                        out.close();
                        }
                        catch (Exception e) 
                        {
                            logger.info(e.getMessage());
                        }
                    }
                    else
                    {
                        BufferedReader reader = new BufferedReader(new InputStreamReader(part.getInputStream(), "UTF-8"));
                        StringBuilder value = new StringBuilder();
                        char[] buffer = new char[1024];
                        reader.read(buffer);
                        value.append(buffer);
                         user = value.toString().trim();
                         logger.info("user = " + value);
                    }

}
    }
    catch (IOException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    catch (ServletException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

Hope this helps someone!!

Share:
14,430

Related videos on Youtube

kavita
Author by

kavita

Updated on June 04, 2022

Comments

  • kavita
    kavita almost 2 years

    I have a input type=file tag in my html which allows user to select multiple files. The action for the form is a REST web service:

    @POST
    @Path("savefile")
    @Produces ({MediaType.TEXT_PLAIN})
    public String createObjects(
            @FormDataParam("datafile") FormDataMultiPart file,
            @FormParam("username") String unm
            //@Context HttpServletRequest request
            ){....}
    

    Initially I used the request object to retrieve all FileItems in the request and then saved it to the server. No problem with that. Now I want to send a string data along with the files. For that I read that the parameters need to be of type FormDataParam. Hence I have added that parameter. This is my client code :

    <form id="form1" action="http://comp1:8080/RestWSGS/jersey/UploadFiles/savefile"
            enctype="multipart/form-data" method="post">
            <input name="username" type="text" style="display:none" value="abc"/>
      <input id="loadId" multiple="multiple" 
            type="file" name="datafile" required="required" autofocus="autofocus"
            onchange="selectFiles(this)"/>
      <div>
        <input style="display: none;" type="submit" value="Send">
      </div>
     </form>  
    

    I am not sure what must be the type of the file parameter to allow multiple files in it???? Either the file parameter gives me multiple files OR do I have to revert back to the @Context injection?? If so how will I retrieve the string parameter?

    Any help is welcome!

    EDIT: I have modified my REST ws to the following:

    @POST
    @Path("savefile")
    //@Consumes (MediaType.MULTIPART_FORM_DATA)
    public void createObjects(
            //@FormDataParam("datafile") FormDataMultiPart file,
            //@FormParam("username") String unm
            @Context HttpServletRequest request
            )
    {
        try
        {
            FileHandler f;
            f = new FileHandler(new File (getClass().getResource("/" +getClass().getName().substring(
                    0, getClass().getName().indexOf("."))).getPath()).getParent().replaceAll("\\\\", "\\\\\\\\")  + "/mylog.log");
            logger.addHandler(f);
    
        }
        catch (SecurityException e1)
        {
            logger.info(e1.getMessage());
    
        }
        catch (IOException e1)
        {
            logger.info(e1.getMessage());
            //e1.printStackTrace();
        }
    
    
        ApplicationConstants.ROOTPATH = new File (getClass().getResource("/" +getClass().getName().substring(
                0, getClass().getName().indexOf("."))).getPath()).getParent().replaceAll("\\\\", "\\\\\\\\") ;
        ApplicationConstants.ROOTPATH = ApplicationConstants.ROOTPATH.substring
        (0, ApplicationConstants.ROOTPATH.indexOf("\\") + 2);
        String user = request.getParameter("username");
        logger.info("ApplicationConstants.ROOTPATH" + ApplicationConstants.ROOTPATH);
    
    
        try
        {
            for (Part part : request.getParts())
            {
                    try
                    {
                        logger.info("part = " + part.getName());
                        if (!part.getName().equalsIgnoreCase("username"))
                        {
                            String fileName = processFileName(part.getName());
                            part.write(new File(ApplicationConstants.ROOTPATH + user + "\\" + fileName).getPath());
                        }
    
                        else
                        {
                             user = request.getParameter("username");
                             logger.info("user = " + user);
                        }
                    }
                    catch (IOException e)
                    {
                        logger.info(e.getMessage());
    
                    }
            }
        }
        catch (IOException e)
        {
    
        }
        catch (ServletException e)
        {
    
        }
    }
    

    But I am always getting the value from request.getParameter("username") as null. I dont know what is going wrong!! Is it illegal to send other data as well in a multipart/form-data form?? I need some pointers here. Please suggest any improvements in this code.

    • JohnP
      JohnP over 12 years
      You can get better visibility for your question by tagging it with the related programming language