Zach's Blog

Just another WordPress.com weblog

Jersey + Guice + Scala

with 6 comments

At Pongr, our RESTful web services are built using Jersey, Guice and Scala (among many other technologies). Here’s a quick post that shows how to set up an example project that uses all three. By the end we’ll be able to declare Guice bindings in our own custom module and have them injected into Jersey resource classes.

We’ll manage everything with Maven, so first create your pom.xml. I know it looks like a lot, but only has three Jersey dependencies (and one on the Servlet 2.5 API to make things compile). The rest of this junk is mainly configuring plugins for Scala – don’t worry about it. The upshot is that you can a) run this all using mvn jetty:run, and b) can generate an Eclipse project using mvn eclipse:eclipse.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.pongr</groupId>
    <artifactId>jerseyguicescala</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>jerseyguicescala</name>
    <properties>
        <jersey-version>1.1.1-ea</jersey-version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-server</artifactId>
            <version>${jersey-version}</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey.contribs</groupId>
            <artifactId>jersey-guice</artifactId>
            <version>${jersey-version}</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey.contribs</groupId>
            <artifactId>jersey-scala</artifactId>
            <version>${jersey-version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- Run with "mvn jetty:run" -->
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>maven-jetty-plugin</artifactId>
                <version>6.1.19</version>
                <configuration>
                    <contextPath>/</contextPath>
                </configuration>
            </plugin>
            <!-- Begin scala plugins, inspired by: http://scala-tools.org/mvnsites/maven-scala-plugin/usage_java.html -->
            <plugin>
                <groupId>org.scala-tools</groupId>
                <artifactId>maven-scala-plugin</artifactId>
                <executions>
                    <execution>
                        <id>scala-compile-first</id>
                        <phase>process-resources</phase>
                        <goals>
                            <goal>add-source</goal>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>scala-test-compile</id>
                        <phase>process-test-resources</phase>
                        <goals>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <configuration>
                    <sourceIncludes>
                        <sourceInclude>**/*.scala</sourceInclude>
                    </sourceIncludes>
                    <buildcommands>
                        <buildcommand>ch.epfl.lamp.sdt.core.scalabuilder</buildcommand>
                    </buildcommands>
                    <additionalProjectnatures>
                        <!-- This nature gets put after org.eclipse.jdt.core.javanature in .project so Eclipse has a J badge on the project instead of an S -->
                        <projectnature>ch.epfl.lamp.sdt.core.scalanature</projectnature>
                    </additionalProjectnatures>
                    <classpathContainers>
                        <classpathContainer>org.eclipse.jdt.launching.JRE_CONTAINER</classpathContainer>
                        <classpathContainer>ch.epfl.lamp.sdt.launching.SCALA_CONTAINER</classpathContainer>
                    </classpathContainers>
                </configuration>
            </plugin>
            <!-- http://groups.google.com/group/liftweb/browse_thread/thread/3dac7002f9e59546/3918bba2f7a92cd3?pli=1 -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>add-source</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>src/main/scala</source>
                            </sources>
                        </configuration>
                    </execution>
                    <execution>
                        <id>add-test-source</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>add-test-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>src/test/scala</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <!-- End scala plugins -->
        </plugins>
    </build>
</project>

Next up, create the src/main/webapp/WEB-INF/web.xml file. This just registers our special GuiceConfig class that, uh, configures Guice.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd" metadata-complete="false" version="2.5">
    <listener>
        <listener-class>com.pongr.GuiceConfig</listener-class>
    </listener>
    <filter>
        <filter-name>guiceFilter</filter-name>
        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>guiceFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

We’ll create an example Guice module in the src/main/java/com/pongr/ExampleModule.java file. It just binds a message String that we’ll inject into our resource classes later.

package com.pongr;

import com.google.inject.*;
import com.google.inject.name.*;

public class ExampleModule extends AbstractModule
{
    @Override
    protected void configure()
    {
        bindConstant().annotatedWith(Names.named("message")).to("Hello, World!");
    }
}

Next up is src/main/java/com/pongr/GuiceConfig.java where we connect Jersey to Guice. This is where we create the Guice Injector using our ExampleModule and configure any Jersey properties, like the package(s) that contain our resource classes.

package com.pongr;

import java.util.*;

import com.google.inject.*;
import com.google.inject.servlet.*;
import com.sun.jersey.api.core.*;
import com.sun.jersey.guice.spi.container.servlet.*;

public class GuiceConfig extends GuiceServletContextListener
{
    @Override
    protected Injector getInjector()
    {
        final Map<String, String> params = new HashMap<String, String>();
        params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "com.pongr");
        return Guice.createInjector(new ExampleModule(), new ServletModule()
        {
            @Override
            protected void configureServlets()
            {
                serve("/*").with(GuiceContainer.class, params);
            }
        });
    }
}

Now for the fun! This src/main/java/com/pongr/JavaResource.java file gets the message String injected and displays it.

package com.pongr;

import javax.ws.rs.*;
import javax.ws.rs.core.*;

import com.google.inject.*;
import com.google.inject.name.*;

@Path("java")
public class JavaResource
{
    private String message;

    @Inject
    public JavaResource(@Named("message") String message)
    {
        this.message = message;
    }

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String get()
    {
        return "From Java: " + message;
    }
}

And for good measure here’s src/main/scala/com/pongr/ScalaResource.scala. Same as JavaResource, except in Scala. The Guice @Inject and @Named annotations can be a bit tricky for constructor injection, so here’s how it’s done.

package com.pongr

import javax.ws.rs._
import javax.ws.rs.core._

import com.google.inject._
import com.google.inject.name._

@Path("scala")
class ScalaResource @Inject() (@Named("message") message: String) {
  @GET
  @Produces(Array(MediaType.TEXT_PLAIN))
  def get(): String = "From Scala: " + message
}

That’s it! Now just run mvn jetty:run on your command line and hit http://localhost:8080/java and http://localhost:8080/scala in your browser to see these resources in action. As always, you can also visit http://localhost:8080/application.wadl to get an overview of the available resources. Enjoy!

Written by Zach Cox

September 22, 2009 at 10:03 pm

Posted in Java, Scala

Tagged with , , , ,

Dynamically Generating Zip Files in Jersey

with one comment

We often need to pull a large number of rows from a database table, split those rows up into n groups, and write each group out to a separate text file.  These text files are then processed by another application.  Each text file starts with the number of rows in the file on the first line, and then contains each row on its own line after that.  It became a pain to generate these files by hand, so I added a new resource to our Jersey-based web service that would generate all of the files and wrap them all up into a single .zip file.  The processing app also used to be run by hand, but it’s now totally automated, so it obtains the .zip file, unzips it, and processes each individual file.

Here is the resource we ended up with, except for this blog I’m just generating a list of 100 random strings instead of pulling rows from a real database:

import java.io.*;
import java.util.*;
import java.util.zip.*;

import javax.ws.rs.*;

@Path("/files")
public class FilesResource
{
    @GET
    @Produces("application/x-zip-compressed")
    public InputStream getZipFile(@QueryParam("per_file") @DefaultValue("25") final int perFile)
            throws IOException
    {
        //we write to the PipedOutputStream
        //that data is then available in the PipedInputStream which we return
        final PipedOutputStream sink = new PipedOutputStream();
        PipedInputStream source = new PipedInputStream(sink);

        //apparently we need to write to the PipedOutputStream in a separate thread
        Runnable runnable = new Runnable()
        {
            public void run()
            {
                //PrintStream => BufferedOutputStream => ZipOutputStream => PipedOutputStream
                ZipOutputStream zip = new ZipOutputStream(sink);
                PrintStream writer = new PrintStream(new BufferedOutputStream(zip));

                try
                {
                    //break the strings up into multiple files
                    List<String> strings = getStrings();
                    int stringCount = strings.size();
                    int fileCount = (int) Math.ceil((double) stringCount / (double) perFile);
                    for (int file = 0; file < fileCount; file++)
                    {
                        zip.putNextEntry(new ZipEntry("file" + (file + 1) + ".txt"));
                        int first = file * perFile;
                        int last = Math.min((file + 1) * perFile, stringCount);
                        int imagesInFile = last - first;
                        writer.println(imagesInFile);
                        for (int i = first; i < last; i++)
                            writer.println(strings.get(i));
                        writer.flush();
                        zip.closeEntry();
                    }

                    //also include a single file with all strings
                    writer.println(stringCount);
                    zip.putNextEntry(new ZipEntry("file.txt"));
                    for (int i = 0; i < stringCount; i++)
                        writer.println(strings.get(i));
                    writer.flush();
                    zip.closeEntry();
                }
                catch (IOException e)
                {
                }
                writer.flush();
                writer.close();
            }
        };
        Thread writerThread = new Thread(runnable, "FileGenerator");
        writerThread.start();

        return source;
    }

    private List<String> getStrings()
    {
        List<String> strings = new ArrayList<String>();
        for (int i = 0; i < 100; i++)
            strings.add(String.valueOf(Math.random()));
        return strings;
    }
}

The getZipFile() method will be called in response to a GET /files request.  I also registered the .zip URI extension so it will also respond to GET /files.zip.  By default it will split up the strings into groups of 25, but the per_file query parameter can be specified in the request to change that, like GET /files.zip?per_file=50 to split them into groups of 50.

The easiest way to create a .zip file in Java is using ZipOutputStream.  Once you have that created you call its putNextEntry() method to start a new file within the .zip file.  We also wrapped the ZipOutputStream in a PrintStream, and write the contents of the text files by calling println() on the PrintStream (there’s also a BufferedOutputStream in there for good measure).

Jersey is smart enough to read the data from an InputStream and use it as the HTTP response body, so ultimately we need to return an InputStream.  By hooking the ZipOutputStream up to a PipedOutputStream, and then connecting the PipedOutputStream to a PipedInputStream, Jersey can read this all of this zip file data from the PipedInputStream.  It’s best to write-to and read-from these piped streams in different threads so we start a new writing thread and return the PipedInputStream right away.

This ends up working perfectly: the resource at http://site.com/files.zip feels like a static zip file, but is really generated dynamically on every request.  It also can now be accessed overy HTTP from any machine and processed automatically.  If it was really expensive to generate we could cache it and re-generate only when one of the rows in the database changed, but for our purposes it’s a cheap .zip file to generate.

Written by Zach Cox

August 26, 2009 at 7:43 am

Posted in Java

Tagged with ,

iPhone + Gmail = You Need GPush

leave a comment »

GPush is an awesome new iPhone app by Tiverias Apps that notifies you when you receive an email to your Gmail account.  Its first few days were a bit sketchy but it seems to be working great now.  I have Gmail open in Firefox all day and GPush pretty much always notifies me of a new email before I see the little (1) on the Gmail tab.

Entrepreneurs and product managers everywhere should take note of this product.  First off, the problem they tackled meets the three important criteria:

  1. Pervasive: everyone with an iPhone and a Gmail account has to wait for the iPhone to poll Gmail for new emails, every 15 mins, 30 mins, or 1 hour depending on settings (while their friends with BlackBerries get emails instantly)
  2. Urgent: that market has had the problem since the iPhone was originally released
  3. Willing to pay: FWIW I’m part of this market and was more than happy to pay $0.99 for a solution to this problem

Their solution is just about perfect.  It’s incredibly simple: you install the app, give it your Gmail username & password, and that’s it.  And as long as they keep the service working properly it works great: you’re notified instantly when you get a new email to your Gmail address.

I know there have been a lot of unhappy GPush users so far, but it’s only been out for about a week.  I’m willing to cut them some slack at this point, and I’ve seen an incredible improvement over the last few days.  If GPush turns out to be a big fail long-term I’ll be happy to criticize it, but at this point I think Tiverias has done an awesome job!

Written by Zach Cox

August 24, 2009 at 10:10 am

Posted in Uncategorized

Tagged with , , ,

Example of Implicit Conversions, Options, Extractors and Tuples

with one comment

While writing a new web service resource today I had the chance to use some pretty awesome parts of Scala, and wanted to share some of them.  We integrate with Twitter and have a POJO like this TwitterUser class:

package com.pongr.twitter;

public class TwitterUser
{
    private String name;

    public TwitterUser()
    {
        this(null);
    }

    public TwitterUser(String name)
    {
        setName(name);
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }
}

It’s been stripped down to only the relevant property, in this case the user’s full name that they specified on their Twitter account.  This new resource sends back various information about a user to our mobile apps, including their Twitter info.  Since I wrote this new resource in Scala I decided to “scalafy” (scalify?) the TwitterUser class a bit.

First off, one of our users may not have linked to their Twitter account, so the TwitterUser object might be null.  And even if they have, the name we get back from the Twitter API will be null if they haven’t entered a name, or may just be a duplicate of their screen name (like @zcox).  We need to split up the name into valid first and last names, so this seemed like a good place to be using an Option[String] instead of just a String, which is a best practice from the Beginning Scala book.  So the TwitterInfo class ended up looking like this:

package com.pongr.twitter

class TwitterInfo(user: Option[TwitterUser]) {
  val NameRegex = """(.*?)\s+(.*)""".r
  val name = user.flatMap(_.getName match {
    case NameRegex(first, last) => Some((first, last))
    case _ => None
  })
  val firstName = name.map(_._1)
  val lastName = name.map(_._2)
}

object TwitterInfo {
  implicit def twitterUser2TwitterInfo(user: TwitterUser) = new TwitterInfo(if (user == null) None else Some(user))
}

Another thing to note is the use of a regular expression as an extractor to split up the Twitter name into separate first and last names.  I picked up this technique from the Programming in Scala book and I have to say that it makes the code incredibly intuitive.  I also made the name field a tuple to reuse this regular expression extraction: the firstName and lastName fields are then initialized to the first and second parts of it, respectively.

Implicit conversions continue to amaze me so I created the twitterUser2TwitterInfo method that converts a TwitterUser object into a TwitterInfo.  Putting all of this together, we can use this TwitterInfo class to safely obtain the user’s Twitter name:

package com.pongr.twitter

import TwitterInfo._

object App {
  def main(args : Array[String]) : Unit = {
    print(new TwitterUser)
    print(new TwitterUser("asdf"))
    print(new TwitterUser("John Smith"))
  }

  def print(user: TwitterUser) = println(user.lastName.getOrElse("N/A") + ", " + user.firstName.getOrElse("N/A"))
}

The implicit conversion lets us (appear to) call TwitterInfo methods right on the TwitterUser object, and since the firstName and lastName fields are each an Option[String] we can gracefully handle the case where we don’t have the Twitter name.  Running the above test app prints out the following:

N/A, N/A
N/A, N/A
Smith, John

I know this is a pretty simple example, but I thought it was a practical demonstration of some of the techniques that make Scala such a fun language to program with.

Written by Zach Cox

August 20, 2009 at 1:44 pm

Posted in Scala

Tagged with , , ,

Simple JDBC Queries in Scala

with 3 comments

The Beginning Scala book has a great example of using partially applied functions to automatically close JDBC connections. Today I needed to use some complex SQL outside of our ORM and extended this code sample to make it incredibly simple & safe.

The using and bmap methods are from the book; the query and queryEach methods are my creations:

object Control {
  def using[Closeable <: {def close(): Unit}, B](closeable: Closeable)(getB: Closeable => B): B =
    try {
      getB(closeable)
    } finally {
      closeable.close()
    }

  import scala.collection.mutable.ListBuffer

  def bmap[T](test: => Boolean)(block: => T): List[T] = {
    val ret = new ListBuffer[T]
    while(test) ret += block
    ret.toList
  }

  import java.sql._

  /** Executes the SQL and processes the result set using the specified function. */
  def query[B](connection: Connection, sql: String)(process: ResultSet => B): B =
    using (connection) { connection =>
      using (connection.createStatement) { statement =>
        using (statement.executeQuery(sql)) { results =>
          process(results)
        }
      }
    }

  /** Executes the SQL and uses the process function to convert each row into a T. */
  def queryEach[T](connection: Connection, sql: String)(process: ResultSet => T): List[T] =
    query(connection, sql) { results =>
      bmap(results.next) {
        process(results)
      }
    }
}

