REST based File upload using Apache CXF and Spring


You can find the introductions about RESTFUL services here

Apache CXF is an open source implementation of JAX-WS and JAX-RS.

It originated as the combination of two open-source projects: Celtix developed by IONA Technologies (acquired by Progress Software in 2008) and XFire developed by a team hosted at Codehaus. These two projects were combined by people working together at the Apache Software Foundation. The name CXF derives from combining the “Celtix” and “XFire” project names.

Step 1:
Maven dependency for Apache CXF

          <properties>
          <cxf.version>2.5.0</cxf.version>
          </properties>
           <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>${cxf.version}</version>
        </dependency>

        <dependency>
          <groupId>org.apache.cxf</groupId>
          <artifactId>cxf-rt-frontend-jaxrs</artifactId>
          <version>${cxf.version}</version>
       </dependency>

        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>

Step 2:
Add spring dependency

         <spring.version>3.0.5.RELEASE</spring.version>
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

Step 3:
web.xml configuration of both spring and Apache CXF

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/beans.xml</param-value>
    </context-param>
    <listener>
	<listener-class>
                        org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    <servlet>
		<servlet-name>CXFServlet</servlet-name>
		<display-name>CXF Servlet</display-name>
		<servlet-class>
			org.apache.cxf.transport.servlet.CXFServlet
		</servlet-class>
		<load-on-startup>2</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>CXFServlet</servlet-name>
		<url-pattern>/rest/*</url-pattern>
	</servlet-mapping>

Note:
With this configuration Apache CXF will take over all the URL which starts like //rest

Step 4:
create the REST service to handle upload

import org.apache.cxf.jaxrs.ext.multipart.Attachment;
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 java.io.*;
import java.util.List;


/**
 *  File upload service to upload files using RESTFUL services. 
 *  Author: Ananth Durai
 */

public class FileUploadService {

    @POST
    @Path("/file")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response uploadFile(List<Attachment> attachments,@Context HttpServletRequest request) {
        for(Attachment attr : attachments) {
            DataHandler handler = attr.getDataHandler();
            try {
                InputStream stream = handler.getInputStream();
                MultivaluedMap map = attr.getHeaders();
                OutputStream out = new FileOutputStream(new File(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 finalFileName = name[1].trim().replaceAll("\"", "");
                return finalFileName;
            }
        }
        return "unknown";
    }

}

Step 5:
Registering services as spring bean on beans.xml

 <bean id="uploadserviceclass" class="FileUploadService" />
 <jaxrs:server id="uploadservice" address="/upload">
        <jaxrs:serviceBeans>
            <ref bean="uploadserviceclass" />
        </jaxrs:serviceBeans>
  </jaxrs:server> 

Step 6:
Test jsp client to test the application

<html>
<body>
	<h1>JAX-RS Upload Form</h1>

	<form action="http://<server>/<contextpath>/rest/upload/file" method="post" enctype="multipart/form-data">

	   <p>
		Select a file : <input type="file" name="uploadedFile" size="50" />
	   </p>
	   <p>
	   The Next file : <input type="file" name="uploadedFile2" size="50" />
	   </p>

	   <input type="submit" value="Upload It" />
	</form>

</body>
</html>

Advertisements

6 thoughts on “REST based File upload using Apache CXF and Spring

  1. how can i send base64 encoded string of an image to the restful webservice.can u help with the jax rs annotations and mime type that must be used to consume the string

    • @Override
      public void uploadPhoto(String filePath) {
      String url = “http://yourservice/serviceurl”;
      String output = null;
      PostMethod mPost = new PostMethod(url);
      HttpClient client = new HttpClient();

      try {
      File imageFile = new File(filepath);
      BufferedImage image = ImageIO.read(imageFile);
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      ImageIO.write(image, “jpg”, baos);
      byte[] encodedImage = Base64.encodeBase64(baos.toByteArray());

      String data = ” ”
      + ” ”
      + “” + “image/jpeg” +” ”
      + “” + new String(encodedImage) +” ”
      + “”;

      mPost.setRequestBody(data);
      mPost.setRequestHeader(“Content-Type”, “text/xml”);
      client.executeMethod( mPost );
      output = mPost.getResponseBodyAsString( );
      mPost.releaseConnection( );
      } catch (HttpException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      }
      System.out.println(output);
      }

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s