RESTful Java Servlet

For a recent project I found that a RESTful interface would be appropriate. My first inclination was to use Jersey (or one of the JAX-RS implementations available). The environment where this new REST API would deploy is still using Java 1.5. This became a major roadblock when I was found that none of the JAX-RS implementations provide support for the Java 1.5 virtual machine. This is not surprising since it’s few YEARS past EOSL (end of support life) for Java 1.5, but disappointing still the same.

After spending a day or so with the available frameworks, trying to get one of them to work in Java 1.5, I grew nervous that even if I did succeed, that puts my implementation squarely in a non-support region, even on the mailing lists. So I decided to see how close I could come to a simple, reliable RESTful interface using a plain old Java servlet (POJS?).

While I’m disappointed that I’m unable to leverage an existing, mature framework, I was happy with the outcome. Here are the details

HTTP Methods built in

To begin with, the servlet specification defines methods for the HTTP actions: GET, POST, PUT, DELETE, OPTIONS and HEAD.

Each of these methods receives a HttpServletRequest and HttpServletResponse object, which makes it easy to access the payload of the request and construct a response. Manipulation of return headers, payload content, response codes (200, 404, etc.) are all available directly through the HttpServletResponse object.

The only imports required to accomplish this were available in the standard Java environment, which relieved me of the need to worry about interoperability.

1
2
3
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

URI mapping

The next challenge was how to map RESTful URIs on to the methods in my servlet. At first glance, the conventional mapping done in the web.xml file wouldn’t be sufficient. The problem was with the extra parameters that were embedded in the URI. This goes just beyond what the mapping delineates in web.xml.