The using method just ensures that something with a close() method gets closed after it’s used, while bmap collects the results of some function into a list. I found the using method resulted in a fair amount of boilerplate code, so I factored that out into the query method. You just give it a Connection object and an SQL string and it will handle creating the Statement and ResultSet, passing the ResultSet to your custom processing function, and then closing everything safely for you.

The queryEach method also eliminates some common boilerplate. It builds on the query method by using each row in the ResultSet to create some domain object and collecting all of those objects into a list. As the example usage below shows, you just give queryEach your connection and SQL, as well as some simple code to process a single row in the ResultSet:

import com.whatever.Control._
import java.sql._

val conn: Connection = ...
val people = queryEach(conn, "SELECT * FROM person") {rs =>
  new Person(rs.getString("name"), rs.getInt("age"), rs.getBoolean("valid"))
}

I think this results in some very compact and intuitive code. And reusing all of the boilerplate in the Control methods ensures that you don’t forget to close a Statement or ResultSet.

Written by Zach Cox

August 17, 2009 at 3:21 pm

Posted in Scala

Tagged with ,

URI Extensions in Jersey

with one comment

Jersey provides an excellent system for easily supporting multiple representations of resources. You use the @Produces annotation to define which formats a resource method supports:

@GET
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Thing getThing()
{
    Thing thing = ...;
    return thing;
}

