Selecting multiple files and uploading them using Jersey
Asked Answered
O

3

5

I need help with multiple file uploads using Jersey. I used the following code to upload a single file using Jersey.

package my.first.rest;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;



import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;

@Path("uploadfile")
public class Upload {
String location;



    @POST
    @Path("/upload")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public  String uploadfile(@FormDataParam("file") InputStream is, @FormDataParam("file") FormDataContentDisposition filedetail){



        saveToDisk(is,filedetail);
        return  "File Uploaded Succesfully_"+location;

    }


    private void saveToDisk(InputStream is1,
            FormDataContentDisposition filedetail) {
        // TODO Auto-generated method stub

         location = "E://upload/"+filedetail.getFileName();
        try{
            OutputStream out = new FileOutputStream(new File(location));
            int read = 0;
            byte[] bytes = new byte[1024];
            out = new FileOutputStream (new File(location));
            while((read = is1.read(bytes)) != -1){
                out.write(bytes,0,read);
            }
            out.flush();

            out.close();
        }catch (IOException e){
            e.printStackTrace();
        }
    }


}

The above code works well with uploading a single file but when I add the multiple="multiple" attribute to the input type = file tag, I'm able to select multiple items in a single upload, it uploads the first selected item and the name of the last selected item. I'm not expecting the code to work cause it wasn't meant to handle multiple file uploads but there has to be a way around it, right?? Since, it's taking one file and the name of another one.

I have looked multiple stackoverflow threads and googled a lot. I wouldn't have posted this if I had found the answer. I'm not looking for uploading multiple files using the types of code below:

<input type ="file" name="file">
<input type ="file" name="file">
<input type ="file" name="file2">

I don't want to upload multiple files individually. I want to be able to select multiple files at a time and all of them to be uploaded somewhere. My tag is like this:

<input type ="file" name="file" multiple="multiple">

Here's the entire HTML code.

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form action ="http://localhost:8080/fuseframework/uploadfile/upload" method="post" enctype="multipart/form-data">
file: 
<br>
<input type ="file" name="file" multiple="multiple">

<input type="submit" value="send">
</form>
</body>
</html>

These are the jars I've used https://i.sstatic.net/1tVT8.png

Oud answered 9/9, 2014 at 16:15 Comment(0)
R
10

It works OK for me to use the 'FormDataMultiPart'.

Here is the Java code, the FormDataContentDisposition object(formParams) contains actual file content.

List<FormDataBodyPart> parts = formParams.getFields("file");
for (FormDataBodyPart part : parts) {
    FormDataContentDisposition file = part.getFormDataContentDisposition();
}

In the JS side, I use the FormData object and push several files with the same name:

for (var i = 0; i < files.length; i++)
    fd.append('file', files[i]);

Wish it will help

Retinol answered 17/10, 2014 at 7:29 Comment(2)
To get the file content use: InputStream is = bodyPart.getEntityAs(InputStream.class);Towardly
when I try to pass inputStream as argument I get a runtimeexception, it says that "DataHead$ReadMultiStream" is not serializable. any idea?Lisle
J
14

This thing worked for me pretty well:

@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public void uploadMultiple(@FormDataParam("file") FormDataBodyPart body){
    for(BodyPart part : body.getParent().getBodyParts()){
        InputStream is = part.getEntityAs(InputStream.class);
        ContentDisposition meta = part.getContentDisposition();
        doUpload(is, meta);
    }
}
Joslyn answered 6/12, 2015 at 20:32 Comment(0)
R
10

It works OK for me to use the 'FormDataMultiPart'.

Here is the Java code, the FormDataContentDisposition object(formParams) contains actual file content.

List<FormDataBodyPart> parts = formParams.getFields("file");
for (FormDataBodyPart part : parts) {
    FormDataContentDisposition file = part.getFormDataContentDisposition();
}

In the JS side, I use the FormData object and push several files with the same name:

for (var i = 0; i < files.length; i++)
    fd.append('file', files[i]);

Wish it will help

Retinol answered 17/10, 2014 at 7:29 Comment(2)
To get the file content use: InputStream is = bodyPart.getEntityAs(InputStream.class);Towardly
when I try to pass inputStream as argument I get a runtimeexception, it says that "DataHead$ReadMultiStream" is not serializable. any idea?Lisle
B
0

This answer also allows you to add "file" as a @FormDataParam to a @BeanParam class when its type is FormDataBodyPart. FormDataMultiPart will only build as a parameter in the request and will not build when inherited by a subclass.

Buna answered 22/7, 2021 at 16:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.