Miko Jasper
Miko Jasper

Reputation: 27

How to get images from a folder in the server using Jersey WS?

I am learning the Jersey web services, now I understood how GET and POST work :

 @GET
    @Produces("text/html")
    public String getHandler() {
        return "<h1>Get some REST!<h1>";
    }

@POST
@Consumes("application/x-www-form-urlencoded")
@Produces("text/plain")
public String postHandler(String content) {
    return content;
} 

in Jersey Documentation for featching images it said :

@GET
@Path("/images/{image}")
@Produces("image/*")
public Response getImage(@PathParam("image") String image) {
  if (!isSafeToOpenFile(image)) {
    throw new IllegalArgumentException("Cannot open the image file.");
  }

  File f = new File(image);

  if (!f.exists()) {
    throw new WebApplicationException(404);
  }

  String mt = new MimetypesFileTypeMap().getContentType(f);
  return Response.ok(f, mt).build();
}

I would appreciated if you can show me an example using the above code to fetch images from a folder in the server and post them in a html. Thanks lot.

Upvotes: 2

Views: 6492

Answers (2)

Stephane Lallemagne
Stephane Lallemagne

Reputation: 1256

Here is a full example of a live gallery, based on REST services.

REST services (Jersey)

This service gives the content (filenames) of the image server directory (here C:\Temp\hotfolder).

    // array of supported extensions 
    static final String[] EXTENSIONS = new String[] { "jpg", "jpeg", "gif", "png", "bmp" };

    // filter to identify images based on their extensions
    static final FilenameFilter IMAGE_FILTER = new FilenameFilter() {

        @Override
        public boolean accept(final File dir, final String name) {
            for (final String ext : EXTENSIONS) {
                if (name.endsWith("." + ext)) {
                    return (true);
                }
            }
            return (false);
        }
    };

    @GET
    @Path("folderImages")
    @Produces("text/json")
    public Response getFolderImages(@QueryParam("lastknown") String lastknown) 
    {
        //Gets the contents of the folder (reverse order : more recent first)
        //see http://stackoverflow.com/questions/11300847/load-and-display-all-the-images-from-a-folder
        File dir = new File("C:\\Temp\\hotfolder");
        File [] files = dir.listFiles(IMAGE_FILTER); 
        Arrays.sort( files, new Comparator<File>() {
            public int compare(File f1, File f2) {
                if (f1.lastModified() > f2.lastModified()) {
                    return -1;
                } else if (f1.lastModified() < f2.lastModified()) {
                    return +1;
                } else {
                    return 0;
                }
            }
        });
        //Fills a list (from the more recent one, until the last known file)
        ArrayList<String> newfiles = new ArrayList<String>();
        for (File f : files)
        {
            if (lastknown!=null && f.getName().equals(lastknown)) 
                break;
            newfiles.add(f.getName());
        }
        //Answers the list as a JSON array (using google-gson, but could be done manually here)
        return Response.status(Status.OK).entity(new Gson().toJson(newfiles)).type("text/json").build();
    }

Also this is the image service, needed for rendering each image individually.

    @GET
    @Path("/images/{image}")
    @Produces("image/*")
    public Response getImage(@PathParam("image") String image) {
      File f = new File("C:\\Temp\\hotfolder\\" + image);
      if (!f.exists()) {
        throw new WebApplicationException(404);
      }
      String mt = new MimetypesFileTypeMap().getContentType(f);
      return Response.ok(f, mt).build();
    }

gallery.html

Html, with a little help of JQuery. This HTML polls every 5 seconds, asking for service if there is new files (more recent) than the last file known. Et voilà!

You can notice we are using the jquery .prepend method to insert images dynamically at the beginning of the gallery div.

<html>
<head>
  <title>Folder demo</title>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
    <h1>Live gallery</h1>
    <div id="gallery1" style="border:1px solid black;padding:10px;"></div>
    <div id="info1"></div>
<script>
var counter = 0; 
var lastknown = ""; 
function doPoll(){
$.get('rest/folderImages?lastknown='+lastknown, function(data) {
    counter++;
    $("#info1").html("<pre>Counter: " + counter + "<br>New files: " + data + "</pre>");
    for (var i=data.length-1; i>=0; i--) {
        $("#gallery1").prepend("<img src=\"rest/images/" + data[i] + "\" style=\"width:200px;height:200px\" />");
        lastknown = data[i];
    }
    setTimeout(doPoll,5000);
    });
}
$(document).ready( doPoll );
</script>
</body>
</html>

Upvotes: 1

Stephane Lallemagne
Stephane Lallemagne

Reputation: 1256

The Jersey example from documentation is clear enough to me. However, here is a simplified example without parameters (do simple to begin...)

@GET
@Path("/images/pet")
@Produces("image/*")
public Response getImage() {
  File f = new File("C:\\\\Temp\\dog.jpg");
  if (!f.exists()) {
    throw new WebApplicationException(404);
  }
  String mt = new MimetypesFileTypeMap().getContentType(f);
  return Response.ok(f, mt).build();
}

As my Jersey is configured as /rest/* path in the web.xml of the yourapp application, the image is accessible at the following address:

http://serverip:port/yourapp/rest/images/pet

You can try it directly this URL in the browser navigation bar (it is a REST image service, served as if it was a static image), or if you want it in a html page, you can use classic HTML:

<html>
  <body>
    <h1>Woof!</h1>
    <img src="http://localhost:8080/myapp/rest/images/pet" />
  </body>
</html>

Hope it helps.

EDIT

Okay that was too obvious. So you need to implement a method or service that gives the content of a directory with image file names in the given order you need (as a java List).

Using this List, you can build a html like this within a loop:

<html>
  <body>
    <h1>Several images</h1>
    <img src="/yourapp/rest/images/last.jpg" /><br/>
    <img src="/yourapp/rest/images/third.jpg" /><br/>
    <img src="/yourapp/rest/images/second.jpg" /><br/>
    <img src="/yourapp/rest/images/first.jpg" /><br/>
  </body>
</html>

This is the result HTML you must output (in JSP or whatever you use). The REST service getImage() will be called automatically by the browser, once for each image.

Am I clear ?

Upvotes: 1

Related Questions