In this case clients can obtain the representation of the thing resource in either XML or JSON format (assuming you’ve registered corresponding MessageBodyWriters for the Thing class).  Just by including the @Produces annotation, Jersey handles sending the response back in the proper format and will even send a 415 Unsupported Media Type response automatically if the client requests the resource in an unsupported format.

By default Jersey uses the Accept request header to determine which response format to use.  Setting request headers in client apps can be cumbersome though, so a more convenient approach is to use URI extensions.  So if you want the http://site.com/thing resource as XML you GET http://site.com/thing.xml, or GET http://site.com/thing.json if you want its JSON representation.

To tell Jersey to use URI extensions, you create a cusom PackagesResourceConfig implementation and set up the mappings between extensions and media types:

import java.util.*;
import javax.ws.rs.core.*;
import com.sun.jersey.api.core.*;

/** Registers URI extensions for some common media types.  This lets clients specify the desired
 * response format right in the URI like http://site.com/whatever.xml instead of
 * http://site.com/whatever with an Accept:application/xml header. */
public class UriExtensionsConfig extends PackagesResourceConfig
{
    private Map<String, MediaType> mediaTypeMap;

    public UriExtensionsConfig()
    {
        super();
    }

    public UriExtensionsConfig(Map<String, Object> props)
    {
        super(props);
    }

