A Sinatra inspired micro web framework for quickly creating web applications in Java with minimal effort

Getting started

Download the spark lib and its dependencies (Or, let maven do all that for you). Put in your classpath. Start coding:
            
import static spark.Spark.*;
import spark.*;

public class HelloWorld {

   public static void main(String[] args) {
      
      get(new Route("/hello") {
         @Override
         public Object handle(Request request, Response response) {
            return "Hello World!";
         }
      });

   }

}

Ignite and view at:
http://localhost:4567/hello

Routes

The main building block of a Spark application is a set of routes. A route is made up of three simple pieces:
  • A verb (get, post, put, delete, head, trace, connect, options)
  • A path (/hello, /users/:name)
  • A callback ( handle(Request request, Response response) )

NOTE! Routes are matched in the order they are defined. The first route that matches the request is invoked.


 ....
      
 get(new Route("/") {
    @Override
    public Object handle(Request request, Response response) {
       // .. Show something ..
    }
 });
       
 post(new Route("/") {
    @Override
    public Object handle(Request request, Response response) {
       // .. Create something .. 
    }
 });
       
 put(new Route("/") {
    @Override
    public Object handle(Request request, Response response) {
       // .. Update something ..
    }
 });
       
 delete(new Route("/") {
    @Override
    public Object handle(Request request, Response response) {
       // .. annihilate something ..
    }
 });
       
 options(new Route("/") {
    @Override
    public Object handle(Request request, Response response) {
       // .. appease something ..
    }
 });
       
 ....


Route patterns may include named parameters, accessible via the params method on the request object:

 // matches "GET /hello/foo" and "GET /hello/bar"
 // request.params(":name") is 'foo' or 'bar'
 get(new Route("/hello/:name") {
    @Override
    public Object handle(Request request, Response response) {
       return "Hello: " + request.params(":name");
    }
 });       

Route patterns may also include splat (or wildcard) parameters, accessible via the splat method on the request object:

 // matches "GET /say/hello/to/world"
 // request.splat()[0] is 'hello' and request.splat()[1] 'world'
 get(new Route("/say/*/to/*") {
    @Override
    public Object handle(Request request, Response response) {
       return "Nbr of splat parameters: " + request.splat().length;
    }
 });       

Request

In the handle method request information and functionality is provided by the request parameter:

 ....
 request.body();               // request body sent by the client
 request.cookies();            // request cookies sent by the client
 request.contentLength();      // length of request body
 request.contentType();        // content type of request.body
 request.headers();            // the HTTP header list
 request.headers("BAR");       // value of BAR header
 request.attributes();         // the attributes list
 request.attribute("foo");     // value of foo attribute
 request.attribute("A", "V");  // sets value of attribute A to V
 request.host();               // "example.com"
 request.ip();                 // client IP address
 request.pathInfo();           // the path info
 request.params("foo");        // value of foo path parameter
 request.params();             // map with all parameters
 request.port();               // the server port
 request.queryMap();           // the query map
 request.queryMap("foo");      // query map for a certain parameter
 request.queryParams("FOO");   // value of FOO query param
 request.queryParams();        // the query param list
 request.raw();                // raw request handed in by Jetty
 request.requestMethod();      // The HTTP method (GET, ..etc)
 request.scheme();             // "http"
 request.session();            // session management
 request.splat();              // splat (*) parameters
 request.url();                // "http://example.com/foo"
 request.userAgent();          // user agent
 ....

Query maps

Query maps allows you to group parameters to a map by their prefix. This allows you to group two parameters like user[name] and user[age] to a user map.

request.queryMap().get("user", "name").value();
request.queryMap().get("user").get("name").value();
request.queryMap("user").get("age").integerValue();
request.queryMap("user").toMap();

Response

In the handle method response information and functionality is provided by the response parameter:

 ....
 response.body("Hello");        // sets content to Hello
 response.header("FOO", "bar"); // sets header FOO with value bar
 response.raw();                // raw response handed in by Jetty
 response.redirect("/example"); // browser redirect to /example
 response.status(401);          // set status code to 401
 response.type("text/xml");     // set content type to text/xml
 ....

Stopping the server

By calling the stop() method the server is stopped and all routes are cleared.

Cookies

Handling cookies can be done via spark request and response objects.

 ....
 request.cookies();     // get map of all request cookies 
 request.cookie("foo"); // access request cookie by name
 ....
 response.cookie("foo", "bar");       // set cookie with a value
 response.cookie("foo", "bar", 3600); // set cookie with a max-age
 response.cookie("foo", "bar", 3600, true); // secure cookie
 response.removeCookie("foo");        // remove cookie
 ....

Session management

