Wednesday, November 28, 2012

Image upload via RESTful web service

During some project I had to write Android client for RESTful web service where between other things, image upload was goal. Server was handled by Zaries http://zaries.wordpress.com/ so it was Lisp on Hunchentoot. I didn’t want to start with two unknowns, implementing problematic multipart/form-data on Android and writing from the scratch Lisp web service, so I started searching for simple Java example of upload RESTful web service. I expected something on NetBeans but closest what I managed to find was Jersey hello world example http://www.mkyong.com/webservices/jax-rs/jersey-hello-world-example/ done using Maven. So, here I am writing user friendly tutorial for user friendly NetBeans for millions of prospective Android developers which are not quite comfortable with Java EE development, yet. Android client will be separate article.
This was done on LinuxMint Maya, IDE is NetBeans 7.2 and deployment target is Tomcat 7.0.27.
We start from New Project dialog where from group Java Web we select Web Application. With exception of Server and Settings where we want to target Apache Tomcat during all other steps we accept defaults. If we downloaded bundle, Glassfish is default target.




Now we want to add RESTful web service. We right click on project icon in left pane and select New -> RESTful Web Services from Patterns ...
Again we accept default values with exception of package name where we type in za.org.droid. Before we start coding we add two libraries, those are Jersey 1.8 and JAX-WS 2.2.6. Inside Projects pane we right click on Libraries folder and select Add Library ...


Now we can delete useless GET and PUT Hello World methods generated by IDE and copy and paste this

@POST
@Path("/images")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response imageUpload(@FormDataParam("image") InputStream hereIsImage, @FormDataParam("image") FormDataContentDisposition hereIsName) {
    String path = System.getenv("HOME")+"/tmp/";
    if(hereIsName.getSize()==0) {
        return Response.status(500).entity("image parameter is missing").build();
    }
    String name = hereIsName.getFileName();
    path += name;

    try {
        OutputStream out = new FileOutputStream(new File(path));
        int read;
        byte[] bytes = new byte[1024];
        while ((read = hereIsImage.read(bytes)) != -1) {
            out.write(bytes, 0, read);
        }
        out.flush();
        out.close();
    } catch (IOException e) {
        return Response.status(500).entity(name + " was not uploaded\n"+e.getMessage()).build();
    }
    return Response.status(200).entity(name + " was uploaded").build();
}


We should create in our $HOME folder tmp folder where images will be saved. We look for image parameter and it will tell us what is image called and also it will contain raw image data. We return response informing client about how successful was upload attempt.
Since we accepted default names for RESTful web service it will have “generic” path assigned, that is important because we use that path to call it.
Only what is left is to do configuration. In WEB-INF folder we create web.xml file and paste the following in:




We can save xml and deploy web application. End-point to call will be http://localhost:8080/WebApplication3/xyz/generic/images, application name WebApplication3 may be different so please change it accordingly. To test upload one can use HttpClient, httpcomponents-client-4.2.1 contains working example. I will add blog about Android client in day or two.

No comments:

Post a Comment