Multiple files upload using REST
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!!
Related videos on Youtube
kavita
Updated on June 04, 2022Comments
-
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 over 12 yearsYou can get better visibility for your question by tagging it with the related programming language
-