Scalatra 2.2.0-RC1 Released

Scalatra 2.2 has been in development for about the past two months. As the release is nearly completed, the project has cut a release candidate, Scalatra 2.2.0-RC1.

Here’s a quick rundown of what’s changed since 2.1.1, the current stable release. Some new (but incomplete) documentation for this release candidate is also available, at

Testing, bug reports, and feedback are all very welcome.


  • Removes jerkson support
  • Removes anti-xml support
  • Adds Jackson support
  • Adds common traits for pluggable json serialization. These traits allow library writers to write against a generic json interface. The application developer can then mix in a specific json implementation, such as lift-json or jackson, and retain all functionality
  • Defers reading request parameters until the last responsible moment (aka lazify)
  • Contrib project has been removed. All the contrib modules have been moved into the main Scalatra project


  • Adds typed param support, previously in contrib
  • ApiFormats now also has a method responseFormat which looks at the content type of the response and falls back to the format of the request.
  • The default bootstrap file is renamed from Scalatra to ScalatraBootstrap
  • FileUpload can now be configured through init parameters
  • RouteMatchers don’t use any by-name params anymore
  • RouteMatcher now takes a requestPath as a param to the apply method
  • You are able to mount the same servlet more than once in the ScalatraBootstrap class
  • Added a new relativeUrl method which will compose a path for redirection and keep relative paths relative
  • Refactored the url method to allow for a more granular building of the path with regards to the context path and servlet path
  • Added a fullUrl method which will use the absolute path created by the url method to build a url with protocol, host, port and path + querystring
  • Added a isHttps method which also looks in the headers for a X-Forwarded-Proto header
  • Added a needsHttps method which looks in the init params for a key org.scalatra.ForceHttps for a boolean value (true/false), this is used by the fullUrl method to work out the protocol
  • Added a org.scalatra.HostName init parameter in which you can override the host name of this scalatra application, if unset the value from request.getServerName will be used
  • Added a org.scalatra.Port init parameter in which you can override the port of this scalatra application, if unset the value from request.getServerPort will be used
  • ApiFormats now also has a reverse mapping for the txt extension


  • removed in favour of json4s support


  • removed in favour of json4s support


  • previous lift-json support is replaced with json4s support.
  • Jackson integration is also provided through json4s
  • Replaces ProductToJsonSupport trait with a JValueResult trait which will try to serialize any value to json or xml when the accept headers or format parameter indicate the user wants json or xml.


  • Adds ScalateRenderSupport trait taken from contrib


  • Adds a databinding module for commands. The commands can have validations attached and will read data from headers, params and the request body (like json/xml) This is implemented using an infrastructure of type classes and uses scalaz validations to capture the validation information.
        class RegisterForm extends JacksonCommand { // you have to pick the json library of choice

          val login: Field[String] = asString("login").required.notBlank.minLength(6).validForFormat("\\w+".r)

          val name: Field[String] = asString("name")

          val email: Field[String] = asString("email").required.notBlank.validEmail

          val homepage: Field[String] = asString("homepage").validUrl

          val passwordConfirmation: FieldBinding = asString("passwordConfirmation").required.notBlank

          val password: FieldBinding = asString("password").required.notBlank.validConfirmation("passwordConfirmation", passwordConfirmation.value)



  • Adds an atmosphere integration. This module adds support for websockets, long-polling, and server-side events.

        class MyAtmoServlet {
          def receive = {
            case Connected =>
            case Disconnected(disconnector, Some(error)) =>
            case Error(Some(error)) =>
            case TextMessage(text) => send("ECHO: " + text)
            case JsonMessage(json) => broadcast(json)


  • Added serialization for AllowableValues in Swagger.scala. These are passed as strings in the AllowableValues object:
  // as List
  allowableValues = AllowableValues(1, 2, 3)

  // as range
  allowableValues = AllowableValues(0 to 1000)
  • Updated to support the swagger-1.1 spec
  • Allows for using either jackson or native json to generate the service description json
  • Auto-registers servlets and filters that extend the SwaggerSupport trait in the swagger manager.
  • Includes the swagger-core and swagger-annotations jars as transitive dependencies (batteries included)
  • the models property in the SwaggerSupport can now be Set as Map(classOf[Pet])
  • responseClass can now be set with a type parameter responseClass[Pet]
  • data types in Parameter and ModelField definitions can now be defined as DataType[List[String]]


  • Adds support for authorization through scentry to Swagger. Shows only actions a user is allowed to see. Example
  • Adds support for using commands with Swagger. This creates a model definition for the body parameters and parameter definitions for the query, path and header params as well as a parameter for the body model
  // So your route looks like this:
  get("/id", endpoint("id"), nickname("getById"), parameters[MyCommand])

  // MyCommand is a databinder which takes care of automatic
  // validation and binding of incoming params, and also allows
  // Swagger params annotations to be automatically inferred from
  // the MyCommand params.  
  class MyCommand extends JsonCommand {
    protected implicit val jsonFormats: Formats = DefaultFormats

    val name: Field[String] = asString("name").notBlank

    val age: Field[Int] = "age"

    val token: Field[String] = (
          sourcedFrom ValueSource.Header
          description "The API token for this request"
          notes "Invalid data kills cute innocent kittens"
          allowableValues "123")

    val skip: Field[Int] = asInt("skip").sourcedFrom(ValueSource.Query).description("The offset for this collection index")

    val limit: Field[Int] = asType[Int]("limit").sourcedFrom(ValueSource.Query).withDefaultValue(20).description("the max number of items to return")


  • Added a method ensureSessionIsSerializable method which will try to serialize every session value.


  • Scentry is now lazily initialized so the order of the traits doesn’t matter anymore