« - »

The WhoAmI Service: Server Side

4 February 2008

Earlier I laid out the elements of a possible WhoAmI service that could be invoked on the client side to obtain information about the currently authenticated user. Now it’s time to toss out some Java code to produce the output that was envisioned. That will involve a relatively simple Java servlet, but since we will be doing quite a number of similar servlets, I thought I would start with an abstract class that contains some of the foundation code upon which much of this future work will based:

package org.restafarian.core.servlets;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * <p>This is the base class for all of the REST servlets.</p>
 */
public abstract class RestServletBase extends HttpServlet {

 /**
  * <p>The Servlet "service" method.</p>
  *
  * @param req the <code>HttpServletRequest</code> object
  * @param res the <code>HttpServletResponse</code> object
  * @throws ServletException
  * @throws IOException
  */
 public void service(HttpServletRequest req, HttpServletResponse res) throws
       ServletException,  IOException {
  res.setContentType("text/xml");
  String method = req.getMethod();
  if ("get".equalsIgnoreCase(method)) {
   doGet(req, res);
  } else if ("post".equalsIgnoreCase(method)) {
   doPost(req, res);
  } else if ("put".equalsIgnoreCase(method)) {
   doPut(req, res);
  } else if ("delete".equalsIgnoreCase(method)) {
   doDelete(req, res);
  } else {
   res.sendError(405, "Method Not Allowed. The \"" + method.toUpperCase() +
        "\" is not appropriate for this resource.");
  }
 }

 /**
  * <p>The Servlet "doGet()" method.</p>
  *
  * @param req the <code>HttpServletRequest</code> object
  * @param res the <code>HttpServletResponse</code> object
  * @throws ServletException
  * @throws IOException
  */
 public abstract void doGet(HttpServletRequest req, HttpServletResponse res) throws
       ServletException, IOException;

 /**
  * <p>The Servlet "doPost()" method.</p>
  *
  * @param req the <code>HttpServletRequest</code> object
  * @param res the <code>HttpServletResponse</code> object
  * @throws ServletException
  * @throws IOException
  */
 public abstract void doPost(HttpServletRequest req, HttpServletResponse res) throws
       ServletException, IOException;

 /**
  * <p>The Servlet "doPut()" method.</p>
  *
  * @param req the <code>HttpServletRequest</code> object
  * @param res the <code>HttpServletResponse</code> object
  * @throws ServletException
  * @throws IOException
  */
 public abstract void doPut(HttpServletRequest req, HttpServletResponse res) throws
       ServletException, IOException;

 /**
  * <p>The Servlet "doDelete()" method.</p>
  *
  * @param req the <code>HttpServletRequest</code> object
  * @param res the <code>HttpServletResponse</code> object
  * @throws ServletException
  * @throws IOException
  */
 public abstract void doDelete(HttpServletRequest req, HttpServletResponse res) throws
       ServletException, IOException;
}

There is more that we can add to this foundation, but for this exercise, this is all that we will need, so there is no point in confusing the matter with extra properties and methods right at the moment. Basically, this is just a servlet shell right now, with stubs for the four basic REST HTML methods, GET, PUT, POST, and DELETE. Our WhoAmI servlet will extend this abstract class, overriding three of the four methods with error responses, as those methods (PUT, POST, and DELETE) are not appropriate for this service. We only need the GET method for this service, and that is where you will find the majority of the code:

package org.restafarian.id.servlets;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.restafarian.core.servlets.RestServletBase;

/**
 * <p>This servlet returns information about the currenly signed on user.</p>
 */
public class WhoAmIServlet extends RestServletBase {
 private static final long serialVersionUID = 1;

 /**
  * <p>The Servlet "doGet()" method.</p>
  *
  * @param req the <code>HttpServletRequest</code> object
  * @param res the <code>HttpServletResponse</code> object
  * @throws ServletException
  * @throws IOException
  */
 public void doGet(HttpServletRequest req, HttpServletResponse res) throws
       ServletException, IOException {
  StringBuffer buffer = new StringBuffer();

  String userId = OpenIdFilter.getCurrentUser(req.getSession());
  if (userId == null || userId.equals("")) {
   res.sendError(404, "The requested resource was not found on this server.
        If you entered the URL manually please check your spelling and try again.");
  } else {
   buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
   buffer.append("<?xml-stylesheet type=\"text/xsl\" href=\"");
   buffer.append(req.getContextPath());
   buffer.append("/xsl/whoami.xsl\"?>\n");
   buffer.append("<whoami xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n");
   buffer.append("  <remoteAddr>");
   buffer.append(req.getRemoteAddr());
   buffer.append("</remoteAddr>\n");
   buffer.append("  <remoteHost>");
   buffer.append(req.getRemoteHost());
   buffer.append("</remoteHost>\n");
   buffer.append("  <remoteUser id=\"");
   buffer.append(userId);
   buffer.append("\" xlink:href=\"");
   buffer.append(userId);
   buffer.append("\">");
   buffer.append(userId);
   buffer.append("</remoteUser>\n");
   buffer.append("</whoami>");
   PrintWriter pw = res.getWriter();
   pw.print(buffer.toString());
  }
 }

 /**
  * <p>The Servlet "doPost()" method.</p>
  *
  * @param req the <code>HttpServletRequest</code> object
  * @param res the <code>HttpServletResponse</code> object
  * @throws ServletException
  * @throws IOException
  */
 public void doPost(HttpServletRequest req, HttpServletResponse res) throws
       ServletException, IOException {
  res.sendError(405, "Method Not Allowed. Use the \"GET\" method for this URL");
 }

 /**
  * <p>The Servlet "doPut()" method.</p>
  *
  * @param req the <code>HttpServletRequest</code> object
  * @param res the <code>HttpServletResponse</code> object
  * @throws ServletException
  * @throws IOException
  */
 public void doPut(HttpServletRequest req, HttpServletResponse res) throws
       ServletException, IOException {
  res.sendError(405, "Method Not Allowed. Use the \"GET\" method for this URL");
 }

 /**
  * <p>The Servlet "doDelete()" method.</p>
  *
  * @param req the <code>HttpServletRequest</code> object
  * @param res the <code>HttpServletResponse</code> object
  * @throws ServletException
  * @throws IOException
  */
 public void doDelete(HttpServletRequest req, HttpServletResponse res) throws
       ServletException, IOException {
  res.sendError(405, "Method Not Allowed. Use the \"GET\" method for this URL");
 }
}

This particular example assumes that you are using Google’s JOID to secure your web application, and utilizes the getCurrentUser() method of the org.verisign.joid.consumer.OpenIdFilter class to obtain the OpenID of the currently authenticated user. If you were using container-managed authentication, you might use the request.getRemoteUser() method or the request.getUserPrinciple().getName() method to obtain the userId information, coupled with some additional code to go get the user’s URI. If you have an application-based authentication mechanism in place, then you would use your own utilities to go grab the user’s profile information and pull your data from there. This code is just an example; your actual implementation may vary.

But basically, that’s it. You build a simple servlet that responds to a GET request by grabbing the user information from wherever it may be stored and wrapping it in some standard XML boiler plate. That’s about all there is to a WhoAmI service.

Next time, we’ll flip back over to the client side and put together some Javascript to consume this service and do something with it such as put the user’s id on the screen as a link to their URI.


http://blog.restafarian.org/2008/02/the-whoami-service-server-side/

Comments are closed.

Sorry, the comment form is closed at this time.