Friday, March 20, 2015

MAF: Take picture and upload

Problem Description:
In this blog we will see how we can take a picture using MAF and then upload it on server.

Approach:
We will follow below steps
1. Write a REST service: This service will take image-data as input and saves it somewhere in server. Service expects image-data to be a base64 encoded string representation of image.

2. MAF code to take picture and then call REST service: On mobile code we will take picture using device apis and then pass it to REST service as a base64 encoded string.


Implementation

1. Write REST service:
I have already blogged about writing REST services using JAX-RS. We can see http://sanjeev-technology.blogspot.in/2014/09/rest-service-on-weblogic-1034.html and http://sanjeev-technology.blogspot.in/2014/09/rest-adding-json-support-using-jackson.html for more details.
Here is important screenshot of creating REST service to take image-data as string and save it local folder.

   Jersey servlet registration in web.xml: It means we need to put our services in 'com.san.rest.service' folder.

 
    Directory structure:

     PhotoEntity.java

    PhotoService.java




In my code I am trying to put image in my D:\\Temp directory. If you also want to try same think please create same directory.

Now deploy above service on weblogic server. Based on web.xml settings and annotations, URL for service will be http://<server>:<port>/<context>/rest/photos/postImage

2. TEST REST service using Chrome-Extension 'Advanced REST client'
To test this service you can use Chrome-Extension 'Advanced REST client'. Select following values
URL: http://<server>:<port>/<context>/rest/employees/postImage
Method: POST
Payload: imageData={"imageDataB64": "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NeIa78CfFfhvVE1DwXqMl2A5ERScW11CG3D72QpG3ALAgksflAr6TooA+YLD4z/EDwd9m03xDp32jbsfGp20kNy0PC4DcZztb52VjnOc9K7PTf2k9Blt2bVND1K2n3kKlqyTqVwOSzFCDnPGOw5549kvrCz1Ozks7+0gu7WTG+GeMSI2CCMqeDggH8K4+++D/gHULyS6m8OQJI+MiCWSFBgAcIjBR07Dnr1oApwfHH4fTW8Ur61JA7oGaKSzmLISPunahGR04JHoTUn/AAu34ef9DD/5JXH/AMbrDn/Z18GzXEsqXeswI7llijuIyqAn7o3Rk4HTkk+pNR/8M4+D/wDoJa5/3/h/+NUAWL79obwVaXkkEMWq3sa4xPBbqEfIB4DurcdOQOnpzXEan+0prEvlf2T4fsbXGfM+1zPcbumMbdmO/XOcjpjn0ex+BXgG0s44JtLnvZFzmee7kDvkk8hGVeOnAHT15rsNG8KeH/D2w6RotjZSLEIfOhgUSMgxwz43N0BOSckZPNAHzZB4V+KnxTEV1qE12dPncSLLfy+RbgiP5XWEdipwGRCCWPP3jXq/hL4D+GfDtxFeai8mtXaIylLqJRbkk8MIsHkLx8zMM5OAcY9UooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//9k="}

Note: to create payload use form tab in REST client. If you pasted above payload as as raw data then you need to click on 'Encode payload' option.


You will see that a nice photo has been uploaded in your D:\Temp directory.
If you want to test with your image, you can copy image as D:\Temp\MyPhoto.png and run below program to generate base64 encoded string for your image file.

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class PhotoBase64 {
    public static void main(String[] args) throws IOException {
       String dirName="D:\\Temp\\";
       ByteArrayOutputStream baos=new ByteArrayOutputStream(1000);
       File file = new File (dirName, "MyPhoto.png");
       BufferedImage img=ImageIO.read(file);
       ImageIO.write(img, "jpg", baos);
       baos.flush();
         
       String base64String=Base64.encode(baos.toByteArray());
       System.out.println(base64String);
       baos.close();
    }
    
    
}


3. MAF code to take picture and then call REST service:
Now coming to actual MAF code. Approach is
a. Create a REST connection to the service:
               
b. Create a MAF feature with amx page
             
c. Create PhotoBean.java class and register it as a bean


d. Implement bean method to take photo and call REST service
 

e. AMX code to call bean method on button click
<amx:commandButton text="Take Photo" id="cb3" actionListener="#{viewScope.PhotoBean.submitPhoto}"/>


Now keep service running. Generate apk file for your mobile app. Install it on your mobile and click on 'Take photo' button. It will allow you to take photo and same photo will get uploaded into server.


Thats it.

Code can be downloaded from https://github.com/Sanjeev1Chauhan/MAF-Upload-Picture-REST-B64
Follow Doc\readme.txt to deploy application.

4 comments:

Rahul Sharma said...

Hi Sanjeev, can you please share the source code.....

Sanjeev Chauhan said...

Code link https://github.com/Sanjeev1Chauhan/MAF-Upload-Picture-REST-B64

vaibhav said...

Hi Sanjeev,

Really helpful tutorial.
I was wondering if there is a way to access all the pictures in the device gallery and have a selection listener to select few of them and upload them using the service?

Anonymous said...

Dear,
How i can retrieve image from database and show on AMX page.