Forums Register Login

Struts v. Spring

+Pie Number of slices to send: Send
So for that past month or so I've been tooling around with the Spring framework. I've downloaded the jpetstore example to look through source code and I've gone through the very clear and usefull tutorial on from the www.springframework.org site.

I would consider myself extremely comfortable with Struts. When I first started using it I found it extremely easy to get up and running. I even wrote an enterprise app using Struts within the first two months of using the framework. The transition from a propriotary MVC framework to Struts was surprisingly easy.

I don't feel as comfortable with Spring. It's seems convoluted and difficult to get started. There seems to be many layers of indirection which make getting an app configured and running difficult. I've thought perhaps I'm missing something, but looking through the tutorial I feel I've grasped all of the tools I need. I've coupled this tutorial with Rod Johnson's J2EE Development without EJB (ISBN: 0-7645-5831-5) to further my understanding of how Spring should work (using some textual examples through out the book).

How do other people feel about this framework? Have you had difficulty understanding it, compared to Struts? How would you compare it to Struts? Are there other resources you would suggest for people to understand it further?

Thanks,
Frozenquest
+Pie Number of slices to send: Send
Chris,

Take a look at the Petclinic sample application. It's considerably simpler than JPetstore.

SpringMVC is definitely a bit more layered than Struts but it is IMO more flexible and actually easier to use once you get used to it, particularly so for more advanced applications.

Some advantages of SpringMVC over Struts:

1. This is the big one. To do form processing, in Struts, you have to code ActionForm subclasses to access your domain logic POJOs whereas in SpringMVC you directly use the POJOs which are not dependent on either the Struts or Servlet APIs. ActionForms can only have String or boolean properties so you have to provide appropriate mapping of properties in your ActionForm. With SpringMVC, this is handled mostly automatically by the framework through the use of its default PropertyEditors. If you need custom conversion, i.e. for a particular Date format, you just register your own PropertyEditor with the Controller, implementing the setAsText and getAsText methods. The framework does a good job of reporting problems such as type mismatches and allows you to easily configure the messages that are displayed to your users.

2. In Struts you have Action subclasses to handle the workflow. In SpringMVC, you merely have to implement the Controller interface which has a single handleRequest method or you can if you wish subclass or directly use one of the many useful Controller implementations the framework provides, such as SimpleFormController, MultiactionController and AbstractWizardFormController, etc. The important point is that in Struts you MUST derive form Action where in Spring MVC it is a choice that allows more flexibiity. SpringMVC does provide a complex workflow so it does take a bit to wrap your mind around it particularly in the forms area. There is very good documentation of this workflow in the Javadoc and the refernce documentation. There are a lot of places where you can intercept and customize the workflow should you need to, i.e. before binding, or after binding but before the controller gets it, etc.

3. With Struts, you need to use a variety of Struts specific tags to assure that request parameters are bound to your ActionForm fields and display binding/validation errors. In SpringMVC, there is 1 simple bind tag that handles all of this. Your JSP's tend to be smaller and have a lot more pure HTML content. SpringMVC also works more easily with other view technologies such as Velocity, Freemarker, and others because the notion of a view is cleanly separated from the model and controller.

4. With Struts, you couple your Actions to the view by defining ActionForwards either globally or within a particular ActionMapping. SpringMVC has implementations of the HandlerMapping interface to support this functionality. There are a number of useful out-of-the-box implementations for mapping URLs to Controllers. You can group these together into multiple logically related mapping beans that can then have, for instance, AOP interceptors applied to them to implement security, etc.

5. In Struts, validation is ususally implemented in the validate method of an ActionForm, sometimes using the Jakarta common-validator package for declarative validation definition. In SpringMVC, validators are first class business objects that are NOT dependent on the Servlet API, even when using commons-validator (there is code in the sandbox to support this). This allows these validators to be reused for instance in your business logic before persisting a domain object to a database.