    public UriExtensionsConfig(String[] paths)
    {
        super(paths);
    }

    @Override
    public Map<String, MediaType> getMediaTypeMappings()
    {
        if (mediaTypeMap == null)
        {
            mediaTypeMap = new HashMap<String, MediaType>();
            mediaTypeMap.put("json", MediaType.APPLICATION_JSON_TYPE);
            mediaTypeMap.put("xml", MediaType.APPLICATION_XML_TYPE);
            mediaTypeMap.put("txt", MediaType.TEXT_PLAIN_TYPE);
            mediaTypeMap.put("html", MediaType.TEXT_HTML_TYPE);
            mediaTypeMap.put("xhtml", MediaType.APPLICATION_XHTML_XML_TYPE);
            MediaType jpeg = new MediaType("image", "jpeg");
            mediaTypeMap.put("jpg", jpeg);
            mediaTypeMap.put("jpeg", jpeg);
            mediaTypeMap.put("zip", new MediaType("application", "x-zip-compressed"));
        }
        return mediaTypeMap;
    }
}

You register the UriExtensionsConfig in web.xml like this:

    <servlet>
        ...
        <init-param>
            <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
            <param-value>com.pongr.rest.config.UriExtensionsConfig</param-value>
        </init-param>
    </servlet>

This provides yet another way to make your web services more user-friendly. Clients can still use the Accept header but can also use standard URI extensions to specify the desired response format.

