« - »

Notification Service: REST interface

23 November 2008

After carefully considering all of the possible activities to pursue at this point, I finally decided to move on to something that wasn’t even on my initial list: an example page that illustrates the use of the service. Some time back I had set up the Example project as a place to put sample pages that used the various services that I have been constructing, and that’s just the place to insert a new page that sends out a simple notification using the new service. But in order to do that with just plain HTML and Javascript, I first needed a REST interface to the Notifer, so I have added the SendNotificationServlet to the notify-web project:

package org.restafarian.notify.servlets.impl;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

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

import org.apache.commons.lang.StringUtils;
import org.restafarian.core.servlets.RestServletBase;
import org.restafarian.notify.service.Notifier;

/**
 * <p>This servlet handles NoticeTemplates.</p>
 */
public class SendNotificationServlet extends RestServletBase {
  private static final long serialVersionUID = 1;
  private Notifier notifier;

  /**
   * <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 {
    sendError(req, res, 405, "Method Not Allowed. Only the \"POST\" method is allowed for this
         URL.");
  }

  /**
   * <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 {
    // log request, if enabled
    if (log.isDebugEnabled()) {
      String message = "Processing POST request";
      if (StringUtils.isNotEmpty(req.getQueryString())) {
        message += "; query string=" + req.getQueryString();
      }
      log.debug(message);
    }

    // get required parameters
    String sendTo = req.getParameter("sendTo");
    String templateId = req.getParameter("templateId");
    if (StringUtils.isNotEmpty(sendTo) && StringUtils.isNotEmpty(templateId)) {
      // send notification
      sendNotification(req, res);
    } else {
      // send error
      sendError(req, res, 400, "This request is incomplete. Required parameters \"sendTo\" and/or
           \"templateId\" are missing or invalid.");
    }
  }

  /**
   * <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 {
    sendError(req, res, 405, "Method Not Allowed. Only the \"POST\" method is allowed 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 {
    sendError(req, res, 405, "Method Not Allowed. Only the \"POST\" method is allowed for this
         URL.");
  }

  /**
   * <p>Handles a get request for a single NoticeTemplate.</p>
   *
   * @param req the <code>HttpServletRequest</code> object
   * @param res the <code>HttpServletResponse</code> object
   */
  private void sendNotification(HttpServletRequest req, HttpServletResponse res)
         throws IOException {
    // gather up all of the sendTo addresses
    List sendTo = new ArrayList();
    String[] sendToArray = req.getParameterValues("sendTo");
    for (int i=0; i<sendToArray.length; i++) {
      sendTo.add(sendToArray[i]);
    }
    // get the optional sendFrom address
    String sendFrom = req.getParameter("sendFrom");
    // get the template id
    String templateId = req.getParameter("templateId");
    // send the notification
    notifier.sendNotification(sendFrom, sendTo, null, templateId, req.getParameterMap());
    // send success message back to browser
    PrintWriter pw = res.getWriter();
    if (pw != null && !pw.equals("")) {
      pw.print("<message>Notification sent.</message>");
    } else {
      sendError(req, res, 500, "There was a technical error while attempting to process this
           request. Details of this error have been logged on the server.");
    }
  }

  /**
   * @return the notifier
   */
  public Notifier getNotifier() {
    return notifier;
  }

  /**
   * @param notifier the notifier to set
   */
  public void setNotifier(Notifier notifier) {
    this.notifier = notifier;
  }
}

It’s a relatively simple servlet, actually. It takes only the POST method; all other methods are rejected. In the POST method, we make a quick check for the presence of at least one “sendTo” address and the id of the desired notice template, and then pass the request off to the method that does all of the heavy lifting, rejecting the request if the minimum requirements are not met.

In the sendNotification method, we gather up all of the “sendTo” addresses, grab the optional “sendFrom” address and the template id, and then invoke the Notifier, passing the entire HTTP request parameter map as additional data that can be used to resolve variables in the notice template. That’s it.

The last thing to do, of course, is to send some kind of XML response back to the calling party, so I just put together a simple <message> tag that indicates that all is well.

To make it all work, I had to add this to the web.xml file:

  <servlet>
    <description>SendNotificationServlet</description>
    <display-name>SendNotificationServlet</display-name>
    <servlet-name>sendNotificationServlet</servlet-name>
    <servlet-class>
      org.restafarian.core.servlets.GenericSpringServlet
    </servlet-class>
  </servlet>

  ...

  <servlet-mapping>
    <servlet-name>sendNotificationServlet</servlet-name>
    <url-pattern>/send</url-pattern>
  </servlet-mapping>

… and this to the applicationContext.xml file:

  <bean id="emailCourier" class="org.restafarian.notify.service.impl.EmailCourier">
    <property name="smtpHostName" value="localhost"/>
    <property name="smtpPort" value="25"/>
    <property name="defaultFromAddress" value="no-reply@restafarian.org"/>
  </bean>

  <bean id="messageCourierFactory"
                           class="org.restafarian.notify.service.impl.MessageCourierFactoryImpl">
    <property name="messageCourierMap">
      <map>
        <entry>
          <key>
            <value>email</value>
          </key>
          <ref bean="emailCourier" />
        </entry>
      </map>
    </property>
  </bean>

  <bean id="deliveryService" class="org.restafarian.notify.service.impl.DeliveryServiceImpl">
    <property name="messageCourierFactory" ref="messageCourierFactory"/>
  </bean>

  <bean id="notifier" class="org.restafarian.notify.service.impl.NotifierImpl">
    <property name="noticeTemplateManager" ref="noticeTemplateManager"/>
    <property name="deliveryService" ref="deliveryService"/>
    <property name="defaultTemplateContext" value="global"/>
  </bean>

  <bean name="sendNotificationServlet"
                            class="org.restafarian.notify.servlets.impl.SendNotificationServlet">
    <property name="notifier" ref="notifier"/>
  </bean>

Now that we have that out of the way, I should be able to put together a sample page that POSTs some data to this servlet to send out a little sample notification.


http://blog.restafarian.org/2008/11/notification-service-rest-interface/

Leave a reply

You must be logged in to post a comment.