March 11, 2009

Identifying MIME using mime-util library


Mime-util is a very small, easy-to-use MIME detection library for Java. It can be used for any type of Java application and can detect MIME types from different sources like File, InputStream, URLConnection, byte array etc. Recently 1.3 version of the library was released and had a look at it.


The new release brings in some changes in packages by deprecating eu.medsea.util and bringing in eu.medsea.mimeutil package. The library still has the old package for backward compatibility. The MIME detection is based on the Unix magic mime files which is used by Unix file command. When using the library, it actually tries to access this file for detecting the MIME type. For other platforms, the library uses an internal copy of magic.mime file. This is available in eu.medsea.mimeutil

Working with the library is very simple. I tried out a simple swing application where the user will select a file using JFileChooser and the MIME type is detected and displayed. Assuming that you have got the absolute path of the file, here is my code:



FileInputStream fis = new FileInputStream(dataDisplayLabel.getText());
BufferedInputStream bis = new BufferedInputStream(fis);
MimeUtil mimeUtilObject = new MimeUtil();
log.warn("Support for Mark and Reset: " + fis.markSupported());
log.warn("Support for Mark and Reset: " + bis.markSupported());
log.info("Stream size: " + fis.available());
Collection coll = mimeUtilObject.getMimeTypes(bis);
log.info(coll.size());
Iterator itr = coll.iterator();
while(itr.hasNext()) {
MimeType mt = itr.next();
log.info("Media type: " + mt.getMediaType());
log.info("Sub Type: " + mt.getSubType());
}
One important point to note is that FileInputStream does not support mark and reset methods. For MIME detection, you will have to provide a InputStream that supports mark and reset methods. In this case, I have used BufferedInputStream and it is fed into getMimeTypes method. After detection of MIME type all the methods they return a collection. You will have to iterate this collection and get media type and sub type using separate APIs.

Even though this library will not be frequently used, it can be used for validation of files during upload or transfer. It is not always safe to check the file extension and proceed with your program logic. You can download mime-util library from sourceforge.

March 09, 2009

Multiple file upload using RESTful web service (Jersey)

For a web application, requirements comes in very interesting form. A typical challenging task is building a multiple file upload feature into web application. Regular Techno Paper readers know about "Multiple file upload using Struts" and how popular the solution is. Today, we will look at how to upload multiple files using a RESTful web service.

Let’s state the requirement more clearly. We need to provide the facility to upload multiple files on to the server using a REST web service. Users will have an “Add File” button that will present them with another file selection widget. Adding a new widget is done using the same java script we used in earlier articles. Still then, let’s have a look at the HTML coding first:
<html>
<head>
<script>
var fCount = 3;
function addFileElement() {
fCount++;
var fObject = document.getElementById('fileSection');
var text = 'File:';
var tag='<input type="file" name="fileup'+fCount+'" />';
var brk='<br>'
var o1 = document.createTextNode(text);
var o2 = document.createElement(tag);
var o3 = document.createElement(brk);
fObject.appendChild(o3);
fObject.appendChild(o1);
fObject.appendChild(o2);
fObject.appendChild(o3);
}
</script>
<title>Multiple file upload using JAX-RS</title>
</head>
<body>
<form action="jersey/fileupload" method="POST" enctype="multipart/form-data">
<div id="fileSection" >
File:<input type="file" name="fileup0" /><br>
File:<input type="file" name="fileup1" /><br>
File:<input type="file" name="fileup2" /><br>
</div>
<hr>
<input type="submit" value="Upload All files" />
<input type="button" onclick="addFileElement()" value="Add File"/>
</form>
</body>
</html>
The html code is very simple one with a form having action as the REST service’s URL. Also note that the method is POST and encoding type is multipart form. Form’s encoding type must be set to “multipart/form-data” for a file upload. In this example, initially I have provided three file selection fields in the form. On click of the button, a java script method “addFileElement” is called. The method simply creates a new file element and appends it to the form. You can modify this code to suit your requirements like limiting the number of file to a maximum of 7 files etc. You can also provide a facility to remove selected files. These modifications are left for people who will play with my code.

