The choice of a framework is a reflection of one's philosophy, and so
questions about this choice are introspections into one's own philosophy
about what a web application is, how it works, and what you expect to
lose and gain from your chosen tool.
The four you've listed fall into 2 groups: full-stack (lift and play)
and minimal (scalatra and unfiltered). Are you a full-stack or minimal?
Decide and you are half way to your answer. If you think a framework
should provide rich layers over key technologies including your
protocol, data store, presentation, and state management, then you want
full-stack. Such frameworks are fine, but it is incumbent upon you to
have an intimate understanding of how such frameworks abstract over this
infrastructure, as well as the infrastructure itself. Some will disagree
with that, arguing that the very reason you want these abstractions is
so you don't need this understanding. If you buy that then I wish you
luck; you'll surely need it should you decide to develop a non-trivial
application.
The other two, scalatra and unfiltered, are much lighter. These are
similar in that they provide a syntactic abstraction for working with
http, but intentionally avoid abstracting it away. Instead the embrace
the protocol and keep it front and center. This naturally makes some
tasks more involved (like state management), but such tools make it
easier to wield http, instead of wrangle it into something it isn't.
Additionally, because they're so small and so bound to the medium,
they're much easier to learn.
I've worked a fair bit with lift and play in the past. I like lift's
component-like architecture but found it generally obtuse. I found play
much easier to get started with, and if you're a RoR-flavored MVC type,
it's definitely a good choice. Both pack abstractions over http and come
with ORMs, view and state management out of the box. That said, I'm not
sure I would choose to use either of these simply because I'm more
minimal. In my experience I've found that the bigger the framework, the
bigger the chance of it getting in your way.
I work full time on a mid-sized web app built entirely with unfiltered.
I've worked with unfiltered in some manner since it surfaced, and for
the time being it's unlikely that I would pick something else. Why? It
simply matches my philosophy about web apps, and it leverages scala's
strength to wrap http. For example, instead of using string patterns
that the framework parses on the fly (like scalatra), unfiltered uses
partial functions to pull apart a request as a pattern match. The
library has many intuitive extractors to help you pull apart requests
based on content types, authentication headers, encoding types, and
includes a combinatorial library for sending responses in various
formats. It runs on GAE (I have two such apps deployed), standard
servlet containers, and netty.
So by now my bias is clear, but I'm not really the emotional type. I
arrived at unfiltered after years with many different frameworks, and
after having a go with both lift and play. They are fine frameworks, but
they don't match my philosophy.