6. In general, Struts takes the approach that you should subclass framework classes to implement your ui. This does have the advantage of making it easy for you to hit the ground running. SpringMVC, on the other hand, like the rest of the Spring framework follows an interface based philosophy which provides a lot more flexibility and a lot easier testing. It also provides a number of easy to use default implementations of its interfaces so it's actually pretty easy to use also.

7. SpringMVC is only a small part Spring and as you might imagine it integrates seamlessly with the rest of what Spring has to offer, i.e. dependency management, declarative transactions, AOP, simpler access to persistence and remoting frameworks, etc.

When you see SpringMVC through Struts-tinted glasses, it's not so easy to see that it provides the same functionality only in a more general and better organized way IMO. None of this should be taken as a knock on Struts as I think it is an excellent product that obviously has a great mindshare and acceptance and has really pioneered a lot of the important conceptual work in this area.

DISCLAIMER: I am prejudiced as I am a Spring committer.
+Pie Number of slices to send: Send
Great post Ken, thanks for taking the time with this one. I really know next to nothing about Spring, and although I'm not a Struts zealot, there are a couple comments/questions I have on a couple of your points.

1. This is the big one. To do form processing, in Struts, you have to code ActionForm subclasses to access your domain logic POJOs whereas in SpringMVC you directly use the POJOs which are not dependent on either the Struts or Servlet APIs.

I can see where this can be a turn-off, but in my mind it doesn't really seem like a bad thing. First, ActionForms are tied to the view, they are not meant to represent the model, even though we know in practice that they often do. With that in mind it makes sense that all properties are limited to Strings or booleans (or arrays of the same, or Objects composed of the same, or Collections composed of the same, etc...) since we are dealing with the request, which is only String values. In other words, you can almost look at ActionForms as an abstraction of the request. So that at least explains why they are limited to Strings and booleans.

On your second point, I personally don't like exposing the model directly to the JSP in such a manner that the model is modified directly from user input. This may be a hangup I've heldover from my Perl/CGI days where variables set directly from user input were considered "tainted" and had to be handled in a specific manner.

5. In Struts, validation is ususally implemented in the validate method of an ActionForm, sometimes using the Jakarta common-validator package for declarative validation definition. In SpringMVC, validators are first class business objects that are NOT dependent on the Servlet API, even when using commons-validator (there is code in the sandbox to support this). This allows these validators to be reused for instance in your business logic before persisting a domain object to a database.

Only validation of user input should be handled through the Struts validator framework. Validation of business rules should still be handled by independant business objects. It's a problem of implementation when developers start having validator validate business rules and is yet another symptom of tier leakage that happens in any MVC framework if the developers aren't diligent.
+Pie Number of slices to send: Send
Hi Jason,

I can see where this can be a turn-off, but in my mind it doesn't really seem like a bad thing. First, ActionForms are tied to the view, they are not meant to represent the model, even though we know in practice that they often do. With that in mind it makes sense that all properties are limited to Strings or booleans (or arrays of the same, or Objects composed of the same, or Collections composed of the same, etc...) since we are dealing with the request, which is only String values. In other words, you can almost look at ActionForms as an abstraction of the request. So that at least explains why they are limited to Strings and booleans.



I'm not saying that there is generally something wrong with this approach. I just like the Spring approach a lot better because I don't have to test/write/maintain as much code when I can just use the domain object instead of writing the ActionForm.

On your second point, I personally don't like exposing the model directly to the JSP in such a manner that the model is modified directly from user input. This may be a hangup I've heldover from my Perl/CGI days where variables set directly from user input were considered "tainted" and had to be handled in a specific manner.



Is there ever a justifiable reason for the view to directly modify the model ??? I don't think so. I think all experienced developers should know this by now. If a member of your team persists in doing so after being warned, he/she should be forced to clean the spitoons at the Big Moose Saloon for a long time or some other suitable punishment like having to moderate "meaningless drivel"
If you're really worried about it, like if you're working with legacy code, you can extend your domain object to throw some RuntimeException in every setter and pass it that instead. That should allow you to find the miscreant software and fix it.

