<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3974932801312672746</id><updated>2011-07-28T23:15:00.947-04:00</updated><category term='phorce'/><category term='struts'/><category term='java'/><category term='assembly'/><category term='web frameworks'/><title type='text'>stosb</title><subtitle type='html'>Technical musings and ramblings...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://stosb.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3974932801312672746/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://stosb.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>mcmagi</name><uri>http://www.blogger.com/profile/09415871348097595278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b-uULRZ-tXY/Sq74Lw4a3ZI/AAAAAAAAADA/zmNqfNEKoqA/s1600-R/mikeconf.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3974932801312672746.post-7645920522036300878</id><published>2010-06-29T20:21:00.001-04:00</published><updated>2010-06-29T20:23:44.018-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web frameworks'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='struts'/><title type='text'>Working with Struts 2</title><content type='html'>So as I mentioned in a previous post, I've had some time to work with a real Struts 2 app.  While most of my initial impression stands, some of my feelings about it have changed slightly. I can say there are certainly some features I've warmed up to yet there are others I feel are still in need of improvement.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;AJAX&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;For starters, I had the opportunity to replace the DOJO tags already in use by the application with the &lt;a href="http://code.google.com/p/struts2-jquery/"&gt;JQuery plugin&lt;/a&gt;.  While the functionality offered by the plugin was pretty cool, it did suffer from a few quirks.  The first issue that presented itself was that the plugin always fetches a value from the server when the component loads on the page.  Being AJAX, this is done in a separate request from the page itself.  I supposed what I would have liked to see was the initial loading of the component from the same action which loads the page.  This would be less requests against the server initially if you have a bunch AJAX components.  Having said that, I realize this isn't always possible as sometimes the action which returns the AJAX content (be it a div, a select box, or what have you) may need to be different from the action which loads the page.&lt;br /&gt;&lt;br /&gt;One of the features of the tags is that you can "chain" invocations by publishing and subscribing to topics.  For example, say you have multiple select boxes whose values depend on one another.  To do this, you set up your components such that the first select box publishes to a topic that the second subscribes to.  When the value changes in the first one, the second will reload as a result of the message on the topic.  This is kind of neat, but we run into problems again on initial load.  I had one situation in which a page that had three inter-dependent select boxes required SEVEN requests to the server on initial load: one (1) for the page, three (3) to load the initial values, two (2) to refresh the second and third once the first one completed loading, and a one (1) to refresh the third once the second one had completed loading.  I managed to fix this by introducing a &lt;a href="http://groups.google.com/group/struts2-jquery/browse_thread/thread/2f86233f1f848b80/583b1cf414463dd1?lnk=gst"&gt;"deferred loading" patch&lt;/a&gt; to the jQuery plugin source - which essentially suppresses the initial load of the component's values for those tags which you specify the deferredLoading attribute.  This brought the number of requests from seven down to four which is a bit more sane.&lt;br /&gt;&lt;br /&gt;In hindsight, I wish I had come up with a little more general-purpose patch which also addressed the first issue and would have resulted in only one server request on initial load.  But this will do for now.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Annotations&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I've gotten pretty used to writing annotations to declare Struts configuration.  Annotations used in this way really provide contextual configuration.  There's no need to declare what class you're working with as you would in a centralized configuration file.  You simply declare the namespace, your results, and optionally whether or not the class is an action.  (Struts has a multitude of ways to figure out if a class is an action, the annotation is just one way.)  The advantage is that you don't have to remember to edit a configuration file.&lt;br /&gt;&lt;br /&gt;Now in my opinion one of the prime advantages of using Struts over a model-1 approach was the fact that configuration was central.  What I liked about the central config was it gave you a bird's-eye view of the whole configuration, and you could essentially map out a graph of the whole application without delving into individual class files.  The price to pay for this was in terms of overhead; the action classes and the config always need to remain in sync with one another.  Somewhere down the line this was heralded as an inconvenience and annotations were embraced as the solution.  Not to dis annotations as they do play a major role in providing contextual configuration and therefore reducing development time (how would you envision JAXB without any annotations? 'nuff said).  But it almost seems to me there should be two views of the configuration: a per-class view for those doing the developing and a centralized view for those who need a high level perspective of the application.  This might be role that could be filled by an IDE plugin.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Validators&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;While I initially glossed over it when I read the book, I had an opportunity to work with the Validator framework.  I had never used it before, but I admit this is a pretty powerful feature and saves a lot of coding time.  What's nice is that in Struts 2 you can throw your validations into annotations right above the execute function they pertain to, so you don't need to keep a separate validation XML file in sync with your page as you did in Struts 1.&lt;br /&gt;&lt;br /&gt;Having said that it seems there are some minor caveats.  For one, it works well with simple validations.  While you can express conditional validations, you end up repeating yourself quite a bit if several input fields rely on those conditions - and even more if said conditions are complex.  There are ways to ease the pain a bit, such as adding convenience getters to the action which match the condition.&lt;br /&gt;&lt;br /&gt;Another issue I noticed relates to how Struts has field-level validators and global validators.  Field validators are nice since you can show the error associated with the field right next to the field on the page.  However you cannot use field validators if your edits are conditional.  These must be expressed using global validators.  It would be nice if Struts' validation framework gave you the choice of how to categorize (and hence where to display) each type of error.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;OGNL &amp;amp; the Value Stack&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Working with OGNL and the Value Stack wasn't as confusing as I initially expected, although it wasn't without error.  For the most part I wrote my JSP pages using Struts tags and OGNL and was able to avoid the use of EL.  In those cases where I did need both I ran into issues where I needed to &lt;i&gt;transfer&lt;/i&gt; a value from OGNL to EL and vice-versa, and there are some not-quite-so-obvious ways to do that.  At first, you might think the answer would look something like this:&lt;br /&gt;&lt;br /&gt;&lt;div  style=";font-family:&amp;quot;;"&gt;&lt;span style="font-size:x-small;"&gt;JSP to Struts: &amp;lt;s:set var="strutsVar"&amp;gt;${jspVar}&amp;lt;/s:set&amp;gt; &lt;/span&gt;&lt;/div&gt;&lt;div  style=";font-family:&amp;quot;;"&gt;&lt;span style="font-size:x-small;"&gt;Struts to JSP: &amp;lt;c:set var="jspVar"&amp;gt;&amp;lt;s:property value="%{#strutsVar}"/&amp;gt;&amp;lt;/c:set&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;While this might work okay in some situations, it would be an incorrect general solution.  Both of these are converting their values to strings before setting the variable.  So if I had, say, a bean it would set my variable with whatever it's toString() returns.  The actual way to do conversions is as follows:&lt;br /&gt;&lt;br /&gt;&lt;div  style=";font-family:&amp;quot;;"&gt;&lt;span style="font-size:x-small;"&gt;JSP to Struts: &amp;lt;s:property value="%{#attr.jspVar}" /&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style=";font-family:&amp;quot;;"&gt;&lt;span style="font-size:x-small;"&gt;Struts to JSP: &amp;lt;s:set var="jspVar" value="%{#strutsVar}" /&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;You can access variables in any EL-accessible scope (page, request, etc) by using the #attr variable in OGNL.  Likewise, to access any OGNL variable, use &amp;lt;s:set&amp;gt;.  This tag actually does two things: creates a page-scoped JSP variable AND creates an OGNL variable.  You would do the same thing to transfer a value from the ValueStack to a JSP variable.&lt;br /&gt;&lt;br /&gt;I have to admit that OGNL is fairly powerful.  There is a lot more you can do with it than EL - invoke functions, create arrays in-line, and access static properties among other features.  It's powerful enough that I think it's somewhat unfortunate that it's not the default language used by JSP.  And, I'm starting to wonder where exactly EL and JSP are headed, considering Sun (*ahem* Oracle) seems to be backing JSF/Facelets more so than JSP.  But I digress; maybe I'll post more on that topic in another post...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3974932801312672746-7645920522036300878?l=stosb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stosb.blogspot.com/feeds/7645920522036300878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://stosb.blogspot.com/2010/06/working-with-struts-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3974932801312672746/posts/default/7645920522036300878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3974932801312672746/posts/default/7645920522036300878'/><link rel='alternate' type='text/html' href='http://stosb.blogspot.com/2010/06/working-with-struts-2.html' title='Working with Struts 2'/><author><name>mcmagi</name><uri>http://www.blogger.com/profile/09415871348097595278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b-uULRZ-tXY/Sq74Lw4a3ZI/AAAAAAAAADA/zmNqfNEKoqA/s1600-R/mikeconf.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3974932801312672746.post-4224247521156806207</id><published>2010-06-15T16:04:00.000-04:00</published><updated>2010-06-15T16:04:49.173-04:00</updated><title type='text'>Getting back into the spring of things</title><content type='html'>Okay, so it goes without saying that it's been quite some time since I last posted anything.&amp;nbsp; But I've finally been getting back into reading about frameworks again - starting with Spring MVC.&amp;nbsp; Plus I've had some recent experience working with a full-fledged Struts 2 app.&amp;nbsp; I'll talk more about these in later posts, but I just wanted to make a quick post for now to say I've returned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3974932801312672746-4224247521156806207?l=stosb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stosb.blogspot.com/feeds/4224247521156806207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://stosb.blogspot.com/2010/06/getting-back-into-spring-of-things.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3974932801312672746/posts/default/4224247521156806207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3974932801312672746/posts/default/4224247521156806207'/><link rel='alternate' type='text/html' href='http://stosb.blogspot.com/2010/06/getting-back-into-spring-of-things.html' title='Getting back into the spring of things'/><author><name>mcmagi</name><uri>http://www.blogger.com/profile/09415871348097595278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b-uULRZ-tXY/Sq74Lw4a3ZI/AAAAAAAAADA/zmNqfNEKoqA/s1600-R/mikeconf.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3974932801312672746.post-2374227427712327956</id><published>2009-09-23T17:54:00.003-04:00</published><updated>2009-09-23T20:58:14.340-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web frameworks'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='struts'/><title type='text'>Struts 2 in review</title><content type='html'>Much of what I learned of Struts 2 is based on the book &lt;a href="http://www.amazon.com/Struts-2-Action-Don-Brown/dp/193398807X/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1253742591&amp;amp;sr=8-1"&gt;Struts 2 in Action&lt;/a&gt;.&amp;nbsp; The book was well written, well organized, and pretty easy to read over the weekend despite being just shy of 400 pages.&amp;nbsp; I have to say I'm pretty impressed with the Manning books.&amp;nbsp; I have one other Manning book that I'm reading, &lt;a href="http://www.amazon.com/Spring-Action-Craig-Walls/dp/1933988134/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1253742826&amp;amp;sr=8-1"&gt;Spring in Action&lt;/a&gt;, for my analysis of Spring MVC and it's also of very high quality.&lt;br /&gt;&lt;br /&gt;Anyway, after reading the book, I experimented with building a few apps where I could demo the framework's features.&amp;nbsp; As we will see, some of them make customization easier, some of them help separate model and view concerns, and yet others left me scratching my head why they chose to go that direction.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_b-uULRZ-tXY/SrWRy8wR7QI/AAAAAAAAADs/PQB3LwvdEyM/s1600-h/struts2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_b-uULRZ-tXY/SrWRy8wR7QI/AAAAAAAAADs/PQB3LwvdEyM/s400/struts2.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The flow of a Struts 2 request has not changed much since Struts Classic (aka Struts 1) but several new architectural components have been added to the mix and the ActionForm has been removed.&amp;nbsp; When a request is processed by the Struts 2 controller, it first reads your configuration and attempts to associate it with an Action.&amp;nbsp; But rather than invoking the Action right away, it processes the request through something called an Interceptor stack.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Interceptors&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The Interceptor stack is the Struts team's response to complaints about Struts Classic's rigid request processing nature.&amp;nbsp; Previously, developers had very little control over how Struts processed a request.&amp;nbsp; Interceptors, on the other hand, give developers control over the behavior of the controller, allowing you to augment Struts' current Interceptor stack with business activities that cut across many actions (for example, authentication).&amp;nbsp; Interceptors are configured in the struts.xml and are arranged in a sequence representing a call stack.&amp;nbsp; During request processing, the first Interceptor in the sequence is called which performs some pre-processing then calls the next interceptor in the stack.&amp;nbsp; The last Interceptor in the sequence invokes the Action.&amp;nbsp; On the return trip back up the call stack (once the Action has returned) the Interceptors get an opportunity to perform some post-processing.&amp;nbsp; Interceptors also may interrupt processing through the stack and return early, not invoking the Action at all but redirecting the user to a different page.&amp;nbsp; This would happen for example if validation or authentication failed.&lt;br /&gt;&lt;br /&gt;Admittedly, I did have some issues defining my own custom Interceptor properly.&amp;nbsp; Declaring the Interceptor and adding it to the stack feels a little clumsy, and it took me a few iterations of fumbling with the config before I got it working. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Configuration&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This brings me to my next topic... configuration.&amp;nbsp; The configuration file in Struts 2 is organized similarly to Struts 1, but now your Actions are organized into packages.&amp;nbsp; A package is merely a namespace for your Actions.&amp;nbsp; Common Interceptors and Results can be defined within the namespace and applied to all Actions within the namespace.&amp;nbsp; Here is what a package configuration looks like (using the Interceptors I configured in the last section).&lt;br /&gt;&lt;blockquote style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;package name="secure" namespace="/secure" extends="struts-default"&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;interceptors&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;interceptor name="authentication" class="mike.AuthenticationInterceptor" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;interceptor-stack name="secureStack"&gt;&lt;/interceptor-stack&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;interceptor-ref name="authentication" /&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;interceptor-ref name="defaultStack" /&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;/interceptor-stack&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;/interceptors&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;default-interceptor-ref name="secureStack" /&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;global-results&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;result name="login" type="redirect"&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;/login.jspx&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;/result&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;/global-results&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;action name="info" class="mike.InfoAction"&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;result name="success"&amp;gt;info.jspx&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;/result&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;/action&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;action name="logout" class="mike.LogoutAction"&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;result name="success" type="redirect"&amp;gt;/login.jspx&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;/result&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;/action&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/package&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;It is also now possible to use annotations to mark up all this information in your Actions directly, rather than put the information into a centralized configuration file.&amp;nbsp; However, I don't see very much of a benefit as it's now just dispersed configuration.&amp;nbsp; The only thing available in the way of convention is mapping action paths to action classes.&amp;nbsp; Maybe others might find this useful, but personally I just do not see a major benefit in using the annotations here.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Actions&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;As I mentioned earlier, Struts 2 has removed the ActionForm.&amp;nbsp; The ActionForm was generally considered an unnecessary inconvenience as developers were required to create separate beans to represent page components, but those beans were forever tied to the Struts framework by extension.&amp;nbsp; The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;execute()&lt;/span&gt; method of the Action was given the ActionForm and it was up to the developer to cast it to the correct type.&amp;nbsp; Furthermore, validation logic was wired into the ActionForm not the Action, which made integration with backend services (typically Spring-injected) more difficult.&amp;nbsp; But ultimately the ActionForm often lent itself to anti-patterns when not designed on a per-page basis, resulting in  large and unwieldy ActionForms permanently stored in session scope.&lt;br /&gt;&lt;br /&gt;In Struts 2, request parameters are instead saved directly to properties of the Action or to model objects accessible from the Action.&amp;nbsp; (Technically, this is happening against the Value Stack, but we'll get to that later...)&amp;nbsp; If you still prefer to model your pages with separate backing beans (and there may be many reasons why you'd want to) then you are welcome to do so but Struts no longer enforces it.&amp;nbsp; Validation methods are also tied to the Action now, making it easier to access Spring-injected services.&amp;nbsp; Actions, in fact, don't even need to implement the Action interface, but there are some reasons why you'd want to anyway.&amp;nbsp; (convention over configuration being one such reason)&lt;br /&gt;&lt;br /&gt;A very simple Action looks as follows:&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;public class LogoutAction extends ActionSupport&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; implements SessionAware&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Map&lt;string,object&gt; session;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void setSession(Map&lt;string,object&gt; session)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.session = session;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String execute()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; session.put("user", null);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return Results.LOGIN.getValue();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/string,object&gt;&lt;/string,object&gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;b&gt;Results&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;When the Action finishes executing, it returns a string representing the next view component to load.&amp;nbsp; In Struts Classic these were called ActionForwards.&amp;nbsp; In Struts 2 they are called Results, but they also represent something more than just the location of the next page.&amp;nbsp; Results are full-fledged components in the Struts 2 architecture.&amp;nbsp; The default result type works with JSP output, but the framework provides other results types to handle non-JSP content, for example Freemarker, Velocity, and redirects.&amp;nbsp; You are also free to write your own Result to handle output such as JSON output, XML, or XSLT.&amp;nbsp; This makes Results one of the most important components in my view as it ensures view-specific logic stays out of the Action.&lt;br /&gt;&lt;br /&gt;Thus far, I have no major grievances with the Struts 2 framework.&amp;nbsp; I think Interceptors and Results were a clean design and they help separate the Action from cross-cutting concerns and view-specific logic.&amp;nbsp; They do add another layer of complexity to the architecture, but the default configuration makes enough sense so that if you don't need to do anything fancy with them then they won't get in your way.&amp;nbsp; But where I have some major differences with Struts 2 is with the view layer and the Value Stack.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Tags&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Struts 2 has consolidated a lot of the tags from Struts Classic.&amp;nbsp; While there were previously four tag libraries with tons of tags, there is now one tag library with a much shorter list.&amp;nbsp; The advantage here is that there is less to learn.&amp;nbsp; The taglib includes general purpose tags (e.g.  retrieving properties, manipulating the value stack, conditional and iterative logic) as well as UI component tags. &lt;br /&gt;&lt;br /&gt;The UI component tags are "themed", requiring you to put a &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;s:head&lt;/span&gt;&lt;/span&gt; tag in the page header to set up styles for the rest of the page.&amp;nbsp; This of course means that the tags do more than just output the component, they attempt to provide formatting around the component as well.&amp;nbsp; A bold effort on the part of Struts 2, but there are several problems here.&amp;nbsp; First of all, the default theme outputs tables around your input elements and outputs the tags in XHTML, both of which I have problems with.&amp;nbsp; Now, unless you've lived in a hole the past five years or so, tables should not be used for input forms in modern web sites.&amp;nbsp; This is how it was done in the 90's and the first half of this decade.&amp;nbsp; Nowadays, tables should only be used for tabular data (and even then this is debatable).&amp;nbsp; If you're not using divs and styles then you have a bit of catching up to do.&amp;nbsp; Second, XHTML has not become the "next version" of HTML we all though it would be 10 years ago.&amp;nbsp; IE support for it is still broken, and XHTML renderers are often unforgiving about syntax mistakes. &lt;br /&gt;&lt;br /&gt;Having said all that, Struts does offer other themes which will add div's around the tags for you.&amp;nbsp; Even still, I'm a little bit hesitant to use this over the "basic" theme (which supplies no formatting).&amp;nbsp; The problem I have here is that I believe that it's not the responsibility of the framework to format your HTML.&amp;nbsp; There are many evolutions taking place in this space as well, including HTML5.&amp;nbsp; And although it will take some time to see how these new technologies flush themselves out, my concern is that the speed of these developments will outpace the framework.&amp;nbsp; To Struts' credit, it allows you to create your own themes if you're not content with any of the built-in ones.&amp;nbsp; But why require that at all?&amp;nbsp; If you want something to output HTML for you, why not let the tools that are good at building your HTML already do that work for you?&lt;br /&gt;&lt;br /&gt;Another issue I have with the tags is Struts 2's deviance from JSTL tags.&amp;nbsp; For example, there are &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;s:if&lt;/span&gt;, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;s:iterate&lt;/span&gt;, and&amp;nbsp; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;s:property&lt;/span&gt;.&amp;nbsp; JSTL has tags that do the same thing: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;c:if&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;c:choose&lt;/span&gt; perform conditional logic, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;c:foreach&lt;/span&gt; iterates over collections, and &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;c:out&lt;/span&gt;&lt;/span&gt; (or even an EL expression without tag) will output a property value.&amp;nbsp; Standard conformance is a good thing, especially when it's widely in use.&amp;nbsp; Much of the reason for the duplication I believe is because of two other technologies employed by the framework: OGNL and the Value Stack.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;OGNL&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In order to resolve properties, Struts employs a language called OGNL - Object Graph Navigation Language.&amp;nbsp; You can pronounce it "oganal" for short.&amp;nbsp; OGNL expressions evaluate relative to the Value Stack and operate only within the context of a Struts tag.&amp;nbsp; So if you want to access property &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;myProp &lt;/span&gt;on your Action, you would use &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&amp;lt;s:property value="%{myProp}" /&amp;gt;&lt;/span&gt; or in most cases you can just specify the property name without the braces, as in &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&amp;lt;s:property value="myProp" /&amp;gt;&lt;/span&gt;.&amp;nbsp; OGNL can do some pretty neat things.&amp;nbsp; For example, you can specify a list inline as you might want to do for select boxes or check boxes, though in doing so you have to be careful not to inject business logic into your view. &lt;br /&gt;&lt;br /&gt;OGNL does seem like a useful and expressive language, but again, as with JSTL, there is a considerable deviation from the standard here.&amp;nbsp; JSP developers will already be familiar with EL, and will take some time getting use to the &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;%{}&lt;/span&gt;&lt;/span&gt; syntax instead of the familiar &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;${}&lt;/span&gt;.&amp;nbsp; Granted the expressions within the braces are not too different from EL, but there are some differences.&amp;nbsp; Furthermore, the expressions can only be used within Struts tags, and not all attributes accept OGNL by default.&amp;nbsp; In order words, although you can shorten your OGNL expressions in most cases to avoid the use of curly braces it's not immediately clear, without referencing the documentation, if an attribute is allowed to be written as simply &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;myProp &lt;/span&gt;or must be written with the curly braces as in &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;%{myProp}&lt;/span&gt;.&amp;nbsp; Overall,  the benefit you get from the selection of OGNL seems very minimal over conformance to a common standard.&amp;nbsp; If anything the Value Stack could be exposed as a page variable and incorporated into the Struts component tags with EL expressions.&lt;br /&gt;&lt;br /&gt;Now to Struts' credit the view layer was not designed with &lt;i&gt;only &lt;/i&gt;JSP in mind.&amp;nbsp; There are other view technologies that Struts considered including Freemarker and Velocity.&amp;nbsp; OGNL therefore helps satisfy their requirement that Struts remains view agnostic.&amp;nbsp; But it was done so with the risk of making JSP developers unhappy and ultimately abandoning the framework.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Value Stack&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I had mentioned the Value Stack a few times but did not say much about it.&amp;nbsp; The Value Stack is essentially a "virtual" bean containing request parameters, the Action, and optionally any model objects you're working with.&amp;nbsp; When you use OGNL to ask the ValueStack to get a property, it attempts to retrieve its value from the top-most object on the stack.&amp;nbsp; If the it has no accessor for that property then the ValueStack will check the next object in the stack, and so on.&amp;nbsp;&amp;nbsp; What's important here is that it's happening per property.&amp;nbsp; So, to demonstrate how this works, let's consider the following bit of code:&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;s:property name="outerProp" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;s:push value="innerObject"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;s:property name="outerProp" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;s:property name="innerProp" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;lt;/s:push&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;s:push value="innerObject"&gt;&lt;/s:push&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;Suppose the top object of the Value Stack is the Action.&amp;nbsp; The first tag would essentially execute the method &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;MyAction.getOuterProp()&lt;/span&gt;&lt;/span&gt;, which we assume exists for this example.&amp;nbsp; The next tag invokes &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;MyAction.getInnerObject()&lt;/span&gt;&lt;/span&gt; and pushes the value on the Value Stack.&amp;nbsp; The inner object will stay on the value stack within the &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;s:push&lt;/span&gt;&lt;/span&gt; element.&amp;nbsp; The property &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;innerProp &lt;/span&gt;&lt;/span&gt;exists on the inner object and is therefore retrieved from it.&amp;nbsp; But &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;outerProp &lt;/span&gt;does not exist on this object, so the Value Stack falls back to the previous object in the stack, the Action.&lt;br /&gt;&lt;br /&gt;Note that &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;s:push&lt;/span&gt;&lt;/span&gt; behaves much like the old nested tags from Struts Classic.&amp;nbsp; In fact, I can't seem to find any other reason for the existence of the Value Stack.&amp;nbsp; Nested tags were kind of cool when they first appeared as it helped simplify Struts' expressions and therefore reduced code.&amp;nbsp; But I found in practice they were actually somewhat of a pain to maintain.&amp;nbsp; The problem is that your nested context keeps changing throughout the code, making any property expression &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;/span&gt;ambiguous in and of itself.&amp;nbsp; Whenever I would come across such an expression, I found myself traipsing through the code to find the nested context, which was often nested within several other nested contexts.&amp;nbsp; Once JSTL and EL appeared on the scene I found I had hardly any need or desire to use the nested tags anymore, except in cases where JSTL could not do the job.&amp;nbsp; Not only was EL more terse, but your expressions had to be prefixed with the object they were being retrieved from.&amp;nbsp; If you wanted to avoid long chains of properties everywhere, you'd assign the value to a page variable using &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;c:set&lt;/span&gt;&lt;/span&gt;.&amp;nbsp; This makes the view logic inherently clearer since there's no scoping going on "implicitly" and therefore behaving more like a regular scripting language.&lt;br /&gt;&lt;br /&gt;To further confound things, the Value Stack makes things even more confusing when it cannot find a property value on the currently scoped object.&amp;nbsp; It will attempt to retrieve that value from the previous object in the stack.&amp;nbsp; So while looking only at the view code it may seem like &lt;span style="font-size: x-small;"&gt;the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;innerObject &lt;/span&gt;&lt;/span&gt;object has two properties retrieved from it, in reality it only has one.&amp;nbsp; If you need to debug this code for some reason you'll have to trace the expression.&amp;nbsp; Typically, to trace the resolution of an EL expression, you need to start at the parent object and make a trip down property operators to find the class actually being returned.&amp;nbsp; But with the Value Stack, you not only need to make the trip down, but you may need to turn around and go back if the property isn't actually there.&amp;nbsp; Really, the added benefit of saving the developer a few seconds during the initial coding does not seem to outweigh the maintenance overhead.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;AJAX&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The book tends to hype up Struts 2's support for AJAX, indicating that there are new tag libraries being built to handle AJAX actions.&amp;nbsp; It does not go into details, saying that the tags are currently under construction.&amp;nbsp; Some &lt;a href="http://www.infoq.com/news/2009/02/Struts2-1"&gt;web research&lt;/a&gt;, however, shows otherwise.&amp;nbsp; Struts 2.1 has now deprecated support for the DOJO-based AJAX tags, allegedly because DOJO changes too quickly.&amp;nbsp; This should tell you to take hype with a grain of salt.&amp;nbsp; While this would seem to be an unfortunate turn of events, I did manage to find that there is an excellent &lt;a href="http://code.google.com/p/struts2-jquery/"&gt;jQuery plugin &lt;/a&gt;which appears to address many AJAX needs.&amp;nbsp; The showcase in particular looks very promising, showing tag usage examples next to the demonstrations.&amp;nbsp; While I did not get the opportunity to experiment with the tags, I may do so soon as they look pretty exciting.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Last Word&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Interestingly missing from Struts 2 is any state management in the architecture.&amp;nbsp; In Struts Classic, you were permitted to store your forms in session scope through a setting in the config file.&amp;nbsp; In Struts 2, there is no session management whatsoever.&amp;nbsp; It's entirely up to you to manage your sessions.&amp;nbsp; This is good in that it solves the problem of having bloated ActionForms in session scope, but it leaves me feeling that some major aspect is missing.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In conclusion, Struts 2 gets points for the addition of Interceptors and Results to the architecture.&amp;nbsp; It also simplifies the Action considerably, consolidating ActionForm behavior into it.&amp;nbsp; But the selection of OGNL instead of EL was an unfortunate deviance from standards.&amp;nbsp; Furthermore, the Value Stack implementation feels unnecessarily complex.&amp;nbsp; I would also have taken away points for the loss of AJAX components, but the jQuery plugin looks like a very promising replacement.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3974932801312672746-2374227427712327956?l=stosb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stosb.blogspot.com/feeds/2374227427712327956/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://stosb.blogspot.com/2009/09/struts-2-in-review.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3974932801312672746/posts/default/2374227427712327956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3974932801312672746/posts/default/2374227427712327956'/><link rel='alternate' type='text/html' href='http://stosb.blogspot.com/2009/09/struts-2-in-review.html' title='Struts 2 in review'/><author><name>mcmagi</name><uri>http://www.blogger.com/profile/09415871348097595278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b-uULRZ-tXY/Sq74Lw4a3ZI/AAAAAAAAADA/zmNqfNEKoqA/s1600-R/mikeconf.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_b-uULRZ-tXY/SrWRy8wR7QI/AAAAAAAAADs/PQB3LwvdEyM/s72-c/struts2.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3974932801312672746.post-884845562661242258</id><published>2009-09-15T23:16:00.005-04:00</published><updated>2009-09-18T17:58:25.500-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web frameworks'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='struts'/><title type='text'>Where we're going &amp; where we've been...</title><content type='html'>I've finished reading &lt;a href="http://www.amazon.com/Struts-2-Action-Don-Brown/dp/193398807X/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1252985511&amp;amp;sr=8-1"&gt;Struts 2 in Action&lt;/a&gt;.  Quite a good book, but before I start talking about it I want to play around with some Struts 2 code and get an app running.  In the mean time, I've been thinking about posting some goals and criteria for myself so I have something to evaluate and not just looking for what I may subjectively think is "cool" (though I'll probably do that too).&lt;br /&gt;&lt;br /&gt;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.  &lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The first server-side integration of Java with a web server, aside from CGI, was in 1997 and it was called the &lt;a href="http://en.wikipedia.org/wiki/Java_servlet"&gt;Servlet&lt;/a&gt;.  (I suspect the name was coined to contrast the &lt;a href="http://en.wikipedia.org/wiki/Java_Applet"&gt;Applet&lt;/a&gt;, 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:&lt;br /&gt;&lt;blockquote style="font-family: courier new;"&gt;&lt;span style="font-size: 85%;"&gt;PrintWriter pw = servletContext.getWriter();&lt;br /&gt;pw.println("&amp;lt;html&amp;gt;");&lt;br /&gt;pw.&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;println&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;("&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;");&lt;br /&gt;pw.&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;println&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;("&amp;lt;a href=\" + myurl + "\"&amp;gt;Click here&amp;lt;/a&amp;gt;");&lt;br /&gt;pw.&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;println&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;("&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;");&lt;br /&gt;pw.&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;println&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;("&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;");&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;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.&lt;br /&gt;&lt;br /&gt;It's now 1999 - and &lt;a href="http://en.wikipedia.org/wiki/JavaServer_Pages"&gt;JSP&lt;/a&gt; came to the rescue.  JSP followed the lead of &lt;a href="http://en.wikipedia.org/wiki/Php"&gt;PHP&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/SSJS"&gt;SSJS,&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/ColdFusion"&gt;ColdFusion&lt;/a&gt; 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:&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&lt;/span&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&lt;/span&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&amp;lt;a href="&amp;lt;%= myurl %&amp;gt;"&amp;gt;Click here&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&lt;/span&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;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 &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;&amp;lt;% %&amp;gt;&lt;/span&gt;&lt;/span&gt; special tags or by custom-written tags.&lt;br /&gt;&lt;br /&gt;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 &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;/myservlet&lt;/span&gt;&lt;/span&gt; which mapped to a Servlet subclass, you called &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;mypage.jsp&lt;/span&gt;&lt;/span&gt;.  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.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&amp;lt;tags:mylink&amp;gt;Click here&amp;lt;/&lt;/span&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;tags:mylink&lt;/span&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;Used in this way, a tag could be considered no more than a glorified include.  So the architectural problem still remained.  Enter &lt;a href="http://en.wikipedia.org/wiki/Apache_Struts"&gt;Struts&lt;/a&gt;.  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.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_b-uULRZ-tXY/SrQB6VYG1II/AAAAAAAAADk/vybFjQH6Rqc/s1600-h/struts1.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_b-uULRZ-tXY/SrQB6VYG1II/AAAAAAAAADk/vybFjQH6Rqc/s400/struts1.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;For example, rather than making a direct request to a JSP page, the request would be made to &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;/myaction.do&lt;/span&gt;&lt;/span&gt; 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 &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;form.getMyParam()&lt;/span&gt;&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;&lt;/span&gt; instead of &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;request.getParameter("myParam")&lt;/span&gt;&lt;/span&gt;) 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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Actions must be tied to the Struts framework through subclassing and the ActionForm - they cannot be simple POJO's.&lt;/li&gt;&lt;li&gt;The request processing workflow was fairly static and not very easy to modify.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The JSP custom tags are many and somewhat unwieldy to use.  Learning the tags feels like learning a new language.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Often JSP pages are littered with many custom tags that makes coordination difficult with the plain old HTML that designers delivered.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;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.&lt;/li&gt;&lt;/ul&gt;Several frameworks arrived on the scene that attempted to address some of these issues, for example: Spring MVC, WebWork, and Struts 2 (which evolved out of WebWork).  Such frameworks are said to be action-based.  Others took a different approach entirely,  focusing on better integration between Java code and the page components, for example: JSF, Tapestry, and Wicket.  Such frameworks are said to be component-based.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&amp;nbsp; &lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Separation of presentation and business logic&lt;/span&gt; - I would expect this to be through an MVC, but there may be other patterns that achieve this.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Presentation should be mostly HTML/CSS &lt;/span&gt;- 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.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;AJAX support &lt;/span&gt;- This should be a MUST in order to make &lt;span style="font-style: italic;"&gt;rich &lt;/span&gt;web pages.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Transparent AJAX support &lt;/span&gt;- 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.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Security &lt;/span&gt;- 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.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Convention over configuration &lt;/span&gt;- 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.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Standards Support&lt;/span&gt; - The more support for standards, the easier it will be to code.&amp;nbsp; This helps reduces ramp-up time and makes learning the framework less overhead on the developer.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;There are probably others, but these are the ones that come to mind at the moment. Overall, these criteria are what in my mind contribute to a framework's &lt;i&gt;elegance&lt;/i&gt;, making it simple to code and making sense for both web-based and user interface development paradigms.&amp;nbsp; With that said, next time I post, I'll be talking Struts 2.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3974932801312672746-884845562661242258?l=stosb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stosb.blogspot.com/feeds/884845562661242258/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://stosb.blogspot.com/2009/09/servlets-jsp-and-struts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3974932801312672746/posts/default/884845562661242258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3974932801312672746/posts/default/884845562661242258'/><link rel='alternate' type='text/html' href='http://stosb.blogspot.com/2009/09/servlets-jsp-and-struts.html' title='Where we&apos;re going &amp; where we&apos;ve been...'/><author><name>mcmagi</name><uri>http://www.blogger.com/profile/09415871348097595278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b-uULRZ-tXY/Sq74Lw4a3ZI/AAAAAAAAADA/zmNqfNEKoqA/s1600-R/mikeconf.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_b-uULRZ-tXY/SrQB6VYG1II/AAAAAAAAADk/vybFjQH6Rqc/s72-c/struts1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3974932801312672746.post-9120514611209513163</id><published>2009-09-14T22:18:00.000-04:00</published><updated>2009-09-14T23:29:59.570-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web frameworks'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='struts'/><category scheme='http://www.blogger.com/atom/ns#' term='phorce'/><title type='text'>Web Application Frameworks</title><content type='html'>&lt;a href="http://en.wikipedia.org/wiki/Web_application_framework"&gt;Web Application Frameworks &lt;/a&gt;have become a recent obsession of mine.  For the last seven or so years the framework I have most heavily utilized has been &lt;a href="http://struts.apache.org/1.3.10/index.html"&gt;Apache Struts&lt;/a&gt;.  Frameworks are generally supposed to ease your development and, at the same time, be a pleasure to work with.  Lofty goals to be sure.  And while Struts' &lt;a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller"&gt;MVC architecture &lt;/a&gt;was a revolutionary step in the right direction, it had more than it's share of shortcomings.  So what is life after Struts like for a Java web developer?&lt;br /&gt;&lt;br /&gt;Thankfully, there have been many products released (in various states of completion) that have attempted to reconcile Struts' shortcomings or perhaps revolutionize web development all over again.  In the next few articles I'll attempt to review some of these frameworks by both reading about them (and I mean full book reads, not an hour in front of Google) and experimenting with building an app.  Hopefully something better than Hello World.&lt;br /&gt;&lt;br /&gt;Now this brings me to my other motivation for doing so.  It seems to be a rite of initiation for Java web developers to build their own framework at some point or another.  My own pet project is one that I call  &lt;a href="http://sourceforge.net/projects/phorce/"&gt;Phorce&lt;/a&gt;.  However, mine is not in Java.  It's in PHP.  Feel free to check out the source if you're so inclined, but keep in mind it's a work in progress and will likely remain that way until I can at least gauge what the best direction is to take in this web framework arena.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3974932801312672746-9120514611209513163?l=stosb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stosb.blogspot.com/feeds/9120514611209513163/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://stosb.blogspot.com/2009/09/web-application-frameworks.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3974932801312672746/posts/default/9120514611209513163'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3974932801312672746/posts/default/9120514611209513163'/><link rel='alternate' type='text/html' href='http://stosb.blogspot.com/2009/09/web-application-frameworks.html' title='Web Application Frameworks'/><author><name>mcmagi</name><uri>http://www.blogger.com/profile/09415871348097595278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b-uULRZ-tXY/Sq74Lw4a3ZI/AAAAAAAAADA/zmNqfNEKoqA/s1600-R/mikeconf.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3974932801312672746.post-1885634262421300902</id><published>2009-09-14T21:55:00.001-04:00</published><updated>2009-09-14T23:29:00.428-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>Hello World</title><content type='html'>Ok, so I've finally done it.  I have my own blog.  It really is about time.&lt;br /&gt;&lt;br /&gt;I'm dedicating this to my technical thoughts, musings, and sometimes ramblings.  The title, STOSB, is a reference to the &lt;a href="http://www.penguin.cz/%7Eliterakl/intel/s.html#STOS"&gt;8086 assembly instruction &lt;/a&gt;used for storing a byte from a CPU register to the location in memory referenced by es:di.  It was intended for use in string processing and means "Store String Byte".&lt;br /&gt;&lt;br /&gt;Anyway, not much of substance to say in this post.  It was just intended as a cheesy introduction.  Hello world. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3974932801312672746-1885634262421300902?l=stosb.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stosb.blogspot.com/feeds/1885634262421300902/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://stosb.blogspot.com/2009/09/hello-world.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3974932801312672746/posts/default/1885634262421300902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3974932801312672746/posts/default/1885634262421300902'/><link rel='alternate' type='text/html' href='http://stosb.blogspot.com/2009/09/hello-world.html' title='Hello World'/><author><name>mcmagi</name><uri>http://www.blogger.com/profile/09415871348097595278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_b-uULRZ-tXY/Sq74Lw4a3ZI/AAAAAAAAADA/zmNqfNEKoqA/s1600-R/mikeconf.jpg'/></author><thr:total>0</thr:total></entry></feed>
