Code I/O

A topnotch WordPress.com site


1 Comment

5 Minutes on Adobe Flex – sending XML from Flex to Servlet

Many developers have asked how to take XML, Images and other objects and send it to Servlets … I did some research on the web, it seemed like many wanted to do so, but there were some or the other glitches, and here is an overview on how it can be done …

My use case was to get images for URLs given and save them locally, after a struggle and have a learning curve with Flex, here is what I did, hope this will be useful to others as well.

I found this to be easy, exciting to learn and cool to send a bulk of Images from anywhere to a common store.

The crack to do so is as follows … if there are better ways, please feel free to share with me.
How to use?

loadImage("http://imagecache2.allposters.com/images/pic/ADVG/741~Donald-Duck-Posters.jpg");
// Snippet to get URL as Bitmap
private var _bitmapData:BitmapData;
private var _urlLoader:URLLoader = new URLLoader();
public function loadImage(urlString:String):void
{
if(urlString != null)
{
_urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
_urlLoader.load(new URLRequest(urlString));
_urlLoader.addEventListener(Event.COMPLETE, completeHandler);
}
}
private function completeHandler(event:Event):void
{
var imageData:ByteArray = URLLoader(event.target).data;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleteHandler);
loader.loadBytes(imageData);
}
private function loaderCompleteHandler(event:Event):void
{
_bitmapData = Bitmap(event.target.content).bitmapData;
}

There was a need to turn the image to JPEG Encoded bytes and save as XML, here is what I did …

// Snippet to Save JPEG Bytes as XML
private function onSave():void
{
var fileToSave:File = File.documentsDirectory;
try
{
fileToSave.browseForSave(“Save Image as XML”);
fileToSave.addEventListener(Event.SELECT, fileSelectedForSave);
}
catch (error:Error)
{
trace(“Failed:”, error.message);
}
}

private function fileSelectedForSave(event:Event):void
{
var selectedFile:File = (event.target as File);
var xmlData:XML = new XML(“<EncodedJPEGBytes>” +bitmapToString(_bitmapData) + “</EncodedJPEGBytes>”);
var xmlStr:String = “<?xml version=”1.0″ encoding=”UTF-8″?>”
+ xmlData.toXMLString();
var fs:FileStream = new FileStream();
fs.open(selectedFile, FileMode.WRITE);
fs.writeUTFBytes(xmlStr);
fs.close();
}

private function bitmapToString(bitmapData:BitmapData):String
{
var encodedJPEG:JPEGEncoder = new JPEGEncoder(100);
var baJPEG:ByteArray = encodedJPEG.encode(bitmapData);
var be:Base64Encoder = new Base64Encoder();
be.encodeBytes(baJPEG);
var jpegToString:String = be.flush();
return(jpegToString);
}

Once the file is saved locally as encoded XML String, this can be sent over to a Servlet for processing, this can further be used for something else …

// Snippet upload XML to Servlet
private function onUpload():void
{
var fileToSave:File = File.documentsDirectory;
var xmlFilter:FileFilter = new FileFilter("Select an XML file", "*.xml");
try
{
fileToSave.browseForOpen("Upload JPEG Bytes to Server", [xmlFilter]);
fileToSave.addEventListener(Event.SELECT, doFileUpload);
}
catch (error:Error)
{
trace("Failed:", error.message);
}
}
private function doFileUpload(event:Event):void
{
var selectedFile:File = (event.target as File);
var uploadReq:URLRequest = new URLRequest("http://localhost:8080/JpegXML/FileUploadServlet");
uploadReq.method = "POST";
selectedFile.upload(uploadReq);
}

Now the interesting part … how to receive this data in Servlet?  Here is a code snippet that will help you understand how it can be done.

	public static void uploader(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String imgStoreDir = ServletPreferences.getImageStoragePath() + File.separator + UUID.randomUUID().toString();
		Utility.createNonExistantDirs(imgStoreDir);

		try
		{
			FileItemFactory fileItemFactory = new DiskFileItemFactory();
			ServletFileUpload uploadServlet = new ServletFileUpload(fileItemFactory);

			List<FileItem> fileItems = uploadServlet.parseRequest(request);
			Iterator<FileItem> fileIterator = fileItems.iterator();

			while(fileIterator.hasNext())
			{
				FileItem fileItem = (FileItem)fileIterator.next();

				if(!fileItem.isFormField()) {
					File filePathName = new File(imgStoreDir + File.separator + fileItem.getName());
					logger.debug("uploader: fileStorageDir = " + filePathName.getAbsolutePath());
					fileItem.write(filePathName);

					Utility.extractJPEG(filePathName, fileItem.getName());
				}
			}

			fileItemFactory = null;
			uploadServlet = null;
		}
		catch( Exception e ) {
			logger.error("uploader: Exception during UPLOAD: " + e.getMessage());
		}

		FileUtils.deleteDirectory(new File(imgStoreDir));
	}

After receiving the Images on the servlet, one can parse and decode the file using Base64Decoder, then use JPEGDecoder to decode the bytes to images … I’m still writing this up, I’ll update the blog once that’s done!