Written by Zach Cox

August 11, 2009 at 4:40 pm

Posted in Java

Tagged with , , , ,

Same Snippet, Different Designs

leave a comment »

You’re building a web site and the designers send you XHTML templates with essentially the same form on two different pages, but each page uses a slightly different layout. Being the good coder you are, you want to reuse the same submit-handling code on the back-end to prevent code duplication. This is easy to handle using Lift snippets.

The form lets a user add a new restaurant to our restaurant review site. So we create a snippet like this (it just prints the submitted data for now):

import scala.xml._
import net.liftweb.util.Helpers._
import net.liftweb.http._

class CreateRestaurant {
  def render(xhtml: NodeSeq): NodeSeq = {
    var name = ""
    var address = ""
    var phone = ""

    def createRestaurant() = println("Created " + name + ", " + address + ", " + phone)

    bind("form", xhtml, "name" -> SHtml.text(name, name = _),
                        "address" -> SHtml.text(address, address = _),
                        "phone" -> SHtml.text(phone, phone = _),
                        "submit" -> SHtml.submit("Add", createRestaurant))
  }
}

Next we can create two different forms in our XHTML templates and bind them to the same CreateRestaurant snippet. We are free to modify the design inside the snippet, as long as we bind the same form elements in each one.

Here’s the first form template:

  <lift:CreateRestaurant form="POST">
    <h3>Add a new restaurant</h3>
    <table>
      <tr><td>Name</td><td><form:name><input type="text"/></form:name></td></tr>
      <tr><td>Address</td><td><form:address><input type="text"/></form:address></td></tr>
      <tr><td>Phone</td><td><form:phone><input type="text"/></form:phone></td></tr>
      <tr><td></td><td><form:submit><input type="submit"/></form:submit></td></tr>
    </table>
  </lift:CreateRestaurant>

