JQuery File Upload

 

Database Table

CREATE TABLE "TEST_ATTACHMENT" 
(	
	"ID" VARCHAR2(20 BYTE) NOT NULL ENABLE, 
	"ATTACHMENT" BLOB, 
	CONSTRAINT "TEST_ATTACHMENT_PK" PRIMARY KEY ("ID")
);

RESTful Service

* See this post on how to setup RESTful service using JDeveloper

Directory Structure

JDeveloper Libraries and Classpath

* Make sure to include matching versions of jersey-multipart.jar and mimepull.jar

web.xml

<?xml version = '1.0' encoding = 'windows-1252'?>
<web-app 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"
         version="2.5">
  <servlet>
    <servlet-name>jersey</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>jersey</servlet-name>
    <url-pattern>/jersey/*</url-pattern>
  </servlet-mapping>
</web-app>

Jersey RESTful Service Java File

* This is the POJO Java file with Jersey annotation:

package test.att.rs;
 
 
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;
 
import java.io.IOException;
import java.io.InputStream;
 
import java.util.Collections;
import java.util.List;
 
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
 
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
 
import org.apache.commons.io.IOUtils;
 
import test.att.ejb.AttSessionEJB;
import test.att.ejb.TestAttachment;
 
 
@Path("/attRS")
public class AttRS {
    private static String[] whiteList = {".pdf", ".doc"};
    private AttSessionEJB attBean;
    private String mappedName = 
        "FLASApp-TestAttachment-AttSessionEJB#test.att.ejb.AttSessionEJB";
 
    private boolean inWhiteList(String fileName){
        for (String str : whiteList){
            if (fileName.endsWith(str)){
                return true;
            }
        }
        return false;
    }
 
    public AttRS() {
        super();
        Context ctx = null;
        try {
            ctx = getIniCtx();
            attBean = (AttSessionEJB)ctx.lookup(mappedName);
        } catch (NamingException e) {
            throw new RuntimeException(e);
        }
 
    }
 
    @GET
    @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    public List<TestAttachment> listAttachments() {
        System.out.println("listAttachments...");
        List<TestAttachment> all = attBean.getTestAttachmentFindAll();
        //TODO sort list
        Collections.sort(all);
        return all;
    }
 
    @GET
    @Path("{attId}")
    @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    public TestAttachment findById(@PathParam("attId") String id){
        System.out.println("findById: " + id);
        TestAttachment att = attBean.findByPrimaryKey(id);
        att.setAttachment(null);
        return att;
    }
 
    @POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response create(
        @FormDataParam("attId") String id, 
        @FormDataParam("file") InputStream is, 
        @FormDataParam("file") FormDataContentDisposition fileDetails) {
        System.out.println("Adding attachment with id " + id 
                           + " and file name: " + fileDetails.getFileName());
        if (!inWhiteList(fileDetails.getFileName())){
            return Response.status(400).entity("File type not supported.").build();
        }
        TestAttachment att = new TestAttachment();
        att.setId(id);
        try {
            byte[] ba = IOUtils.toByteArray(is);
            System.out.println("InputStream size: " + ba.length);
            att.setAttachment(ba);
            att.setFileName(fileDetails.getFileName());
        } catch (IOException e) {
            System.err.println(e.getMessage());
            return Response.status(400).entity("Error saving file").build();
        }
        attBean.persistTestAttachment(att);
        return Response.status(200).entity("OK").build();
    }
 
    @GET
    @Path("/downloadFile")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response downloadFile(@QueryParam(value = "attId") String id){
        TestAttachment att = attBean.findByPrimaryKey(id);
        System.out.println("Attachment size: " + att.getAttachment().length);
        String fn = att.getId();
        if (att != null && att.getFileName() != null){
            fn = att.getFileName();
        }
        return Response
            .ok(att.getAttachment(), MediaType.APPLICATION_OCTET_STREAM)
            .header("content-disposition", "attachment; filename = " + att.getFileName()).build();
    }
 
    private static Context getIniCtx() throws NamingException {
        return new InitialContext();
    }
 
}

jQuery Script

* Download into js folder (see previous directory structure)
jquery-1.8.3.js
jquery.form.js
purl.js
* jQuery script:

 
var rootURL = "http://127.0.0.1:7101/FLASApp-TestAttachment-context-root/jersey/attRS";
var currentAtt;
 
/**
 * Find all attachments
 */
function findAll() {
    console.log("findAll...");
    $.ajax( {
        type : 'GET', 
        url : rootURL, 
        dataType : "json",
        success : renderList
    });
}
 
/**
 * Find attachment by Id
 */
function findById(){
    var id = $.url().param('attId');
    console.log("findById: " + id);
    $.ajax( {
        type : 'GET', 
        url : rootURL + '/' + id, 
        dataType : "json",
        success : function(data){
            console.log("findById success");
            currentAtt = data;
            renderDetails(currentAtt);
        },
        error : function (jqXHR, textStatus, errorThrown) {
            console.log('findById error: ' + textStatus + errorThrown);
            alert('findById error: ' + textStatus + errorThrown);
        }
    });
}
 