Building a REST web service is very simple. For this article also I have used the Jersey library. To extract files from the form data, I have used the Apache FileUpload module. Now let’s have a look at our REST resource class file:
@Path("fileupload")
public class FileUploadResource {
@POST
@Produces("text/plain")
public String loadFile(@Context HttpServletRequest request) {
String resultStatus="fail";
String fileRepository="I:\\testRepo\\";
if (ServletFileUpload.isMultipartContent(request)) {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items=null;
try {
items = upload.parseRequest(request);
} catch (FileUploadException e) {
e.printStackTrace();
}
if(items!=null) {
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = iter.next();
if(!item.isFormField() && item.getSize() > 0) {
String fileName = processFileName(item.getName());
try {
item.write(new File(fileRepository+fileName));
} catch (Exception e) {
e.printStackTrace();
}
resultStatus="ok";
}
}
}
}
return resultStatus;
}

private String processFileName(String fileNameInput) {
String fileNameOutput=null;
fileNameOutput = fileNameInput.substring(
fileNameInput.lastIndexOf("\\")+1,fileNameInput.length());
return fileNameOutput;
}
}
Notice that our resource’s access path is defined as: fileupload. This will match the action path specified in our HTML form. Also notice that we are processing HTTP POST method and not GET. To keep things simple, I am just returning a plain text back to the browser saying “ok” or “fail” as a status to the upload process.

loadFile method is the method called on submit of the form.The method has a injected parameter of type HttpServletRequest. This is to get access to the request object when the method is invoked. From the request we identify if the submitted data is a multipart data and then proceed in access the files in the request object using Apache FileUpload. Since the files are accessed as a List item, we can upload n number of files. The files are extracted using the API provided and stored into an appropriate location.

Let me know what you think of this solution. I am sure there are other methods to achieve the same task using REST web service. Your comments are welcome! You can grab the code as Eclipse project here!

You can enhance this code achieve more intersting things like uploading only image,adding constraint of file size, adding other form elements and validations.

March 05, 2009

Jersey Annotations explained!

Jersey uses Java programming language annotations to simplify the development of RESTful web services. Developers decorate a resource class (a POJO) with HTTP-specific annotations to define resources and the actions that can be performed on those resources. Like I promised in the previous post, here we will be explaining about different annotations a developer needs to know when using Jersey.

Jersey provides just about 19 annotations. Lets get started right away…

@Path – Path annotation value is a relative URI path to the resource. A resource class must have this annotation either at the class level or for the methods defined in the resource class. The annotation also provides the facility for embedding variables and creating URI path templates.

@Consumes – This annotation specifies the media types that the methods of a resource class can accept. It’s an optional one and by default, the container assumes that any media type is acceptable. This annotation can be used to filter the requests sent by the client. On receiving request with wrong media type, sever throws an error to the client.

@Produces – This annotation defines the media types that the methods of a resource class can produce. Like @Consumes annotation, this is also optional and by default the container assumes that any media type can be sent back to the client.

Jersey also provides annotations to specify the request methods and supports 5 methods. They are:

@GET – This is request method designator corresponding to HTTP GET method. Any java method annotated with this will process HTTP GET requests.

@POST – This is request method designator corresponding to HTTP POST method. Any java method annotated with this will process HTTP POST requests.

@PUT – This is request method designator corresponding to HTTP PUT method. Any java method annotated with this will process HTTP PUT requests.

@DELETE – This is request method designator corresponding to HTTP DELETE method. Any java method annotated with this will process HTTP DELETE requests.

@HEAD – This is request method designator corresponding to HTTP HEAD method. Any java method annotated with this will process HTTP HEAD requests.

@HttpMethod – This annotation is another way of specifying HTTP request method. The annotation takes a value which can be any of supported HTTP request method.

Example:

HttpMethod(“GET”)
Public String getUserName() {
return username;
}

@DefaultValue – The DefaultValue annotation is used to define default values of request metadata. The annotation is bound to be used along with PathParam, QueryParam, MatrixParam, CookieParam, FormParam, or HeaderParam annotations. The defaultValue is used if corresponding metadata is not available with the request.