And here’s the second form template:

  <lift:CreateRestaurant form="POST">
    <table>
      <tr>
        <th>Name</th>
        <th>Address</th>
        <th>Phone</th>
        <th></th>
      </tr>
      <tr>
        <td><form:name><input type="text"/></form:name></td>
        <td><form:address><input type="text"/></form:address></td>
        <td><form:phone><input type="text"/></form:phone></td>
        <td><form:submit><input type="submit"/></form:submit></td>
      </tr>
    </table>
  </lift:CreateRestaurant>

Same form, just different layouts: the first has the fields arranged horizontally while the second lays them out vertically. When Lift renders them they both look different but behave exactly the same way on the back-end, because they both reuse the same snippet code.

CreateRestaurant1

CreateRestaurant2

No more need to duplicate back-end form submit handling code!

Written by Zach Cox

August 10, 2009 at 1:31 pm

Posted in Scala

Tagged with , ,

Using Dummy Data in Lift Templates

leave a comment »

One of the awesome features of “view first” web frameworks like Lift and Wicket is that the page templates are stand-alone documents that are viewable without being served by the framework and don’t contain any server-side code.  This makes things much easier for web designers: they can create an XHTML template file using whatever tool they want and then you just sprinkle in some additional elements.  In a Model 2 framework (like Rails or countless others) your templates are rarely viewable right in a web browser: they’re chopped up to pieces and contain lots of logic in Ruby/PHP/Java/whatever.

In the Lift Book and most Lift code samples, the templates aren’t really useful outside of the framework because the Lift elements are all empty.  For example, consider this snippet that displays an account’s balance at a certain time:

<lift:Ledger.balance>
  <ledger:balance/> as of <ledger:time/>
</lift:Ledger.balance>

When this is displayed in a browser right off of the file system, you don’t really see anything meaningful:

template1

Instead, we can put some dummy data into this template to make it display a little more realistic on its own:

<lift:Ledger.balance>
  <ledger:balance>$2500.00</ledger:balance> as of <ledger:time>8 Aug 2009 11:43am</ledger:time>
</lift:Ledger.balance>

template2

Typically, a web designer will give you a file more like this one, to which you will add your own lift tags.  But your lift tags are simply ignored by the browser, so viewing the template right off your file system works fine.

If you don’t have web designers involved in your project there probably is no point in using all of this dummy data in the templates.  But if web designers are building the template files, it’s very useful to include it.

Written by Zach Cox

August 8, 2009 at 11:50 am

Posted in Scala

Tagged with , ,

XHTML Resource Representations in Jersey using StringTemplate

leave a comment »

Most web services these days use XML and/or JSON as representation formats, mainly because they are simple to create and are easily parseable by other apps.  A less commonly used, but extremely useful format is XHTML.  But wait, that’s for displaying web pages right?  It sure is, but it’s also valid XML.  So if you use XHTML as a representation format, your responses are both viewable to a human in a web browser and parseable by a machine.

Being viewable in a browser is a great way to make your web service self-documenting.  If you use XHTML, instead of reading boring documentation about your web service or using curl to get real XML/JSON responses your users can just navigate around your service using their favorite browser.  The pages look nice so it’s easy to see what information is available for each resource, and they can view the page source to see how to parse it.  XHTML makes linking to other resources easy using the <a> element (remember: hypermedia as the engine of application state!).  XHTML also lets you build forms to show how to use other resources: the forms are easily usable by humans and they also show which HTTP method and parameters to use when making requests from your own app.