/**
 * Render attachment details
 * @param att 
 */
function renderDetails(att){
    console.log("renderDetails...");
    $('#attId').empty();
    $('#attId').append(att.id);
    $('#fileName').empty();
    $('#fileName').append(downloadUrl(att));
}
 
/**
 * Render a list of all attachments
 * @param data 
 */
function renderList(data) {
    console.log("renderList...");
    // JAX-RS serializes an empty list as null, and a 'collection of one' as an object (not an 'array of one')
    var list = data == null ? [] : (data instanceof Array ? data : [data]);
 
    $('#attList li').remove();
    $.each(list, function (index, att) {
        var attUrl = rootURL + '/downloadFile?attId=' + att.id;
        var item = '<li><a href="p2.html?attId=' + att.id + '">' + att.id + '</a>';
        if (att.fileName){
            item += '    ' + downloadUrl(att);
        }
        item += '</li>';
        $('#attList').append(item);
    });
}
 
/**
 * Build a file download URL
 */
function downloadUrl(att) {
    var attUrl = rootURL + '/downloadFile?attId=' + att.id;
    var dlurl;
    if (att.fileName){
        dlurl = '<a href="' + attUrl + '">' + att.fileName + '</a>';
    }
    return dlurl;
}
 
/**
 * Upload an attachment
 * Requires IE 10 and above since IE 9 and below do not support
 * file API and FormData.
 */
function uploadAttachment() {
    console.log('uploadAttachment...');
    var attId = $('#attId').val();
    var file = $('#file').get(0).files[0];
    var formData = new FormData();
    formData.append('attId', attId);
    formData.append('file', file);
    console.log('file size: ' + file.size);
    $.ajax( {
        type : 'POST', 
        url : rootURL, 
        data : formData, 
        processData : false, 
        contentType : false, 
        success : function (data, textStatus, jqXHR) {
            console.log("File uploaded successfully.");
            findAll();
        },
        error : function (jqXHR, textStatus, errorThrown) {
            console.log('uploadAttachment error: ' + textStatus + errorThrown);
            alert('uploadAttachment error: ' + textStatus + errorThrown);
        }
    });
}
 
/**
 * Upload an attachment using jQuery Form Plugin
 * which supports ajax file upload for IE9 and below
 */
function uploadAttachmentWithJQueryForm() {
    console.log('uploadAttachmentWithJQueryForm...');
    var options = {
        type : 'POST', 
        url : rootURL, 
        success : function (data, textStatus, jqXHR) {
            console.log("File uploaded successfully.");
            findAll();
        },
        error : function (jqXHR, textStatus, errorThrown) {
            console.log('uploadAttachment error: ' + textStatus + errorThrown);
            alert('uploadAttachment error: ' + textStatus + errorThrown);
        }
    };
 
    $('#attForm').ajaxSubmit(options);
}

Test HTML Page

Upload Page

* This is the test html page (p1.html) used to upload file:

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"></meta>
    </head>
    <body>
 
        <ul id="attList"></ul>
 
        <form id="attForm" name="attForm" enctype="multipart/form-data" method="POST">
            ID: <input type="text" name="attId" id="attId"/>
            <br/>
            Attachment: <input type="file" id="file" name="file" size="30"/>
            <br/>
            <input type="submit" id="btnSave" name="btnSave" value="Submit"/>
        </form>
 
        <script src="js/jquery-1.8.3.js" type="text/javascript"></script>
        <script src="js/jquery.form.js" type="text/javascript"></script>
        <script src="js/att.js" type="text/javascript"></script>
        <script type="text/javascript">
            $(document).ready(function (){
                $('#attForm').submit(function(){
                    //uploadAttachment(); // Upload attachment with FileAPI and FormData. Need IE10.
                    uploadAttachmentWithJQueryForm(); // Upload attachment with jQuery Form plugin.
                    return false;
                });
                findAll();
            });
        </script>
    </body>
</html>

Download Page

* This is the download test page:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Attachment Details</title>
    </head>
    <body>
 
        ID: <label id="id">ID</label><br/>
        File Name: <label id="fileName">fileName</label><br/>
 
        <script src="js/jquery-1.8.3.js" type="text/javascript"></script>
        <script src="js/purl.js" type="text/javascript"></script>
        <script src="js/att.js" type="text/javascript"></script>
        <script type="text/javascript">findById();</script>
    </body>
</html>

* Test download URL: http://127.0.0.1:7101/FLASApp-TestAttachment-context-root/p2.html?attId=15

References

* RESTful services with jQuery and Java using JAX-RS and Jersey
* 6 Nice jQuery File Upload Plugins
* post
* post
* Jersey File Upload Example
* jQuery Form Plugin

This entry was posted in jquery and tagged , , , . Bookmark the permalink.

Leave a Reply

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


*

This site uses Akismet to reduce spam. Learn how your comment data is processed.