@Context – The Context annotation is used to inject information into a variable or method parameter. Using this annotation, you will be able to inject information like Request, URI information etc.

To extract information from URL,request hearders etc, Jersey provide a set of annotations that make extracting data very simple. They are:

@PathParam – The PathParam annotation is used to extract parameters from the resource URL. URI path parameters are extracted from the request URI, and the parameter names correspond to the URI path template variable names specified in the @Path class-level annotation.

@QueyParam – This annotation is used to extract parameters from URL query parameters. It is mostly used in conjunction with HTTP GET method. When using GET method to send data, the parameters and values are encoded into the URL. QueryParam is used to extract these values and assign them to the appropriate variables.

@FormParam – This annotation is used to extract parameters from a form submission. It is used in conjunction with HTTP POST method.

@CookieParam – Like above mentioned parameter extraction annotations, CookieParam is used to extract values form a cookie.

@HeaderParam – This annotation is used to extract parameters from HTTP header.

@MatrixParam – This annotation is used to extract parameters from matrix URI. You can learn more about matrix URI here.

@Provider – This annotation is used to mark the implementation of an extension interface.

@Encoded – This annotation is used to disable automatic decoding of parameter values. Is this annotation on a method will disable decoding for all parameters.

Well that's all about Jersy annotations. I have some important points for you to remember associated with annotations:

  • Method level annotations override a class level annotation.
  • It is possible to define more that one Media type in @Consumes and @Produces annotations.


I will be back really interesting article related building RESTful service next week.Till them enjoy programming :)

March 02, 2009

Building RESTful web service using Jersey

Jersey is an open source reference implementation of JSR-311. The implementation provides support for annotations defined in JSR-311 and other APIs making it easy for developers to build RESTful web service. In this tutorial we will build a simple Hello World web service using Jersey.

Before we code, let’s have a look at basics.

What is a RESTful web service?

Representational state transfer (REST) is a style of software architecture for distributed hypermedia systems. It’s not a standard but makes use of widely accepted standards like HTTP,HTML, XML and URL.

A client application using REST is viewed as state machine. The client references a Web resource using a URL. A representation of the resource called is returned to the client. It can be HTML, XML, plain text etc.

What is Jersey?

Like I earlier - Jersey is the open source JAX-RS (JSR 311) reference implementation for building RESTful web services. Jersey 1.0.2 implements JAX-RS 1.0 and is shipped with GlassFish server. You can download the jars from Jersey site: https://jersey.dev.java.net/

Building our frist RESTful web service

I have kept our first web service as simple as possible. It would just serve a text “Hello World”! You can grab the source code here. I have used ServletContainer to expose the service. This way you will be able to deploy our service in any servlet container.

In REST, a service is called resource. Jersey provides annotation what make developers job easy and quick. Here is our resource (HelloWorldResource.java):
package rest.resource;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("helloworld")
public class HelloWorldResource {

@GET
@Produces("text/plain")
public String getMessage() {
return "Hello World";
}
}
Remove the annotations and you get a simple POJO. So, in short what we are doing here is adding some annotations to a POJO and deploying it as a service. Let me explain the annotation you see in the above code.

@Path defines a relative URI path for accessing the service. What you see is a very simple path. JAX-RS allows you to embed variables in URI making it path templates.

@GET annotation designates the request method. JAX-RS supports @POST, @PUT, @DELETE and @HEAD along with @GET method.

@Produces annotation is used to specify the MIME types for a resource representation that is sent back to the client. In our case, we are returning a plain text.

We will discuss other annotation is the coming tutorials. With this, we have out first service ready. To deploy this in a servlet container we need to configure web.xml to process requests coming to the server. In web.xml file, we declare a serlvet-class with appropriate parameters as shown below:
<servlet>
<servlet-name>Jersey</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>rest.resource</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey</servlet-name>
<url-pattern>/jersey/*</url-pattern>
</servlet-mapping>
Please note that in my servlet-mapping, I have the url-pattern as /jersey/*. This is not the only method to specify REST resources class in web.xml. I will explain other methods in a separate article.You can access our new RESTful service using the URL http://localhost:8080/restweb/jersey/helloworld.