While you can use a tool like XStream to serialize your Java objects to XML or JSON, using XHTML will generally require hand-crafting the responses.  What you don’t want to do is build up the entire response in Java:

@GET
@Produces(MediaType.APPLICATION_XHTML_XML)
public String getUser()
{
    User user = ...;
    return "<html><body><dl><dt>First name:</dt><dd>" + user.getFirstName() +
        "</dd><dt>Last name:</dt><dd>" + user.getLastName() +
        "</dd><dt>Email:</dt><dd>" + user.getEmail() +
        "</dd></dl></body></html>";
}

That looks terrible and is going to be very hard to maintain.

What you really need to do is use some sort of template engine.  This will let you put the overall response into a plain text file with certain markers where the data will go.  I’ve found StringTemplate to be one of the best template engines.  You can read all about its great virtues on its own site, but the main idea is that there is basically no logic in the view templates.

To refactor the previous example using StringTemplate, we’d first create a User.st file:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  <head>
    <title>User $user.ID$</title>
  </head>
  <body>
    <dl>
      <dt>First name:</dt> <dd id="firstName">$user.firstName$</dd>
      <dt>Last name:</dt> <dd id="lastName">$user.lastName$</dd>
      <dt>Email:</dt> <dd id="email">$user.email$</dd>
    </dl>
  </body>
</html>

This defines the overall structure of our template, providing places where the user data will get inserted.  Anything between the dollar signs is a StringTemplate expression that the engine evaluates.  So $user.firstName$ results in the getFirstName() method being called on our User object.

Then we would bind a User object to the User.st template and render it:

@GET
@Produces(MediaType.APPLICATION_XHTML_XML)
public String getUser()
{
    User user = ...;
    StringTemplateGroup group = new StringTemplateGroup("someGroup");
    StringTemplate template = group.getInstanceOf("path/to/User");
    template.setAttribute("user", user);
    return template.toString();
}

And this is what will get sent back in the response body:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  <head>
    <title>User 1234</title>
  </head>
  <body>
    <dl>
      <dt>First name:</dt> <dd id="firstName">Zach</dd>
      <dt>Last name:</dt> <dd id="lastName">Cox</dd>
      <dt>Email:</dt> <dd id="email">zach@something.com</dd>
    </dl>
  </body>
</html>

As you can see, this is just XHTML and is easily parseable.  To extract the first name, you could use an XPath expression like “//dd[@id='firstName']“.  If you view this response in a browser, it’s very easy to quickly see what information this resource provides:

User Template

We could also include links to other resources (maybe the user has a set of recipes at /user/{username}/recipes) or a simple form to change the user’s info (it would do a POST to /users/{username} and have a hidden _method=PUT field to account for browsers not support the PUT request).

Written by Zach Cox

June 26, 2009 at 11:24 am

Posted in Java

Tagged with , ,

Use Exceptions to Send Error Responses in Jersey

with one comment

Jersey provides several different ways to send back particular HTTP responses.  While your resource methods can all return Response objects, sometimes it’s more natural to return a domain object if everything goes OK and throw exceptions when errors occur.

The WebApplicationException class serves this purpose.  You throw an instance of it in your resource method, Jersey catches it and sends back the corresponding HTTP response.  While it’s perfectly fine to create & throw WebApplicationException objects, it’s a lot more convenient to create your own subclasses of it for commonly-used responses.

401 Unauthorized

If you have an authentication/authorization system in place to protect access to certain resources, you will become very familiar with the 401 response.  Let’s say we have an Authentication interface and an instance of it can be injected into a resource class:

public interface Authentication
{
    public boolean isAuthenticated(String authorization);
}

One of the first things you’d want to do in a protected resource method is check the user’s credentials, and return a 401 response if necessary:

//this gets injected somehow
private Authentication auth;

@GET
public ImportantThing getImportantThing(@HeaderParam(HttpHeaders.AUTHORIZATION) String authorization)
{
    if (!auth.isAuthenticated(authorization))
        throw new UnauthorizedException();

    ImportantThing thing = ...;
    return thing;
}

