IntroductionJava has been around for a while. Soon after its initial inception, Sun started to push the platform towards the web with an eye on big enterprise environments, in the form of the Java Enterprise Edition specification. This gave birth to, among others, the epic Servlet specification - in most environments the heart of the Java web layer.
Now many years later, there are dozens of web frameworks that either extend the initial Servlet core or bypass it completely. There is for example Sun's own JSP technology which is a simple templating system on top of the Servlet specification. Next to that there is the Javaserver Faces technology, which is a stateful enterprise scale web framework designed to be used to build large backend systems and user interfaces for existing enterprise solutions (and less for, say, the next Facebook).
Having also visited the Sun/Oracle forums for many years now, the same question pops up again and again and again: which web framework is best. Let me address and demystify that question right here and right now:
the best does not exist.
Stop looking for it, it is not there. They all have their merits and they all have their breaking points. There is not a single web framework out there that will work for all requirements out there. JSF is a good example of this: you could attempt to create web 2.0 type webapps with it (blog, social website, twitter 2.0, etc.), but you'll only find it a rather grueling experience. JSF was not designed for that purpose. Neither was Spring framework. Struts and Play framework however are better candidates in this particular case. But if I would have to build a web application that ties into a JEE backend, I wouldn't want to use anything but JSF 2.1.
So what then!? Why is there no one tool for all jobs like in .NET and why is there no Microsoft telling you what to use and how to use it? Yep, that's the Java platform. You either love the freedom of choice, or you should run away now. As it is, you have a whole wonderful world of frameworks to examine and explore. I have done that too just for the fun of it and I like to discuss some of them with you, to perhaps save you some time or at least make you aware of their existence. This will most certainly not be a "JSF VS Spring" type comparison, because I am smart and experienced enough to know the futility in such discussions. Of course I cannot document what I don't know, so don't expect to find all frameworks in the world in this article.
Before we start I have to make the obvious crystal clear: these ramblings are of course my personal opinion and experiences which in some cases may have been resolved since the time of writing, or a better solution escaped me at the time. Your mileage may and probably will vary. If you keep it neutral I will be very glad to hear where you disagree with me!
Servlets and JSPsThe golden oldies. I have long called JSP technology seriously outdated, but I have recently changed my mind a little about that. The fact of the matter is that Servlets and JSPs do nothing for you; its you in charge, you do everything including mapping request parameters to objects and validating them.
Even with the big bad world of frameworks out there, is there still a place for Servlets & JSPs? Yes, certainly. Smaller web applications are still quickly and cleanly built using them and you don't need any external dependencies either. The only side note is that you do it properly, which means:
- use Servlets to invoke business logic (which includes invoking database queries)
- use JSPs to generate the view
- JSPs contain no Java code, only JSTL tags and if you want custom tags
One 'page' will generally be bound to both a servlet and a JSP; the servlet for the backend business logic and the JSP for the view logic. This works by making the servlet the entry point (for example a form submission goes to the servlet) and when its time to show something, you forward control to the JSP. By setting appropriate objects in the request scope, you can share data between the servlet and the JSP.
If you want or need to stick to these bare basics, it would still benefit you to investigate the Stripes framework. Stripes is a lightweight framework on top of servlets & jsps, taking away many boilerplate tasks you would normally be very bored with yourself.
Want to learn Servlets & JSP technology? Read Core Servlets 2nd Edition, a free online e-book. It is old, but still the best book I know on the subject.
I would use this: when you have only a few pages/functions to implement, like for a simple management interface for a backend application or a webapp with very light dynamic needs.
Javaserver FacesJavaserver Faces, or JSF, has had a rocky development cycle. It only became anything close to 'good' with the 1.2 release where many design flaws were fixed. Years later JSF 2.0 (and now JSF 2.1) made its appearance, which fixed even more design flaws and took away most if not all of the XML configuration necessity that made JSF 1.X clunky indeed.
Many hate it, many love it. The main reason most people hate it is because of its steep learning curve and the fact that people use it for all the wrong purposes. You have to accept one basic fact: you are not going to properly use JSF until you really know how it ticks under the hood. You have to understand how the request lifecycle works and how the statefulness of JSF works. And when you do, you can wield it like a magic wand. It is a powerful framework that can save you an immense amount of time... if used for the right purpose! The right purpose is found within the specification it is part of: the Java Enterprise Edition specification. JSF is primarily aimed at being used to build web components for enterprise applications. That is where it shines: creating complex user interfaces with bells and whistles while the framework takes care of wiring UI components to backend classes with automated validation and transformations going on. Due to its stateful nature you even have an object representation of the web UI available to you server side.
JSF itself is only the base actually. It is designed to be extended, and many third parties do just that. On top of JSF you also have JBoss Richfaces, Icefaces, Primefaces, Oracle ADF, Apache Tomahawk, JBoss Seam, Omnifaces, etc. They all share the fact that they extend core JSF with more functionality, which usually comes in the form of Ajax controlled "rich internet components". Jboss Seam is unique in that list in that it does not actually aim to extend, but "seamlessly wire together" many frameworks and technologies to the enterprise platform.
Since JSF 2.0 these extension frameworks integrate quite neatly, so you can even mix and mash them together and have an even richer component library available to you. Its all quite neat, but beware: this is not easy material. JSF is hard, and "they" want you to buy books to remedy that so don't expect rich online documentation either. What documentation there is, you can find as part 2 of the JavaEE tutorial - that's a good place to start to see if JSF is anything for you.
I would use this: For medium to complex enteprise webapps where full control over the front end is not a requirement. If the application is built and designed around a solid backend, JSF 2.1 is your friend. If your application aims around a rich and dynamic web 2.0 front end, JSF is not your friend.
EDIT 10-04-2013: Apparently JSF can now also be stateless, as reported by Balusc on his blog. That may help a lot of people to actually use the framework where previously they couldn't or it was very hard (session-size limited environment, load-balanced website)!
Spring frameworkIts a bit unfair to list Spring framework here, as it is actually not a 'web framework' but more like an alternative to Enterprise Javabean technology. But Spring is unique in that it does not want to be something specific; it is such a dynamic and open framework, it shares JBoss Seam's aim in wiring together many different technologies, both frontend and backend. It does not aim to replace Java Enterprise Edition technology, not at all. You can use it as an alternative, but you are just as free to wire Spring and JEE technologies into the same application. Spring helps you to do it. Want to use JSF as the front end? No problem. Want something simple but you don't want to lower yourself to JSPs? No problem, Spring has a built in front end layer.
So what does Spring add itself? Plenty!
- a bean autowiring system to replace (or extend) the dependency injection model as it exists in the JEE specification. Spring does not limit itself to managed classes, you can autowire just about anything using Spring with either the right configuration or a few annotations, including in client side applications if you would want to go so far.
- an incredibly strong security model (which can be uses separately from the Spring framework itself).
- "Inversion of Control", or IOC. In stead of manually constructing objects, you "inject" them from a Spring managed context. You may be familiar with dependency injection schemes as they exist nowadays in the JEE6 specification; Spring offered such services for a long time already.
- a strong emphasis on the Model View Controller pattern. Spring provides default controller types for example, but you can also implement your own. As for the model layer the framework can setup JDBC, Hibernate, JPA, etc. for you and it can even manage the sessions and transactions.
- A built in web front end framework with easy to use annotations that is a very decent replacement for JSP technology and hooks nicely into Spring's MVC model.
And much, much more. Check out the reference manual to at least adopt the awe it deserves.
That also proves Spring's main disadvantage: it is huge and huge frameworks tend to be clunky. On top of that Spring has been around for a while now and has gone through three iterations already, which means that there is also a big amount of legacy that the framework has to drag around. All this makes it quite hard to start to use the framework as first you have to separate those pieces of corn from the cob that you really want to eat.
I would use this: when I have to build and maintain a large enterprise application that will also target other legacy systems and technologies. Spring is so flexible you'll have the least trouble adapting it to whatever you already have floating around. That doesn't mean it is going to be easy, but the people that built Spring already did a lot of the ground work for you. Also there is a huge community around Spring, which counters the startup troubles you'll likely have.
Struts 2Struts is what existed "before Spring". It is one of the earliest Java web frameworks out there. As such, you don't want to use Struts 1 anymore. It is old, outdated and every framework released after it was aimed to do better than it.
Struts 2 is one of those frameworks that aims to do better than Struts 1; it is actually quite a clean and neat framework if you but dive into the documentation for a moment. If all you want to do is create simple web applications, "web 2.0" or otherwise, then it isn't a bad idea at all to consider Struts 2. But beware that it has limitations. For one, the security model is weak at best (the fact that the sales pitch on the home page doesn't even mention it is a good backup of that statement). In this world of web paranoia and heightened security demands, the framework does nothing to assist you or to help you prevent doing it wrong.
I would use this: for web applications that do not have high security demands but will be a mix of complex forms and dynamic frontend pages. Also good to get into the world of Java web development as it has such an incredibly low learning curve.
Wicket 6+Another framework brought to us by Apache, Wicket is actually quite a cool alternative to its competitors. A Wicket application, although targeting the web, develops like a Swing application. You work with components in stead of a "backend and a frontend"; the separation between the two layers is almost taken away by Wicket. In stead you think in events. A user presses a button, what is supposed to happen? Where other frameworks tend to hide the interaction, Wicket bares it all - on the Java side. Unless you introduce the rich Ajax functionality of Wicket of course, then stuff starts to happen client side as well.
Wicket is also a framework that is friendly to the developer. It integrates nicely into IDEs and even has built in support for hot-deployment making it far easier to change and debug your applications. Also boring and cumbersome features like making your application multilingual is made incredibly easy. The framework really takes away most of the boring repetitive chores from you, leaving only the interesting stuff for you to do.
But, no framework is perfect. Wicket has some downsides in my opinion:
- the available information is a bit weak and disorganized (but has grown since I first wrote this article). I found myself having to hunt through endless forums, blogs and even the source code to figure out how the more advanced features of Wicket not only really work - but also how they should be properly applied and what you absolutely should not do. Don't get me wrong, when you know how they work Wicket rules, but I wish someone would have written it all down in a coherent form in a single resource. A notable exception is "Wicket in Action"; that book tends to go a little bit further and actually provides useful examples you can use directly in your application. But in my opinion: still not enough and the book is aging and Wicket's evolution has not stopped since it was written.
- Even if the framework takes away plenty of work, I found myself having to write lots of boilerplate code nonetheless because of the component oriented approach; in some cases it can even be a little counter intuitive. You really have to think about how you organize your project to not drown in the sea of pages, panels, components, validators, model objects, message files, etc. etc. It can be hard to manage large Wicket projects, take your time to keep your project well-structured and don't be afraid to move things around. Also don't fear inner and anonymous classes when you know you're not going to reuse something.
- The framework may appear simple, in fact it shares the Javaserver Faces problem of being complex under the hood and yet again do you really need to know how the framework ticks, or you can get into big trouble later on. A notable problem is that of an exploding session for example; Wicket is by default stateful and uses the session to keep its state, including the component tree of pages being rendered. If you're not careful you can be cramming a lot of data into the session without even realizing it; the framework does not do enough to help you prevent that. You have to read the fine print to know what to do and what not to do. Be careful choosing and using Wicket in an environment were the session size is limited. There are more such examples, most of them boiling down to "Always use models!". Then why offer the possibility to not use them and send newcomers awry? :/
- The framework has a rich history, which has also lead to feature creep. There are ALWAYS multiple Wicket classes and features to do the exact same thing, and you have to be experienced to know which way fits with what exact requirement. Keep the javadocs really close.
Regardless of those negative points, they are all to be circumvented by properly thinking about it, doing the necessary research and simply gaining experience. Rarely any framework can work without those basic attributes in your personal involvement. So now that you're aware of it, don't fear to use Wicket if you're interested.
I would use this: When you need the power of JSF but you hate JSF's design, or when you need more control over the front-end. Wicket also works really well in environments where web designers and developers share tasks, since there is no code and almost no special markup in the views. Finally: if you're a client software developer by heart and you want to get into web development, Wicket will make the transition easier than other frameworks given its component approach. Finally, if you anticipate your project will make use of lots of components or fragments of pages that you'll be reusing multiple times, definitely go for Wicket!
On top of GWT itself Google also provides you a wide range of tools, for example a rich set of plugins for Eclipse. This makes it a complete package that is completely carried by Google itself. This keeps it all tightly integrated and documented, which is a big plus for a web framework. It is of course also a good choice if you want to deploy into Google's App Engine - there are also tools to be able to do that from your IDE. These tools are a bit invasive however; I recommend installing a fresh copy of Eclipse specifically for GWT app development.
My main beef with GWT is that the framework is so vastly different from any other framework out there; you even need a specific GWT compiler. When you want to use it you start from scratch, even if you've been writing webapps for years already. That is not necessarily a bad thing of course, but it may make it hard to adopt it for a new project.
I would use this: when you have the requirement to create highly complex and feature rich web user interfaces. This is especially true when you have to work with people that do not have widespread experience with Java enterprise development, as GWT only lightly touches upon the Java language.
Play FrameworkPlay framework is a relatively young framework that hasn't been given the attention that it deserves so far. I say that because when I started to experiment with it, it made one thing clear to me: this framework succeeds royally. What it does better than other frameworks:
- stripping away the boring part of Java web development
- fusing backend and front end development
- being completely stateless and REST-enabled
- providing perfect hot-deployment without need for JRebel; even JPA entities!
- simplifying setup; you don't even need to configure anything in the web.xml
- integrates with many popular and important web technologies
- manages dependencies for you without needing to learn the complexities of Maven
- consolidates web dev into a neat package. You don't have to make choices, Play has everything on board to get you going.
- data is very easily shared as XML or JSON
- incredibly easy ORM model based on Hibernate and JPA 2.0, with an additional layer that takes away the cumbersomeness. You don't even need a persistence.xml.
- toolset inspired by that of Ruby and Groovy On Rails that allow you to manage most of anything you want to do with a Play project, including setting it up for a specific IDE.
- not the least important: the maintainers are active and listen to you. Expect bugs you report to be fixed timely (if it is really a bug of course).
- for easy administration, a CRUD module is available
Really, this framework is a breath of fresh air and will appeal to people that cannot work with for example the statefulness of a framework such as JSF or the confusingly open nature of Java enterprise development as a whole. Play lays down the rules, it brings the conventions and it provides you the foundation to allow you to quickly and painlessly develop web applications, without boilerplate, dependency conflicts or layer upon layer of configuration.
This is the first framework I know of that can utilize the benefits of the Scala language (but it is also built for the Java language). The same is true for Play 2.0 which is out right now, and more so. This is mostly because the framework is modeled almost entirely after Ruby on Rails 3 including the available tooling, which is a web framework stack that "just works". If you know which buttons to push and which levers to pull of course.
I've been incredibly positive so far, of course there are a few things to complain about.
- the programming model is quite... counter-intuitive. You'll be creating lots of static classes and entities with public members for example
- navigation is based on throwing exceptions :/
- documentation is a bit shallow at the moment, although Play 2 will have some nice books written by people I have had the pleasure of conversing with and I respect a lot. The online documentation is of the "this is the easiest way to do it" type. Still with a bit of digging you can figure out anything you need, especially because you get a nice set of example programs.
- deploying is a bit of a mess using Play as you don't deploy classes, you deploy the source files (which the framework instruments at runtime before compiling them for you). You can deploy as a war, but you are encouraged to deploy in exploded form. At least using Play 1.X I would advise you to just do that.
- The (alternative) way you manage a Play project makes it difficult to integrate it in for example a JEE application in a way that is easy to maintain.
- Play 2.0 still supports the Java language, but at its heart it is really designed for Scala. You'll see evidence of that every way you turn, starting with the template language which is Scala based.
I would use: if you are new to Java web development as it is really easy to pick up. Also if you are bothered by the incoherence that most popular Java web frameworks are prey to, Play may be the relief you need. Finally if you need to create a webapp that is highly front-end oriented but you don't want to dig into the complexities of for example GWT, Play is also a really good choice as you have total freedom there. The basic idea is that you use jquery and jquery-ui to create your rich internet components. Play's simple Java (or Scala) backend will help you take care of the rest. If you want to use Scala in stead of the Java language, the choice should be a no-brainer.
As stated I did not use all frameworks out there so I can't comment on them, but readers of this article have seen fit to make recommendations and I respect their opinions. Hence let me summarize some things that you may glance from the comments; I encourage you to check them out before making a final decision on a framework to use.
In closingThat was a quick overview of the web framework which I consider to be the most viable. There are many, many more, but most of them serve the same purpose as one I already named here. I couldn't end this article without at least passing out my personal recommendation. And that would be:
- use Play framework for pure stateless webapps
- use JSF 2.1 for JEE systems for highly data driven applications and/or that require tight integration between the web layer and the business logic layer. As an added bonus I would add Primefaces for a whole slew of easy to use rich internet components while keeping the webapp lightweight.
If you stick these two in your toolbox, you can basically tackle any problem IMO. Your mileage may vary.