Only validation of user input should be handled through the Struts validator framework. Validation of business rules should still be handled by independant business objects. It's a problem of implementation when developers start having validator validate business rules and is yet another symptom of tier leakage that happens in any MVC framework if the developers aren't diligent.



The problem is that validation is inherently a business related integration activity. Why should you have to write validators that all do the same thing for your persistence layer, your webapp layer, your Web Services client, and your GUI client too. If you think of validation as simply another business service, you can minimize duplication as much as possible. Granted not all clients will have identical validation requirements but at least you have some potential for reuse and centralization of this logic. I don't see this as layer creep at all. The one area when I think it does become a bit fuzzy is when internationalization is involved. Then you have a strategic decision to make as to where the internationalization data (strings, regular expressions, icons, etc.) is stored and how you want to handle Locale awarenenss. The data may be in resource bundles but it may alternatively be stored in a database. The easy answer is "it depends" on your application's needs.

The problem with the Struts validator is it depends on Struts and can't be reused. This problem was partially addressed by extracting the code into the Commons Validator and removing the Struts dependency which makes it available to other webapps. A problem still remains in that the Commons Validator depends on the Servlet API which prevents it from being used in the business layer. The Spring Commons Validator sandbox code fixes this by eliminating the inappropriate Servlet dependency allowing maximum reuse potential.
+Pie Number of slices to send: Send
Is there ever a justifiable reason for the view to directly modify the model ??? I don't think so. I think all experienced developers should know this by now.

Of course not, but if a framework allows you to do something, you can rest assured that there will be too many developers who will do it regardless of what we may think should be common sense. I don't really blame Spring for this, as bare bones JSP similarly exposes the model. Still, I would like to see frameworks enforce proper programming practices where practical (say that five times fast).

Thinking aloud and going back to something I mentioned earlier, I think it would be nice to see a framework with a mechanism similar to Perl's tainted mode, where all form/user input is considered "bad" until explicitly validated. Such a mechanism would require developers to properly validate prior to using that data. Sure it would add a bit of extra overhead on developers, but what we lose there we would more than make up for in security. Anway, as I said, just thinking aloud....

Thanks for the thoughtful comments. They are very much appreciated! You've certainly given me some motivation to go and take a look at Spring.
+Pie Number of slices to send: Send
Jason,

Part of the Spring/component style of development is to use possibly "tainted" but extremely lightweight components and then do just-in-time validation where and when it is needed. Part of this style is to supply no-arg constructors, to use setters instead of attempting to insure correctly initialized objects with constructors, to use singletons that are NOT enforced statically, validating objects from the outside rather than from within, etc. The general thrust of this is to make objects as little aware of their surrounding context as possible confining their knowledge of the system to their immediate collaborators. This keeps the components very lighteweight and reusable. The consequences of this are that we need to form new best practices and to be very disciplined in how we go about things. This is obviously easier to do on small highly skilled teams than on larger teams where the range of developer skills is more diverse. Larger teams probably have to take extra measures in testing to make sure things are done right.

One of the very tangible benfits of this style is that it can drastically reduce the amount of code that's needed to implement an application. The effects of this have a cascade effect which means we have a lot less code to test and maintain which has the other benefit of making these objects approach the programmer's Holy Grail of component status where reusability potential is at a maximum. Think of it, if we can actually reuse our objects/subsystems in different applications, the impact on an organization's bottom line could be enormous, particularly so for a large organization. A side benefit of this style is that it's just a lot more fun to do too.


Thinking aloud and going back to something I mentioned earlier, I think it would be nice to see a framework with a mechanism similar to Perl's tainted mode, where all form/user input is considered "bad" until explicitly validated. Such a mechanism would require developers to properly validate prior to using that data. Sure it would add a bit of extra overhead on developers, but what we lose there we would more than make up for in security.