This code is very simple and gets the point across to other developers: the method is normally supposed to return an ImportantThing, but in the error case where a user is not properly authorized, an exception is thrown.

Here’s what I use for UnauthorizedException:

import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.core.Response.*;

/** Throw this exception to return a 401 Unauthorized response.  The WWW-Authenticate header is
 * set appropriately and a short message is included in the response entity. */
public class UnauthorizedException extends WebApplicationException
{
    private static final long serialVersionUID = 1L;

    public UnauthorizedException()
    {
        this("Please authenticate.", "Name of your web service");
    }

    public UnauthorizedException(String message, String realm)
    {
        super(Response.status(Status.UNAUTHORIZED).header(HttpHeaders.WWW_AUTHENTICATE,
                                                          "Basic realm=\"" + realm + "\"")
                .entity(message).build());
    }
}

409 Conflict

Let’s say in your web service you have a user account resource with URI /users/{username}.  When creating or updating a user by doing a PUT /users/{username} you need to prevent duplicate usernames.  This is a perfect opportunity to return a 409 response.

@PUT
@Path("{username}")
public User createOrUpdateUser(@PathParam("username") String username, @Context UriInfo uriInfo)
{
    if (usernameExists(username))
        throw new ConflictException(uriInfo.getBaseUriBuilder().path("/users/{username}").build(username));

    //create or update the user
    return user;
}

Pretty simple: detect a potential resource conflict and throw an exception.  As a best practice we also include the URI of the conflicting resource in the response.

import java.net.*;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.core.Response.*;

/** Thrown to return a 409 Conflict response with optional Location header and entity. */
public class ConflictException extends WebApplicationException
{
    private static final long serialVersionUID = 1L;

    public ConflictException()
    {
        this(null, null);
    }

    public ConflictException(URI location)
    {
        this(location, null);
    }

    public ConflictException(URI location, Object entity)
    {
        super(Response.status(Status.CONFLICT).location(location).entity(entity).build());
    }
}

400 Bad Request

The 400 response is the generic client-side error response.  I typically use it when there are validation errors in parameters submitted to the web service, when creating or updating a resource.  It’s useful to include the error messages in the response body instead of just sending the 400 response.

Let’s continue the user account example.  When creating/updating a user we need to validate a couple things:

  • Email address is properly formed
  • A name is provided

We’ll perform all of the validations and send back a 400 response if any of them fail:

@PUT
@Path("{username}")
public User createOrUpdateUser(@PathParam("username") String username, @FormParam("email") String email, @FormParam("name") String name, @Context UriInfo uriInfo)
{
    if (usernameExists(username))
        throw new ConflictException(uriInfo.getBaseUriBuilder().path("/users/{username}").build(username));

    List<String> errors = new ArrayList<String>();
    if (invalid(email))
        errors.add(email + " is not a valid email address");
    if (empty(name))
        errors.add(name + " must be provided");
    if (!errors.isEmpty())
        throw new BadRequestException(errors);

    //create or update the user
    return user;
}

Here’s the BadRequestException that I use:

import java.util.*;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.core.Response.*;

/** Thrown to return a 400 Bad Request response with a list of error messages in the body. */
public class BadRequestException extends WebApplicationException
{
    private static final long serialVersionUID = 1L;
    private List<String> errors;

    public BadRequestException(String... errors)
    {
        this(Arrays.asList(errors));
    }

    public BadRequestException(List<String> errors)
    {
        super(Response.status(Status.BAD_REQUEST).type(MediaType.APPLICATION_XHTML_XML)
                .entity(new GenericEntity<List<String>>(errors)
                {}).build());
        this.errors = errors;
    }

    public List<String> getErrors()
    {
        return errors;
    }
}

Notice that the response entity is a GenericEntity<List<String>> and the response format is XHTML. This lets you create your own MessageBodyWriter for a List that gets formatted in nice XHTML.  You can use a class like this to generate a nicely formatted error response body:

@Provider
@Produces(MediaType.APPLICATION_XHTML_XML)
public class ListStringXhtmlWriter implements MessageBodyWriter<List<String>>

Consider the rest of this class an exercise for the reader (or maybe a future post). :)

Written by Zach Cox

June 22, 2009 at 10:33 am

Posted in Java

Tagged with ,