Every request has access to the session created on the server side, provided with the following methods:

 ....
 request.session(true)                            // create (if not created) and return session
 request.session().attribute("user")              // Get session attribute 'user'
 request.session().attribute("user", "foo")       // Set session attribute 'user'
 request.session().removeAttribute("user", "foo") // Remove session attribute 'user'
 request.session().attributes()                   // Get all session attributes
 request.session().id()                           // Get session id
 request.session().isNew()                        // Check is session is new
 request.session().raw()                          // Return servlet object
 ....

Halting

To immediately stop a request within a filter or route use:

 halt();

You can also specify the status when halting:

 halt(401);

Or the body:

 halt("This is the body");

Or both:

 halt(401, "Go Away!");

Filters

Before filters are evaluated before each request and can read the request and read/modify the response. To stop execution, use halt:

 before(new Filter() { // matches all routes
    @Override
    public void handle(Request request, Response response) {
    	boolean authenticated;
    	// ... check if authenticated
    	if (!authenticated) {
            halt(401, "You are not welcome here");
    	}
    }
 });

After filters are evaluated after each request and can read the request and read/modify the response:

 after(new Filter() {
    @Override
    public void handle(Request request, Response response) {
    	response.header("foo", "set by after filter");
    }
 });

Filters optionally take a pattern, causing them to be evaluated only if the request path matches that pattern:

 before(new Filter("/protected/*") {
    @Override
    public void handle(Request request, Response response) {
       // ... check if authenticated
       halt(401, "Go Away!");
    }
 });

Browser Redirect

You can trigger a browser redirect with the redirect helper method:

 response.redirect("/bar");

You can also trigger a browser redirect with specific http 3XX status code:

 response.redirect("/bar", 301); // moved permanently

Static files

Assign a folder in the classpath serving static files with the staticFileLocation method.

 staticFileLocation("/public"); // Static files 
Note that the public directory name is not included in the URL. A file /public/css/style.css is made available as http://<host>:<port>/css/style.css

You can also assign an external folder (not in the classpath) serving static files with the externalStaticFileLocation method.

 externalStaticFileLocation("/var/www/public"); // Static files 

ResponseTransformerRoute

Routes that transforms the output from the handle method. This is done by extending the ResponseTransformerRoute.
Example Of a ResponseTransformerRoute transforming output to JSON using Gson:

 import com.google.gson.Gson;

 public abstract class JsonTransformerRoute extends ResponseTransformerRoute {

    private Gson gson = new Gson();
	
    protected JsonTransformer(String path) {
       super(path, "application/json");
    }
	
    @Override
    public String render(Object model) {
	   return gson.toJson(model);
    }
  
 }
 

and how it is used (MyMessage is a bean with one member 'message'):

 get(new JsonTransformer("/hello") {
    @Override
    public Object handle(Request request, Response response) {
       return new MyMessage("Hello World");
    }
 });

Views / Templates - TemplateViewRoute

A TemplateViewRoute is built up by a path (for url-matching) and the implementation of the 'render' method. Instead of returning the result of calling toString() as body the TemplateViewRoute returns the result of calling render method.

The primary purpose of this kind of Route is to provide a way to create generic and reusable components for rendering output using a Template Engine.

Available TemplateViewRoute implementations:

-- FreeMarker


Renders objects to HTML using Freemarker template engine.

Maven dependency:
<dependency>
      <groupId>com.sparkjava</groupId>
      <artifactId>spark-template-freemarker</artifactId>
      <version>1.0</version>
</dependency>


-- Apache Velocity


Renders objects to HTML using the Apache Velocity template engine.

Maven dependency:
<dependency>
      <groupId>com.sparkjava</groupId>
      <artifactId>spark-template-velocity</artifactId>
      <version>1.0</version>
</dependency>

Port

By default, Spark runs on port 4567. If you want to set another port use setPort. This has to be done before using routes and filters:

 setPort(9090); // Spark will run on port 9090

Embedded Web Server

Standalone Spark runs on an embedded Jetty web server.

Running Spark on a Web Server, e.g. Tomcat

To run Spark on a web server instead of standalone first of all an implementation of the interface spark.servlet.SparkApplication is needed. In the init() method the routes should be initialized. In your web.xml the following filter needs to be configured:
 <filter>
   <filter-name>SparkFilter</filter-name>
   <filter-class>spark.servlet.SparkFilter</filter-class>
   <init-param>
     <param-name>applicationClass</param-name>
     <param-value>com.company.YourApplication</param-value>
   </init-param>
 </filter>

 <filter-mapping>
   <filter-name>SparkFilter</filter-name>
   <url-pattern>/*</url-pattern>
 </filter-mapping

Javadoc

Javadoc is available in the zip files that can be downloaded from the project's page at google code

Examples

Examples can be found on the project's page at google code