In this Jersey 2 file upload example, we will be learning to upload binary files (e.g. PDF files in this example) using Jersey’s multipart form data support. We will learn below required changes to complete the functionality.
Table of Contents 1. Jersey maven multipart dependency 2. Add MultiPartFeature in web.xml 3. Write Jersey Upload REST API 4. Test file upload using HTML Form 5. Test file upload using jersey client
1. Jersey maven multipart dependency
To use multipart features you need to add jersey-media-multipart
module to your pom.xml
file:
<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-multipart</artifactId> <version>2.19</version> </dependency>
2. Add Jersey MultiPartFeature in web.xml
Further, you are required to add MultiPartFeature
in Jersey configuration to let it know that you will use multipart requests. Simplest way is to add support through web.xml
file.
<servlet> <servlet-name>jersey-serlvet</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>com.howtodoinjava.jersey</param-value> </init-param> <init-param> <param-name>jersey.config.server.provider.classnames</param-name> <param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
3. Write Jersey File Upload REST API
Now look at actual REST API for file upload, which will receive and save the file.
@POST @Path("/pdf") @Consumes({MediaType.MULTIPART_FORM_DATA}) public Response uploadPdfFile( @FormDataParam("file") InputStream fileInputStream, @FormDataParam("file") FormDataContentDisposition fileMetaData) throws Exception { String UPLOAD_PATH = "c:/temp/"; try { int read = 0; byte[] bytes = new byte[1024]; OutputStream out = new FileOutputStream(new File(UPLOAD_PATH + fileMetaData.getFileName())); while ((read = fileInputStream.read(bytes)) != -1) { out.write(bytes, 0, read); } out.flush(); out.close(); } catch (IOException e) { throw new WebApplicationException("Error while uploading file. Please try again !!"); } return Response.ok("Data uploaded successfully !!").build(); }
5. Test file upload using HTML Form
Simply create a file ‘fileUpload.html
‘ file in ‘webapp
‘ folder and paste this code.
<html> <body> <h1>File Upload Example - howtodoinjava.com</h1> <form action="rest/upload/pdf" method="post" enctype="multipart/form-data"> <p>Select a file : <input type="file" name="file" size="45" accept=".pdf" /></p> <input type="submit" value="Upload PDF" /> </form> </body> </html>
Now hit the URL : “http://localhost:8080/JerseyDemos/fileUpload.html” and it will display a HTML file control to browse the file. Select any PDF file and click on “Upload PDF” button.
Your file will be uploaded and you will get the message: “Data uploaded successfully !!”
5. Test file upload using jersey client
If you are looking for uploading files using java clients then you can modify below working code as per your need.
Jersey file upload using FormDataMultiPart example.
public static void main(String[] args) throws IOException { final Client client = ClientBuilder.newBuilder().register(MultiPartFeature.class).build(); final FileDataBodyPart filePart = new FileDataBodyPart("file", new File("C:/temp/sample.pdf")); FormDataMultiPart formDataMultiPart = new FormDataMultiPart(); final FormDataMultiPart multipart = (FormDataMultiPart) formDataMultiPart.field("foo", "bar").bodyPart(filePart); final WebTarget target = client.target("http://localhost:8080/JerseyDemos/rest/upload/pdf"); final Response response = target.request().post(Entity.entity(multipart, multipart.getMediaType())); //Use response object to verify upload success formDataMultiPart.close(); multipart.close(); }
Drop me your questions in comments box related to jersey 2 multipart file upload example.
Happy Learning !!
Reference : https://jersey.java.net/documentation/latest/user-guide.html#multipart
Priyanka
My code is exposed to Command Injection error when the code was reviewed/scanned using Code Review plugin.
public Response uploadFile(
@FormDataParam("path") InputStream file2,
@FormDataParam("path") FormDataContentDisposition fileDisposition,
@FormDataParam("body") String body)
When this code was scanned, the Command Injection error points to this line –
@FormDataParam("path") FormDataContentDisposition fileDisposition.
I am using
fileDisposition
to read the file name –String file2Name = fileDisposition.getFileName();
Can someone please help me resolve this?
Ingi
Hello Lokesh,
Would it be hard to create a new example with the same functionality (service and client) where you do not depend on glassfish,
but on another set of implementation ?
best, i
Sam
thanks for the code, I needed a multipart upload jersey code, this works like a charm.
Bhupinder
java.lang.NullPointerException
at org.glassfish.jersey.media.multipart.internal.FormDataParamValueFactoryProvider$FormDataParamValueFactory.provide(FormDataParamValueFactoryProvider.java:282)
at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:81)
while trying to upload a PDF
Boo
When i try to call the API directly with REST client instead of html page, It fails
Greg
Lokesh,
Nice concise tutorial. Unfortunately it didn’t work for me. I am able to select file and click upload and get message “Data uploaded successfully !!” But when I look at the file in C:\temp the file is called “C” and it contains 0 bytes.
Greg
Sayantan Bhadra
Hi Lokesh,
I have been forced to use JAX-RS 1.0 instead of 2.0 due to project’s technical constraint. Is there any alternative for MultiFeature.class in JAX-RS 1.0 as without it I am always getting HTTP 415 error while uploading multiple files along with form fields using rest in my application.
Thanks in advance.
Jason
Fails hard. Throws a 500 error. Same problem as others have mentioned. I ran Maven build, clean, updated, and refreshed the project.
Lokesh Gupta
Can you please share the error stacktrace.
Gene
This app doesn’t work
When I try to upload a .pdf, .png, or .tif file, I get an error. Here is the console output:
INFO: Starting Servlet Engine: Apache Tomcat/8.0.36
Aug 31, 2016 4:47:01 PM org.apache.catalina.util.SessionIdGeneratorBase createSecureRandom
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [210] milliseconds.
Aug 31, 2016 4:47:03 PM org.apache.jasper.servlet.TldScanner scanJars
INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
Aug 31, 2016 4:47:05 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler [“http-nio-8080”]
Aug 31, 2016 4:47:05 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler [“ajp-nio-8009”]
Aug 31, 2016 4:47:05 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 4530 ms
Aug 31, 2016 4:48:05 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [jersey-serlvet] in context with path [/JerseyDemos] threw exception [org.glassfish.jersey.server.ContainerException: java.io.EOFException: Unexpected EOF read on the socket] with root cause
java.io.EOFException: Unexpected EOF read on the socket
at org.apache.coyote.http11 .InternalNioInputBuffer.fill( InternalNioInputBuffer.java:152)
Lokesh Gupta
Can you please try solutions given here and let us know if they work.
Philip
Very nice article Lokesh,
worked fine for me!
really helped me by understanding fileupload with RESTful services.
Keep it up!
Best regards,
Philip
Jainesh
Using the above code I’m uploading WAR file but it is giving the below exception:
Exception in thread “main” javax.ws.rs.ProcessingException: java.io.IOException: Error writing to server
at org.glassfish.jersey.client.HttpUrlConnector.apply(HttpUrlConnector.java:229)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:246)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:667)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:664)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:424)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:664)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:424)
at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:333)
at com.fileupload.rest.FileUploadClient.main(FileUploadClient.java:27)
Caused by: java.io.IOException: Error writing to server
at sun.net.www.protocol.http.HttpURLConnection.writeRequests(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.writeRequests(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at org.glassfish.jersey.client.HttpUrlConnector._apply(HttpUrlConnector.java:321)
at org.glassfish.jersey.client.HttpUrlConnector.apply(HttpUrlConnector.java:227)
… 11 more
Lokesh Gupta
Can you please confirm if you are able to upload other file types such as PDF files?