Friday, June 28, 2013
Monday, February 18, 2013
Jersey Mutipart - Resource that Produces MULTIPART Response and Client code to process it
Handling 'MULTIPART/MIXED' using Jersery Apis.
Jars required:
a. ) jersey-bundle-1.13.jar
b. ) jersey-multipart-1.13.jar
Jersey Client to GET a Multipart Http Request
______________________________________--
Lets build a client equired to GET a Multipart Response. This Response that has two BodyParts.
1. An xml Input : This is the first body part. It is an Xml representation for a JAXB object ,MyEntity E
2. Byte[] array : This array of bytes is the second body part. This byte array is the content of the file produced by a REST resource
So the aim is to create a jersery client and GET a MULTIPART request.
final long resourceId = 1026l;
final String exportUrl = "get Export Resource URL"
final String path = "/" + resourceId ;
Client c = Client.create();
WebResource service = c.resource(exportUrl );
MultiPart multipart = service.path(path).type(MediaType.APPLICATION_XML).header( headerKey, headerValue).get(MultiPart.class);
List
String xmlResponse = bodyParts.get(0).getEntityAs(String.class);
byte[] exportedContent = bodyParts.get(1).getEntityAs(byte[].class);
System.out.println("XML = " + xmlResponse);
System.out.println("\n\n");
System.out.println("ExportedContent : \n");
System.out.println(new String(exportedContent ));
/////////////// The FileExport Resource that would Produce this Multipart Request ///////////////////////
@GET
@Path("{id}")
@Produces("multipart/mixed")
public Response read(@PathParam("id") String resourceId , @Context HttpHeaders headers,
@Context UriInfo uriInfo) // add other @Context arguments if required
{
// process Request and fetch Xml Response Strinrg
String responseStr = getResponseStrForResourceId( reesource Id );
// build Multipart Web Response
MultiPart multipart = buildMultipartResponse(responseStr);
Response response = Response.status(status).header( headerKey, headerValue ) .entity(multipart).type(MultiPartMediaTypes.MULTIPART_MIXED).build();
return response;
}
// build Multipart Data
MultiPart buildMultipartResponse(String xmlResponseStr)
{
MultiPart multiPart = new MultiPart();
multiPart.bodyPart(new BodyPart(xmlResponseStr, MediaType.APPLICATION_XML_TYPE)).bodyPart(
new BodyPart(getAttachmentBytes(), MediaType.APPLICATION_OCTET_STREAM_TYPE));
return multiPart;
}
Jersey Mutipart - Resource that Consumes MULTIPART and Client that POSTs such a request
Handling 'MULTIPART/MIXED' using Jersery Apis.
Jars required:
a. ) jersey-bundle-1.13.jar
b. ) jersey-multipart-1.13.jar
Jersey Client to POST Multipart Http Request
______________________________________--
Lets build a client that requires to POST to a REST resource a multipart request that has two body parts
1. An xml Input : This is the first body part. Let the JAXB object created for this be Represented by MyEntity E
2. Byte[] array : This array of bytes is the second body part. This byte array is the content of the file that needs to imported , along with the above xml input
So the aim is to create a jersery client and post a multipart request.
String fileImporUrl = "URl to the resource that would handle this request"
Client c = Client.create();
WebResource service = c.resource(fileImporUrl );
// Construct a MultiPart with two body parts
// Construct the JAXB object for the Input Xml
MyEntity E = new MyEntity ();
// E.setname( "anbc" );
//E.setId(123 );
.............
..... Build the Entity
// read the file and get bytes to import
byte[] bytesToImport = getBytesToImport();
// Construct Multipart Request. Content-type of the first part is 'application/xml '
// and second part is 'appication/octet-stream'
MultiPart multiPart = new MultiPart().
bodyPart(new BodyPart(E, MediaType.APPLICATION_XML_TYPE)).
bodyPart(new BodyPart(bytesToImport, MediaType.APPLICATION_OCTET_STREAM_TYPE));
// POST the request
ClientResponse response = service.path("/import").
type("multipart/mixed").header( headerKey, headerValue).post(ClientResponse.class, multiPart);
System.out.println( "Import Response status = " + response.getStatus() );
/////////////// A FileImport Resource that would consume this Multipart Request ///////////////////////
@POST
@Consumes("multipart/mixed")
@Produces({ MediaType.APPLICATION_XML, MediaType.TEXT_XML })
public Response importFile(MultiPart multipart, @Context HttpHeaders headers, @Context UriInfo uriInfo) // add other context if required
{
final int INDEX_XML = 0; final int INDEX_FILE_CONTENT = 1; MultipartBodyEntityContent bodyEntityContent = new MultipartBodyEntityContent(); MyEntity E = null; BodyPartEntity fileContentAsBodyPart = null; try { E = multipart.getBodyParts().get(INDEX_XML).getEntityAs(MyEntity.class); fileContentAsBodyPart = (BodyPartEntity) multipart.getBodyParts().get(INDEX_FILE_CONTENT).getEntity(); byte[] byteContent = getByteArrayFromInputStream( fileContentAsBodyPart .getInputStream() );
// Process the MyEntity E and byteContent and return Response }
}
// get byte[] from Input Stream byte[] getByteArrayFromInputStream(InputStream in) { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int nRead; byte[] data = new byte[4096]; while ((nRead = in.read(data, 0, data.length)) != -1) buffer.write(data, 0, nRead); buffer.flush(); buffer.close(); return buffer.toByteArray(); }
Friday, October 26, 2012
Simple Java Program to Write to a Zip File.
This Program takes a Zip file Directory and a Zip file name as Input.
'writeAsZip()' method writes an Array of Bytes as a Zip Entry to the Zip file.
Suppose a zip file 'D:\\test\\cb-1-zip.zip' is has two constituents, namely : 'a.txt' and 'b.png'
This zip File is read and contents stored in a hashMap by 'ZipFileReader'.The size of hashmap is now 2, containing bytes[] of a.txt and b.png
'write()' method takes bytes[] array and name of the file entry to be written to t he Zip file.
Each entry is closed by calling ZipOutputStream#closeEntry() method. Once closeEntry() is called , ZipOutputStream is ready for addition of a new Zip Entry.
Finally ZipOutpurStream#close() method is called. This method finally closes the stream
If the program misses to call 'close()' then a fautly zip file is written to the file system, that is corrupt and perhaps cannot be used. ZipOutpurStream#close() adds the required stream terminating characters.
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipFileWriter {
private String zipDir;
private String zipFilename; // ends in .zip
private static String FS = System.getProperty("file.separator" );
public ZipFileWriter( String zipDir, String zipFilename ) {
this.zipDir = zipDir;
this.zipFilename = zipFilename;
}
/**
}
*
* @return
* @throws IOException
*/
public void writeAsZip( byte[] bytesRead, String fileEntry ) throws IOException {
String absoluteZipFIleName = zipDir + FS + zipFilename;
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(absoluteZipFIleName));
ZipEntry entry = new ZipEntry( fileEntry );
zos.putNextEntry( entry );
zos.write(bytesRead);
zos.closeEntry();
zos.close();
}
public void writeAsText( String filename, byte[] bytesRead ) throws IOException{
FileOutputStream fos = new FileOutputStream( new File( zipDir + FS + filename ));
fos.write( bytesRead );
fos.close();
}
public static void main(String[] args) throws Exception {
String FS = System.getProperty("file.separator" );
String zipDirRead = "D:\\test";
String zipDirWrite = "D:\\test\\out";
String zipFilename = "cb-1-zip.zip";
File zipFile = new File ( zipDirRead + FS + zipFilename );
ZipFileReader reader = new ZipFileReader( zipFile );
Map map = reader.read();
ZipFileWriter writer = new ZipFileWriter(zipDirWrite, zipFilename);
Set set = map.keySet();
Iterator iter = set.iterator();
while ( iter.hasNext() ) {
String key = iter.next();
System.out.println("Writing file Entry :" + key );
byte[] bytesread = map.get(key);
writer.writeAsZip( bytesread, key );
writer.writeAsText( key, bytesread );
}
}
'writeAsZip()' method writes an Array of Bytes as a Zip Entry to the Zip file.
Suppose a zip file 'D:\\test\\cb-1-zip.zip' is has two constituents, namely : 'a.txt' and 'b.png'
This zip File is read and contents stored in a hashMap by 'ZipFileReader'.The size of hashmap is now 2, containing bytes[] of a.txt and b.png
'write()' method takes bytes[] array and name of the file entry to be written to t he Zip file.
Each entry is closed by calling ZipOutputStream#closeEntry() method. Once closeEntry() is called , ZipOutputStream is ready for addition of a new Zip Entry.
Finally ZipOutpurStream#close() method is called. This method finally closes the stream
If the program misses to call 'close()' then a fautly zip file is written to the file system, that is corrupt and perhaps cannot be used. ZipOutpurStream#close() adds the required stream terminating characters.
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipFileWriter {
private String zipDir;
private String zipFilename; // ends in .zip
private static String FS = System.getProperty("file.separator" );
public ZipFileWriter( String zipDir, String zipFilename ) {
this.zipDir = zipDir;
this.zipFilename = zipFilename;
}
/**
}
*
* @return
* @throws IOException
*/
public void writeAsZip( byte[] bytesRead, String fileEntry ) throws IOException {
String absoluteZipFIleName = zipDir + FS + zipFilename;
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(absoluteZipFIleName));
ZipEntry entry = new ZipEntry( fileEntry );
zos.putNextEntry( entry );
zos.write(bytesRead);
zos.closeEntry();
zos.close();
}
public void writeAsText( String filename, byte[] bytesRead ) throws IOException{
FileOutputStream fos = new FileOutputStream( new File( zipDir + FS + filename ));
fos.write( bytesRead );
fos.close();
}
public static void main(String[] args) throws Exception {
String FS = System.getProperty("file.separator" );
String zipDirRead = "D:\\test";
String zipDirWrite = "D:\\test\\out";
String zipFilename = "cb-1-zip.zip";
File zipFile = new File ( zipDirRead + FS + zipFilename );
ZipFileReader reader = new ZipFileReader( zipFile );
Map
ZipFileWriter writer = new ZipFileWriter(zipDirWrite, zipFilename);
Set
Iterator
while ( iter.hasNext() ) {
String key = iter.next();
System.out.println("Writing file Entry :" + key );
byte[] bytesread = map.get(key);
writer.writeAsZip( bytesread, key );
writer.writeAsText( key, bytesread );
}
}
Simple Java Program to Read Zip Files
This program takes a Zip File Name as input ( filename matchin regex '*.zip' )
'read()' method opens a ZipFileInputStream and reads each ZipEntry. A zipEntry is a file constituent of a zipFile. for E.g : if a zipFile name = =myzip.zip contains three files, namely :
file1.txt, file2.png, file.java, then myzip.zip has three ZipEntries.
Bytes contents of each Entry is written to a ByteArrayOutput stream and saved in a HashMap.
ZipInputStream and ByteArrayOutput streams are then closed
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class ZipFileReader {
private File zipFile;
public ZipFileReader( File zipFile ) {
this.zipFile = zipFile;
}
/**
*
* @return
* @throws IOException
*/
public Map
ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile));
Map
byte[] buffer = new byte[4096];
ZipEntry entry = null;
while ((entry = zis.getNextEntry()) != null) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
System.out.println("Extracting: " + entry);
int numBytes;
while ((numBytes = zis.read(buffer, 0, buffer.length)) != -1)
bos.write(buffer, 0, numBytes);
zis.closeEntry();
bos.close();
byteMap.put( entry.getName(), bos.toByteArray() );
}
return byteMap;
}
}
Subscribe to:
Posts (Atom)