What I found was that a wildcard mapping and use of HttpServletRequest.getPathInfo() gave me all the information that I needed to complete the mapping. This is what my web.xml file looks like

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<web-app ...>
	<display-name>testrestservlet</display-name>
	<servlet>
		<description></description>
		<display-name>TestRestServlet</display-name>
		<servlet-name>TestRestServlet</servlet-name>
		<servlet-class>com.danielwatrous.testrestservlet.TestRestServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>TestRestServlet</servlet-name>
		<url-pattern>/api/v1/*</url-pattern>
	</servlet-mapping>
</web-app>

The call I mentioned above, getPathInfo(), returns a string with everything that is in place of the asterisk (*) in my url-pattern above. This means that a URI of the form http://server/testrestservlet/api/vi/resource/id would return a string of “/resource/id” when getPathInfo() is called.

Avoid String Handling

I wanted to avoid messy string manipulation or analysis to parse out the details of this resource identification information. This ruled out any string splitting and checking for indexOf or startsWith.

Instead I wanted to be deliberate and reduce the possibility that a mis-mapping would slip through or that a future developer would misunderstand the exact nature of what to expect. For this reason I chose to use regular expressions. This provides a clear pattern of what my URI should look like, and it will be obvious to other developers. It also reduces the chances of a bad URI resulting in an inconsistent result.

I always use Kodos to develop regular expressions. After I got the regular expressions worked out for each class, I created an inner class inside the servlet that would help me map the URI to a specific request and give me access to the parameters embedded in the request URI. Here’s what that inner class looks like.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
  private class RestRequest {
    // Accommodate two requests, one for all resources, another for a specific resource
    private Pattern regExAllPattern = Pattern.compile("/resource");
    private Pattern regExIdPattern = Pattern.compile("/resource/([0-9]*)");
 
    private Integer id;
 
    public RestRequest(String pathInfo) throws ServletException {
      // regex parse pathInfo
      Matcher matcher;
 
      // Check for ID case first, since the All pattern would also match
      matcher = regExIdPattern.matcher(pathInfo);
      if (matcher.find()) {
        id = Integer.parseInt(matcher.group(1));
        return;
      }
 
      matcher = regExAllPattern.matcher(pathInfo);
      if (matcher.find()) return;
 
      throw new ServletException("Invalid URI");
    }
 
    public Integer getId() {
      return id;
    }
 
    public void setId(Integer id) {
      this.id = id;
    }
  }

Now I’m set to override the methods for each of my HTTP actions.

The Servlet

At this point, creating the servlet is trivial. The mapping provides all path (resource) information to the servlet and our inner class is responsible to determining whether the URI makes sense for our application and to make that information available in a sensible way for processing of the request in the action methods. Here’s what I came up with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package com.danielwatrous.testrestservlet;
 
import java.io.IOException;
import java.io.PrintWriter;
 
import java.util.regex.Pattern;
import java.util.regex.Matcher;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class TestRestServlet extends HttpServlet {
 
  private class RestRequest {
    // Accommodate two requests, one for all resources, another for a specific resource
    private Pattern regExAllPattern = Pattern.compile("/resource");
    private Pattern regExIdPattern = Pattern.compile("/resource/([0-9]*)");
 
    private Integer id;
 
    public RestRequest(String pathInfo) throws ServletException {
      // regex parse pathInfo
      Matcher matcher;
 
      // Check for ID case first, since the All pattern would also match
      matcher = regExIdPattern.matcher(pathInfo);
      if (matcher.find()) {
        id = Integer.parseInt(matcher.group(1));
        return;
      }
 
      matcher = regExAllPattern.matcher(pathInfo);
      if (matcher.find()) return;
 
      throw new ServletException("Invalid URI");
    }
 
    public Integer getId() {
      return id;
    }
 
    public void setId(Integer id) {
      this.id = id;
    }
  }
 
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    PrintWriter out = response.getWriter();
 
    out.println("GET request handling");
    out.println(request.getPathInfo());
    out.println(request.getParameterMap());
    try {
      RestRequest resourceValues = new RestRequest(request.getPathInfo());
      out.println(resourceValues.getId());
    } catch (ServletException e) {
      response.setStatus(400);
      response.resetBuffer();
      e.printStackTrace();
      out.println(e.toString());
    }
    out.close();
  }
 
  // implement remaining HTTP actions here
  ... 
 
}

Conclusion

This turned out to be a clear enough way to capture REST like URIs and map those onto a servlet for processing. Regular expressions provide for reliable and clear access to resource details and should be easy for future developers to quickly understand and extend.

In my next article, I’ll show you how I extend this servlet using the Jackson JSON library and a helper object to serialize and deserialize JSON payloads in RESTful requests.

Twitter Digg Delicious Stumbleupon Technorati Facebook Email

About Daniel Watrous

I'm a Software & Electrical Engineer and online entrepreneur.

8 Responses to “RESTful Java Servlet”

  1. Well done. I was hoping there was an easy way to do this using servlets without having to rely on a framework. I like how you can just hand off to another servlet after the routing has been worked out usings the regex’s.
    Thanks for the writeup.

  2. I was using UUIDs so this is what I done to match the ID… thanks great code here

    matcher = regExIdPattern.matcher(pathInfo);
    if (matcher.find()) {
    id = UUID.fromString(pathInfo.substring(1));
    return;
    }

  3. So I am not sure I follow how this is RESTful. You capture a GET request. REST is all about utilizing protocols to indicate actions. For REST you need GET and POST, which are trivial to support in Servlets. What about PUT and DELETE? I came upon this article seeing if there was a way to do REST with java servlets. I still don’t see that.

    Are you simply doing some url parsing to load a resource in response to a GET? If so, I would not call this a RESTful Java Servlet.

    • Hi xgeoff,

      REST supports all the HTTP methods, like GET, POST, PUT, DELETE, HEADER, OPTIONS… If you want to handle any of those, you would use the servlet methods doPost, doPut, doDelete, etc. However, those are a bit beside the point of this post.

      First off, if you’re going to build a REST client in Java, I would start with Jersey, like I mention at the beginning of the post. If, like me, you’re stuck with a Java 5 environment, then you already know that Jersey support only reaches back as far as Java 6, so you have to use a basic servlet and build in the functionality you need.

      The point of this post is to show a clean way of building in URI parsing and request handling.

    • By the way, this article goes a step further and shows you how to handle JSON within the Servlet.

      http://software.danielwatrous.com/restful-java-servlet-serializing-tofrom-json-with-jackson/

  4. Thank you, Daniel! You post helped me a lot!

Trackbacks/Pingbacks

  1. RESTful Java Servlet: Serializing to/from JSON with Jackson | Daniel Watrous on Software Engineering - March 9, 2012

    […] March 9, 2012 0 Comments […]

  2. What is the difference in developing a web application with servlet vs rest api - September 25, 2013

    […] to apply the REST Architecture. You have to look more around this subject, here is some reading: RESTful Java Servlet | Daniel Watrous on Software Engineering Representational state transfer – Wikipedia, the free encyclopedia Regards, Reply […]

Leave a Reply