Upload files using RESTful Webservice
Apache CXF provides three different approach for uploading a file. MultipartBody, Attachment and File. In this post, we will be using MultipartBody object for uploading the image. We will also learn how to store an image in database and retrieve it back.
The whole request from the HTML form is represented by MultipartBody object. MultipartBody contains method like getAllAttachments(), getRootAttachment() etc. to fetch the attachment and process it further for extracting the data.
To acheive multipart body upload , we will annotate our rest method with @Consumes(MediaType.MULTIPART_FORM_DATA), which indicates that this method will accept multipart data.
@Consumes(MediaType.MULTIPART_FORM_DATA) @Path("uploadImage") public Response uploadImage(@Multipart("file") MultipartBody p_attachment);
Note that we are using MultipartBody as parameter type which represents whole html form. So final REST interface will look like ;
UploadImageRest.java
package com.sarf.restservice; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.apache.cxf.jaxrs.ext.multipart.Multipart; import org.apache.cxf.jaxrs.ext.multipart.MultipartBody; @Path("/uploadimage-service/") @Produces(MediaType.APPLICATION_JSON) public interface UploadImageRest { @POST @Consumes(MediaType.MULTIPART_FORM_DATA) @Path("uploadImage") public Response uploadImage(@Multipart("file") MultipartBody p_attachment); }
We need to provide implementation class of for our rest interface. So in uploadImage() method, we are using MultipartBody object to extract the attachment in form of InputStream using method getRootAttachment().
Note: We assume here that html form is uploading only one file input.
UploadImageRestImpl.java
package com.sarf.restservice; import java.net.URI; import java.util.UUID; import javax.ws.rs.core.Response; import org.apache.cxf.jaxrs.ext.multipart.MultipartBody; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.sarf.dto.ImageEntityDTO; import com.sarf.service.UploadImageService; @Service public class UploadImageRestImpl implements UploadImageRest { @Autowired private UploadImageService uploadImageService; public Response uploadImage(final MultipartBody multipart) { try { this.uploadImageService.uploadImage( multipart.getRootAttachment() .getDataHandler().getInputStream()); return Response.ok(ResponseType.SUCCESS).build(); }catch(final Exception e) { e.printStackTrace(); return Response.ok(ResponseType.SERVER_ERROR).build(); } } }
To store image in to database, we are going to write service class and spring data JPA Repository as DAO. Spring data Jpa is explained in my previous post as "Spring data JPA".
As mentioned in below image, we will create a service class "UploadImageService" which will internally use Repository class "ImageEntityRepository" to persist image into database.
Before we start writing the code, we need to create table for storing the image object.
Here we got entity class
ImageEntity.java
package com.sarf.domain; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Lob; import javax.persistence.Table; @Entity @Table(name = "ImageEntity") public class ImageEntity implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "imageId") private int nImageId; @Lob @Column(name = "image") private byte[] image; public int getnImageId() { return nImageId; } public void setnImageId(final int p_nImageId) { nImageId = p_nImageId; } public byte[] getImage() { return image; } public void setImage(final byte[] p_image) { image = p_image; } }UploadImageService.java
package com.sarf.service; import java.io.InputStream; import com.sarf.dto.ImageEntityDTO; public interface UploadImageService { public void uploadImage(InputStream image); }
UploadImageServiceImpl.java
package com.sarf.service; import java.io.InputStream; import java.util.List; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.InputStream; import javax.imageio.ImageIO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.sarf.domain.ImageEntity; import com.sarf.dto.ImageEntityDTO; import com.sarf.repository.ImageEntityRepository; import com.sarf.util.MapperUtil; import com.sarf.util.UploadUtil; @Service("uploadImageService") @Transactional public class UploadImageServiceImpl implements UploadImageService { @Autowired ImageEntityRepository imageEntityRepository; /** {@inheritDoc} */ public void uploadImage(final InputStream iSImage) { final ImageEntity e = new ImageEntity(); final byte[] image = getImageByteArray(iSImage); e.setImage(image); this.imageEntityRepository.saveAndFlush(e); } /** This method is used to conver an InputStream into byte array */ private byte[] getImageByteArray(final InputStream inputStream) { byte images[] = null; try{ final BufferedImage image = ImageIO.read(inputStream); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(image, "jpeg", baos); images = baos.toByteArray(); }catch (final Exception e) { e.printStackTrace(); } return images; } }
This is our Entity class used to persist image into database using hibernate.
ImageEntityRepository.java
package com.sarf.repository; import java.util.List; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; import com.sarf.domain.ImageEntity; @Repository public interface ImageEntityRepository extends JpaRepository<ImageEntity, Integer> { }
persistence.xml
appContext.xml
web.xml
index.jsp
<< Home