CXF REST File Upload

CXF REST File Upload explains step by step details of Implementing a REST service for uploading attachment using Apache CXF, Spring and Eclipse

JAX-RS is Java API for RESTful Webservices which is very rely upon Representational State Transfer model, you can view JAX-RS specification 

JAX-RS uses annotations for simplifying the development efforts.

Below you can see an example of How to upload an attachment using CXF JAX-RS(REST based) file upload

Note

If you want to upload using SOAP MTOM, You can follow CXF File Upload With SOAP MTOM

Required Libraries

You need to download

  1. JDK 7
  2. Eclipse 4.2
  3. CXF-2.7.3
  4. Tomcat 7

Following jar must be in classpath

  1. commons-logging-1.1.1.jar
  2. cxf-2.7.3.jar
  3. httpasyncclient-4.0-beta3.jar
  4. httpclient-4.2.1.jar
  5. httpcore-4.2.2.jar
  6. httpcore-nio-4.2.2.jar
  7. neethi-3.0.2.jar
  8. spring-aop-3.0.7.RELEASE.jar
  9. spring-asm-3.0.7.RELEASE.jar
  10. spring-beans-3.0.7.RELEASE.jar
  11. spring-context-3.0.7.RELEASE.jar
  12. spring-core-3.0.7.RELEASE.jar
  13. spring-expression-3.0.7.RELEASE.jar
  14. spring-web-3.0.7.RELEASE.jar
  15. wsdl4j-1.6.2.jar
  16. jaxb-api-2.2.6.jar
  17. jaxb-impl-2.2.6.jar
  18. javax.ws.rs-api-2.0-m10.jar
  19. xmlschema-core-2.0.3.jar
  20. jettison-1.3.3.jar (JSON library)

CXF REST File Upload

I am creating a simple restful service project that used to upload Multipart (MediaType.MULTIPART_FORM_DATA) attachment

Firstly create a Dynamic Web Project (File->New->Dynamic Web Project) named "CXFRestUpload" according to following screenshot

Create CXF Project CXF REST File Upload

Create a Service Interface

Here we are implement the logic, this will defines which methods of restful service, to be invoked by the client

We are using annotations @Consumes(MediaType.MULTIPART_FORM_DATA) in order to upload the CXF Multipart file attachments

package com.student;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import javax.activation.DataHandler;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;

import org.apache.cxf.jaxrs.ext.multipart.Attachment;

public class UploadServiceImpl {

  
@POST
   @Path
("/uploadFile")
  
@Consumes(MediaType.MULTIPART_FORM_DATA)
  
public Response uploadFile(List<Attachment> attachments, @Context HttpServletRequest request) {
     
for (Attachment attachment : attachments) {
        
DataHandler handler = attachment.getDataHandler();
        
try {
           
InputStream stream = handler.getInputStream();
            MultivaluedMap<String, String> map = attachment.getHeaders
();
            System.out.println
("fileName Here" + getFileName(map));
            OutputStream out =
new FileOutputStream(new File("C:/uploads/" + getFileName(map)));

           
int read = 0;
           
byte[] bytes = new byte[1024];
           
while ((read = stream.read(bytes)) != -1) {
              
out.write(bytes, 0, read);
           
}
           
stream.close();
            out.flush
();
            out.close
();
        
} catch (Exception e) {
           
e.printStackTrace();
        
}
      }

     
return Response.ok("file uploaded").build();
  
}

  
private String getFileName(MultivaluedMap<String, String> header) {
     
String[] contentDisposition = header.getFirst("Content-Disposition").split(";");
     
for (String filename : contentDisposition) {
        
if ((filename.trim().startsWith("filename"))) {
           
String[] name = filename.split("=");
            String exactFileName = name
[1].trim().replaceAll("\"", "");
           
return exactFileName;
        
}
      }
     
return "unknown";
  
}
}

Here we are using one example showing with POST method

GET---> Calling this method will not result any changes to the server

POST---> Calling this method will result changes to the server, This have more secure than GET method

@Consumes annotation specifies, the request is coming from the client

you can specify the Mime type as @Consumes("application/xml"), if the request is in xml format

@Produces annotation specifies, the response is going to the client

you can specify the Mime type as @Produces ("application/xml"), if the response need to be in xml format

Create a cxf.xml

CXF is using Spring internally, Finding classes by spring we need to add service implementation beans are added on "jaxrs:serviceBeans".

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:jaxrs="http://cxf.apache.org/jaxrs"
    xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">
    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <jaxrs:server id="base" address="/rest">
        <jaxrs:serviceBeans>
            <ref bean="UploadService" />
        </jaxrs:serviceBeans>
    </jaxrs:server>
    <bean id="UploadService" class="com.student.UploadServiceImpl" />
</beans>

Change web.xml

Change the web.xml file to find CXF servlet and cxf.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/cxf.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>
</web-app>

Publishing CXF Restful Service

Run CXF Restful On Tomcat

Note

You can Find all the deployed JAX-WS/JAX-RS services you need to append 'services' at the end of the URL so URL will become following

http://localhost:8080/CXFRestUpload/services

Deployed REST Web Service Using CXF

CXF Restful Service Running

Note

you can also see CXF REST Upload Client in order to run this restful service









1 Responses to "CXF REST File Upload"
  1. Ramon 2016-10-11 16:33:08.0

Your email address will not be published. Required fields are marked *