Contents
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