Spring's goal is to make Java/J2EE development easier by reducing or eliminating the plumbing code that developers have to write so that they can focus on what is specific to their application. Spring's approach is to be as totally non-invasive as possible so you are not likely to see this type of enforcement in Spring itself. If Spring did this, it would simply make more it difficult to use with developer power tools like reflection, ORM, AOP, etc. That shouldn't stop you from developing your own style and process and solving this problem in the way that's most suitable for your own organization.

Have fun with all the Spring mini-frameworks. Because of its non-invasiveness, you can choose at which levels you are willing to incur a dependency on Spring itself. It will make your life easier once you learn how to use them. You will find that the documentation including Javadocs are some of the best around and the Spring community is a real helpful bunch just like here at the ranch. Enjoy.

[ January 25, 2005: Message edited by: Ken Krebs ]
[ January 25, 2005: Message edited by: Ken Krebs ]
+Pie Number of slices to send: Send
Hi Chris,
We use Struts & Spring together & they work fine. Although we could ditch Struts & just use Spring, we've kept Struts going for the presentation layer 'cos thats what the developers here fell confortable with.
I don't understand half of what is available in Spring - its impossible to keep up with the lastest release - but this doesn't stop us from exploiting it as an IoC framework. I'm currently re-reading Rods books & the online docs to find out what else we can use, and am looking forward to the official book thats scheduled for publication later in the year. Until then, I'm happy that it does what we need it to & does it very well - we're probably just not using it as efficiently as we could.
(btw, it was really noddy-like to get going & once you've got a vertical slice working, adding new functionality is a peice of cake).

Regards,
Louise
+Pie Number of slices to send: Send
 

Originally posted by louise rochford:
Hi Chris,
We use Struts & Spring together & they work fine.
Louise



I havent gone beyong looking at spring config file for DI. It would be great if you document your experiences of specifiying all dependencies in a config file. Is the program/use case flow clear when say working with eclipse. Do developers go back and forth between the config file and source code? Do you express all your dependencies in the xml file?
I figure that there are options to do all kinds of wiring, say initializng a map, a list and what not. What kind of features did you guys ended up using?
Did it get cluttered and did you separate them to different files?
Spring class names are so long ..I dont remember seeing such long names anywhere else.
+Pie Number of slices to send: Send
Any open source tool is available for Spring(like StrutsConsole / MyEclipse / StrutsStudio for Struts)?
+Pie Number of slices to send: Send
Karthik / Kri,

I haven't found it any more confusing than previous projects without Spring. I guess that we quickly got into quite a prescribed project structure.
We've seperate xml files for the business layer & the DAO layer, plus a generic xml context for odds & ends like the datasource definition. They all get loaded on servlet init & saved along with the servlet context.

To add a new function, the developers all know that they have to create so many Struts Actions & forms, a business object, and a DAO. The domain / model objects tend to get modelled up front & refactored as neccessary - these aren't specified via Spring config files at the moment - something I want to change in the near future. All the code is written to interfaces & the actual implementing classes are specified in the xml.

We did make an attempt to use an eclipse plugin for xml manipulation but it didn't seem to work properly. We're using WSAD rather than basic eclipse & have had problems with other plugins to WSAD, so it probably wasn't the fault of the plugin! It was over a year ago, so things have probably advanced by now & the plugin might add more value. Manipulating the file in its raw state hasn't been a problem though...

Hope this helps - I'm not sure exactly what you'd like to know - if I can be more help let me know.

Regards,
Louise
+Pie Number of slices to send: Send
 

Originally posted by kri shan:
Any open source tool is available for Spring(like StrutsConsole / MyEclipse / StrutsStudio for Struts)?


The project's website lists an Eclipse plugin right on the frontpage.
+Pie Number of slices to send: Send
Spring framework was long awaited. If I have to pick one reason that's I hate having ActionForms. Not only action forms need to extend a class you also need to have your action form elements as strings. If you don't have the elements as strings you need to put some convoluted logic (refer struts live book) to handle validation.

Secondary hibernate and other O/R persistence tools have become industry ready and struts was developed long before hibernate came. Spring provides nice abstraction and reduces the database access code by 70%.
+Pie Number of slices to send: Send
Now that I have sung the praises of SpringMVC because it eliminates the need for ActionForms by working directly with the domain object, I must also provide a word of caution.

WARNING: A malicious user could potentially subvert your domain object by injecting parameters for fields or properties that do not exist on the form into the HTTP request. This possibility must be dealt with by the application developer. With Struts, the ActionForm acts as a guard by requiring explicit handling of each parameter/form field. With Spring, it can be handled by customizing the setup of the object that binds the parameters to the command object properties (and its nested properties).

All form controllers in Spring inherit the initBinder method from BaseCommandController. initBinder is normally overridden when setting up a special property editor like a specially formatted Date field, etc. The binder has a method, setAllowedFields that allows you to specify a String[] that contains the field names that can be bound. It supports "xxx*" and "*xxx" patterns. More sophisticated matching can be implemented by overriding the binder's isAllowed method. It is best practice to make sure that this is correctly done by writing a unit test for your controller that verifies this behavior.

[ February 16, 2005: Message edited by: Ken Krebs ]
[ February 16, 2005: Message edited by: Ken Krebs ]
+Pie Number of slices to send: Send
 

Originally posted by Ken Krebs:
A malicious user could potentially subvert your domain object by injecting parameters for fields or properties that do not exist on the form into the HTTP request. This possibility must be dealt with by the application developer. With Struts, the ActionForm acts as a guard by requiring explicit handling of each parameter/form field. With Spring, it can be handled by customizing the setup of the object that binds the parameters to the command object properties (and its nested properties).


Does anyone know if this is being worked on? I'd imagine it shouldn't be a big (relatively speaking) deal to put in a facility for enumerating the allowed fields on the server-side (a bit like DynaActionForms in Struts but with support for pattern matching, perhaps?).
+Pie Number of slices to send: Send
Lasse,

originally posted by Ken Krebs:
A malicious user could potentially subvert your domain object by injecting parameters for fields or properties that do not exist on the form into the HTTP request. This possibility must be dealt with by the application developer. With Struts, the ActionForm acts as a guard by requiring explicit handling of each parameter/form field. With Spring, it can be handled by customizing the setup of the object that binds the parameters to the command object properties (and its nested properties).


Does anyone know if this is being worked on?



Not sure what you mean by that. The paragraph following the WARNING describes how to deal with the problem.
[ February 22, 2005: Message edited by: Ken Krebs ]
+Pie Number of slices to send: Send
Ken, I meant whether someone is (or has) working on implementing the "customizing the setup of the object that binds the parameters to the command object properties" into the framework so that application developers don't have to do that themselves.
+Pie Number of slices to send: Send
Lasse, I don't know how the framework could know what the developer's intent is in terms of properties to be set on the form. It is, after all, a pretty simple thing for the developer to do. What probably does need improving is communicating this potential problem to developers.
+Pie Number of slices to send: Send
I guess there is not that much I can add to this discussion other than to say that both Pro Spring and Spring Live are excellent resources for people looking at Spring with/versus Struts.

Rob
Seriously Rick? Seriously? You might as well just read this tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com


reply
reply
This thread has been viewed 5792 times.
Similar Threads
utility of Tiles for JSP layout
What to do next?
GWT, Maven 2, Eclipse, Spring, Hibernate advice
Why Jakarta Struts?
Which web app framework would you choose for an enterprise environment?
More...

All times above are in ranch (not your local) time.
The current ranch time is
Mar 28, 2024 09:06:13.