But before I even go that far, some back-story to this whole web framework scenario may be necessary. In order to understand where we are going, sometimes it helps to understand how we've got here and why. So what follows is a bit of history. If you're a Java web developer who is well versed with the current situation, then most of this will probably be a dejavu for you.
The first server-side integration of Java with a web server, aside from CGI, was in 1997 and it was called the Servlet. (I suspect the name was coined to contrast the Applet, which is a Java program served over the web but runs only on the client side.) In Servlet programming, the request was handed to your custom written class (an extension of HttpServlet) which was able to interact with request parameters and build a response. The core part of building the response was, of course, the HTML to be output to the browser, but the only way to feed the output from the code to the browser was via an OutputStream. Thus, your code would look something like this:
PrintWriter pw = servletContext.getWriter();All this is doing is outputting an HTML document with a dynamic link on it. That's a lot of overhead to send something so simple. And the more complex your output document was supposed to be, the uglier your code became - not to mention the overhead of prepending and appending Java code then escaping each line consumed a fair amount of your development time. Now imagine you just finished your Servlet; the code is perfect and it is all tested and works. Then the HTML designer comes to you with some new changes requested by the client. They deliver you a whole new HTML page. Have fun figuring out what changed then coding it into your Servlet. Yes, Servlets used in this way were also a maintenance nightmare. Really this was only one step above CGI programming.
pw.println("<html>");
pw.println("<body>");
pw.println("<a href=\" + myurl + "\">Click here</a>");
pw.println("</body>");
pw.println("</html>");
It's now 1999 - and JSP came to the rescue. JSP followed the lead of PHP, SSJS, and ColdFusion by allowing developers to begin with the HTML code then amend it with the Java code at the points of the page where it needed it. Thus, in JSP, the last example would look more like this:
<html>Really, a JSP is nothing more than an abstraction of a Servlet. The web application server (Tomcat, JBoss, Weblogic, etc) first compiles the JSP into Servlet code (complete with pw.println's) then compiles that into a class file. But the advantage is that you are working primarily in HTML then inserting your custom code at certain points, be it "scriptlets" delineated by the <% %> special tags or by custom-written tags.
<body>
<a href="<%= myurl %>">Click here</a>
</body>
</html>
JSP's solved a development problem, not an architectural problem. It was much more natural for developers to use JSP's for web development since your primary language was HTML. However, the design of your program did not change much. Instead of calling /myservlet which mapped to a Servlet subclass, you called mypage.jsp. Thus, your JSP's contained not just HTML code but also business logic and SQL. The classic way to solve this (as had often been done with larger PHP sites) was to separate your logic into various includes. But what resulted, especially in large sites, was a very static hierarchical structure of includes that became difficult somewhat to maintain.
This was mitigated somewhat in JSP by custom tags. This was a unique feature of JSP, allowing developers to wrap re-usable page components or logic into an tag with special server-side behavior. For example, I might define a tag that retrieves my link from the database and looks like this:
<html>Used in this way, a tag could be considered no more than a glorified include. So the architectural problem still remained. Enter Struts. Originally developed by Craig McClanahan in 2000, Struts borrowed the Model-View-Controller (MVC) architectural paradigm from Smalltalk to encourage separation of presentation logic (your view) from application logic (your model). The Struts Servlet (the controller) sat between the two, loading the model and view components that were relevant to the request.
<body>
<tags:mylink>Click here</tags:mylink>
</body>
</html>
For example, rather than making a direct request to a JSP page, the request would be made to /myaction.do which gets intercepted by the Struts Servlet. Struts associates the request with two components (as specified in your configuration file): an ActionForm subclass which would hold all request parameters passed by the client in a JavaBeans style (using form.getMyParam() instead of request.getParameter("myParam")) and an Action subclass that would handle the processing of the request. An Action was much like a Servlet in this respect, but this is where the similarity ends. Actions should be used only to contain business logic or calls to business services that would fulfill that logic. When your Action finishes executing, it returns a reference to the page to load once the processing is complete. This affords you the flexibility of giving the same Action multiple outcomes. For example, if an error occurred in processing or validation, you could instruct the controller to load the error page as opposed to the next page in the flow. The JSP pages themselves would use custom tags merely to read processing results from the ActionForm and/or set up another form for submission. Thus, your pages would need to contain only presentation logic, the business logic having already been performed.
This is, of course, a very basic flow example. Struts also offered means for validation, templating, localization, action chaining, and several other features. But it should be enough to demonstrate that the architecture of a web application fundamentally changes with this approach. No longer is your application simply performing JSP document execution and retrieval. Now your websites are truly event-based workflows with real event handlers. Also, model and view components could be reused fairly easily. Because this was a much cleaner approach to web development, Struts quickly established itself as a de-facto standard in the Java web application arena.
In the years following the success of Struts many of it's limitations have come to light. These are not so much limitations of the MVC architecture (which is still viewed as a useful paradigm) as they were of Struts' implementation. For example:
- Actions must be tied to the Struts framework through subclassing and the ActionForm - they cannot be simple POJO's.
- The request processing workflow was fairly static and not very easy to modify.
- The JSP custom tags are many and somewhat unwieldy to use. Learning the tags feels like learning a new language.
- Often JSP pages are littered with many custom tags that makes coordination difficult with the plain old HTML that designers delivered.
- Furthermore, front-end web development continues to evolve in ways that were not possible to predict in 2000, the rise of AJAX being prime among them, enabling a richer end-user experience and resulting in more CSS and JavaScript-oriented pages.
By reviewing many of these frameworks, it is not my expectation to necessarily to find the next generation framework I expect to use in all projects going forward. But who knows? Maybe I'll luck out and find what I've been searching for, but I suspect that if there were such a thing then most of us would have flocked to it already. As such, my aim is to try to understand the current trends, the reason behind the divergence, how these frameworks address the demands of modern websites, and hopefully try to reconcile exactly what I would expect that next generation framework to look like.
Now with all that in mind, these are the sorts of things I expect a good web framework would exhibit. Admittedly, these are subject to change as I find implementation details I like/dislike.
- Separation of presentation and business logic - I would expect this to be through an MVC, but there may be other patterns that achieve this.
- Presentation should be mostly HTML/CSS - Some framework-specific markup is acceptable (and likely necessary), but too much makes it harder to read. Of course, measuring this is an art not a science and therefore subjective.
- AJAX support - This should be a MUST in order to make rich web pages.
- Transparent AJAX support - By this I mean it should be possible but not necessary to code JavaScript to interact with the server. This should be handled for you by the framework components. Furthermore, business logic should NOT need to know whether it is processing a traditional request or an AJAX request.
- Security - This is VERY important. This means that we need good validation or other precautions taken on the server side. We cannot allow a hacker to a send something in the request that can blow up our sever or expose confidential information we don't want exposed.
- Convention over configuration - This is a "nice-to-have"; I don't really view it as critical. I haven't jumped on the annotation craze bandwagon yet and I personally don't mind XML configuration. But I will concede, flexibility with less configuration, like less code, often suggests a more elegant solution.
- Standards Support - The more support for standards, the easier it will be to code. This helps reduces ramp-up time and makes learning the framework less overhead on the developer.
No comments:
Post a Comment