Three ways to integrate Struts applications with Spring __spring

Source: Internet
Author: User
Tags aop new set

Three ways to integrate Struts applications with Spring

Franciscus, co-author of Struts Recipes, will introduce another major struts consolidation tip.

This time, the Struts application is imported into the Spring framework.

Follow George, who will show you how to change the struts action so that the management struts action is like managing Spring beans.

The result is an enhanced web framework that makes it easy to take advantage of Spring AOP.

You must have heard of the control reversal (IOC) design pattern, because it has been spreading information about it for a long time.

If you have used the Spring framework in any feature, you know how it works.

In this article, I use this principle to inject a Struts application into the Spring framework, and you will experience the strength of the IOC model.

Consolidating a Struts application into the Spring framework has many advantages.

First, Spring is designed to solve some real world problems with JEE, such as complexity, low performance and testability, and so on.

Second, the Spring framework contains an AOP implementation that allows you to apply aspect-oriented techniques to object-oriented code.

Third, some people may say that the Spring framework only handles struts better than struts handles itself.

But that's the point of view, and I'm going to show you three ways to consolidate the Struts application into the Spring framework, and you decide which one to use.

The methods I have demonstrated are relatively simple to perform, but they have distinct advantages.

I created an independent and usable example for each method so that you can fully understand each method.

See the download section for a complete example source code.

See Resources for a download of Struts MVC and the Spring framework.

Why Spring is so great.

Spring's founder Rod Johnson takes a critical look at Java™ enterprise software development and proposes that many enterprise challenges can be addressed strategically using the IOC model, also known as dependency injection.

When Rod and a dedicated open source developer team applied the theory to practice, the results produced the Spring framework.

In short, Spring is a lightweight container that allows you to easily connect objects together using an external XML configuration file.

Each object can receive a reference to a dependent object by displaying a JavaBean property, and the simple task left to you is simply to connect them in an XML configuration file.

IOC and SPRINGIOC are design patterns that make application logic externalized, so it is injected rather than written into the client code.

Combining IOC with interface programming applications, like the Spring framework, produces a architecture that reduces the client's reliance on specific implementation logic. See Resources for more information on IOC and Spring.

Dependency Injection is a powerful feature, but the Spring framework can provide more features.

Spring supports pluggable transaction managers, which can provide a broader range of choices for your transactions.

It integrates the leading persistence framework and provides a consistent exception hierarchy.

Spring also provides a simple mechanism for using aspect-oriented code instead of normal object-oriented code.

Spring AOP allows you to use interceptors to intercept application logic at one or more execution points.

Enhancing the logging logic of applications in interceptors results in a more readable and useful code base, so interceptors are widely used in logging.

You'll soon see that Spring AOP publishes its own interceptors to handle crosscutting concerns, and you can write your own interceptors.

Consolidation struts and spring are similar to struts, and spring can be implemented as an MVC.

Both of these frameworks have their own advantages and disadvantages, although most people agree that Struts is still the best in MVC.

Many development teams have learned to use Struts as the basis for structuring high-quality software when time is pressing.

Struts has so much impetus that the development team prefers to integrate the features of the spring framework rather than convert it into spring MVC.

It is good news for you that there is no need to convert.

The spring schema allows you to connect Struts as a WEB framework to the business and persistence layer based on Spring.

The final result is that now all the conditions are available.

In the next few tricks, you'll learn three ways to consolidate Struts MVC into the Spring framework.

I will reveal the flaws of each method and compare their advantages.

Once you understand the usefulness of all three methods, I'll show you an exciting application that uses one of the three methods I like best.

Three tips each of the next integration techniques (or tips) has its own advantages and characteristics.

I prefer one of these, but I know that all three of these can deepen your understanding of Struts and Spring.

This will give you a broad range of choices when dealing with different situations.

The method is as follows: Using Spring's Actionsupport class to consolidate structs use spring's delegatingrequestprocessor overlay struts's requestprocessor will struts Act Ion management delegate to the spring framework mount an application environment whatever technology you use, you need to use spring's contextloaderplugin to load the spring application environment for Struts's actionservlet. Simply add the plugin to your struts-config.xml file just as you would any other plugin.

As follows: Program code: <plug-in classname= "Org.springframework.web.struts.ContextLoaderPlugIn" > <set-property Property= "Contextconfiglocation" value= "/web-inf/beans.xml"/> </plug-in>

As mentioned earlier, in the Downloads section, you can find the complete source code for these three fully available examples.

Each example provides a different way of consolidating Struts and Spring for a book Search application. You can see the main points of the example here, but you can also download the application to see all the details.

Tip 1. Using spring's actionsupport to manually create a spring environment is the most intuitive way to consolidate Struts and spring.

To make it simpler, Spring provides some help. For easy access to the Spring environment, the Org.springframework.web.struts.ActionSupport class provides a Getwebapplicationcontext () method.

All you do is extend your actions from Spring's actionsupport instead of the Struts action class, as shown in Listing 1:

Listing 1. Use Actionsupport to consolidate struts  program code: Package ca.nexcel.books.actions; Import java.io.IOException; Import javax.servlet.ServletException; Import Javax.servlet.http.HttpServletRequest; Import Javax.servlet.http.HttpServletResponse; Import Org.apache.struts.action.ActionError; Import org.apache.struts.action.ActionErrors; Import Org.apache.struts.action.ActionForm; Import Org.apache.struts.action.ActionForward; Import org.apache.struts.action.ActionMapping; Import Org.apache.struts.action.DynaActionForm; Import Org.springframework.context.ApplicationContext; Import Org.springframework.web.struts.ActionSupport; Import Ca.nexcel.books.beans.Book; Import Ca.nexcel.books.business.BookService; public class Searchsubmit extends Actionsupport {| ( 1 public Actionforward Execute (actionmapping mapping, actionform form, httpservletrequest request, HttpServletResponse Response) throws IOException, servletexception {dynaactionform searchform = (dynaactionform) Form; String ISBN = (string) SeaRchform.get ("ISBN"); The old fashion way//bookservice bookservice = new Bookserviceimpl (); ApplicationContext CTX = Getwebapplicationcontext (); | (2) Bookservice Bookservice = (bookservice) ctx.getbean ("Bookservice"); | (3) Book book = Bookservice.read (Isbn.trim ()); if (null = = book) {actionerrors errors = new Actionerrors (); Errors.add (Actionerrors.global_error,new actionerror ("Messa Ge.notfound ")); Saveerrors (request, errors); Return Mapping.findforward ("failure"); } request.setattribute ("book", book); Return Mapping.findforward ("Success"); Let's take a quick look at what's going on here.

at (1), I created a new action by extending from the Actionsupport class of Spring instead of the action class of Struts.

At (2), I use the Getwebapplicationcontext () method to obtain a applicationcontext. To obtain business services, I used the environment obtained at (2) to find a Spring bean at (3).

This technique is simple and easy to understand. Unfortunately, it is coupling the Struts action with the Spring framework. If you want to replace Spring, you must rewrite the code. Also, because the Struts action is not under spring control, it does not have the advantage of Spring AOP. This technique may be useful when using multiple independent Spring environments, but in most cases this approach is not as appropriate as the other two approaches.

Tip 2. Overlay requestprocessor separating Spring from the Struts action is a more ingenious design choice. One way to detach is to use the Org.springframework.web.struts.DelegatingRequestProcessor class to override the Requestprocessor handler for struts,

As shown in Listing 2: Listing 2. Integration program code through Spring delegatingrequestprocessor <?xml version= "1.0" encoding= "Iso-8859-1"?> DOCTYPE struts-config Public "-//apache Software foundation//dtd struts Configuration 1.1//en" "http:// Jakarta.apache.org/struts/dtds/struts-config_1_1.dtd "> <struts-config> <form-beans> <form-bean Name= "Searchform" type= "Org.apache.struts.validator.DynaValidatorForm" > <form-property name= "ISBN" type= " Java.lang.String "/> </form-bean> </form-beans> <global-forwards type=" Org.apache.struts.action.ActionForward "> <forward name=" Welcome "path="/welcome.do "/> <forward-name=" Searchentry "path="/searchentry.do "/> <forward name=" Searchsubmit "path="/searchsubmit.do "/> </ global-forwards> <action-mappings> <action path= "/welcome" forward= "/web-inf/pages/welcome.htm"/> <action path= "/searchentry" forward= "/web-inf/pages/search.jsp"/> <action path= "/searchSubmit" Ca.nexcel.books.actions. Searchsubmit "input="/searchentry.do "validate=" true "Name=" Searchform "> <forward name=" Success "path="/ web-inf/pages/detail.jsp "/> <forward name= Failure" path= "/web-inf/pages/search.jsp"/> </action> </action-mappings> <message-resources parameter= "applicationresources"/> <controller processorclass = "Org.springframework.web.struts." Delegatingrequestprocessor "/> | (1) <plug-in classname= "Org.apache.struts.validator.ValidatorPlugIn" > <set-property property= "pathnames" Value= "/web-inf/validator-rules.xml,/web-inf/validation.xml"/> </plug-in> <plug-in classname= " Org.springframework.web.struts.ContextLoaderPlugIn "> <set-property property=" csntextconfiglocation "value=" /web-inf/beans.xml "/> </plug-in> </struts-config> I used the <controller> tag to use Delegatingrequestprocessor overrides the default Struts requestprocessor.

The next step is to register the action in my spring configuration file, as shown in Listing 3: Listing 3. Registers an action program code in the spring configuration file <?xml version= "1.0" encoding= "UTF-8"?> DOCTYPE beans Public "-//spring//dtd bean//en" "Springframework.org/dtd/spring-beans.dtd" target= "_blank" >http:// Www.springframework.org/dtd/spring-beans.dtd "> <beans> <bean id=" Bookservice "class=" Ca.nexcel.books.business.BookServiceImpl "/> <bean name="/searchsubmit "class=" Ca.nexcel.books.actions.SearchSubmit "> | (1) <property name= "Bookservice" > <ref bean= "bookservice"/> </property> </bean> </beans >

Note: at (1), I registered a bean with the name attribute to match the Struts-config action map name. The Searchsubmit action reveals a JavaBean property that allows Spring to populate the property at run time, as shown in Listing 4: Listing 4. Struts Action Program code with JavaBean attribute package ca.nexcel.books.actions; Import java.io.IOException; Import javax.servlet.ServletException; Import Javax.servlet.http.HttpServletRequest; Import Javax.servlet.http.HttpServletResponse; Import org.apache.struts.action.Action; Import Org.apache.struts.action.ActionError; Import org.apache.struts.action.ActionErrors; Import Org.apache.struts.action.ActionForm; Import Org.apache.struts.action.ActionForward; Import org.apache.struts.action.ActionMapping; Import Org.apache.struts.action.DynaActionForm; Import Ca.nexcel.books.beans.Book; Import Ca.nexcel.books.business.BookService; public class Searchsubmit extends Action {private Bookservice bookservice, public bookservice Getbookservice () {return B Ookservice; } public void Setbookservice (Bookservice bookservice) {| (1) this.bookservice = Bookservice; Public Actionforward Execute ( actionmapping mapping, Actionform form, httpservletrequest request, httpservletresponse response) throws IOException, Se rvletexception {Dynaactionform searchform = (dynaactionform) Form; String ISBN = (string) searchform.get ("ISBN"); Book book = Getbookservice (). Read (Isbn.trim ()); (2) if (null = = book) {actionerrors errors = new Actionerrors (); Errors.add (Actionerrors.global_error,new actionerror ("Me Ssage.notfound ")); Saveerrors (request, errors); Return Mapping.findforward ("failure"); } request.setattribute ("book", book); Return Mapping.findforward ("Success"); } }

In Listing 4, you can learn how to create a Struts action. at (1), I created a JavaBean property. Delegatingrequestprocessor automatically configures this property. This design makes the Struts action unaware that it is being managed by Spring and enables you to take advantage of all the benefits of the Sping Action management framework.

Because your struts action does not notice the presence of spring, you do not need to rewrite your struts code to replace spring with other control reversal containers. Delegatingrequestprocessor method is better than the first method, but there are still some problems.

If you use a different requestprocessor, you need to manually integrate the Spring delegatingrequestprocessor. Adding code can cause maintenance headaches and will reduce the flexibility of your application in the future.

In addition, there are rumors of a series of commands to replace Struts requestprocessor. This change will have a negative impact on the longevity of the solution. Tip 3. Delegating action Management to spring a better solution is to delegate strut action management to spring. You can do this by registering an agent in the Struts-config action map.

The agent is responsible for finding Struts actions in the Spring environment. Because the action is under Spring's control, it can populate the JavaBean properties of the action and make it possible to apply features such as spring's AOP interceptor.

The Action class in Listing 5 is the same as in Listing 4. But Struts-config has some differences: Listing 5. Spring Consolidated Delegate Method program code <?xml version= "1.0" encoding= "iso-8859-1"?> <! DOCTYPE struts-config Public "-//apache Software foundation//dtd struts Configuration 1.1//en" "http:// Jakarta.apache.org/struts/dtds/struts-config_1_1.dtd "> <struts-config> <form-beans> <form-bean Name= "Searchform" type= "Org.apache.struts.validator.DynaValidatorForm" > <form-property name= "ISBN" type= " Java.lang.String "/> </form-bean> </form-beans> <global-forwards type=" Org.apache.struts.action.ActionForward "> <forward name=" Welcome "path="/welcome.do "/> <forward-name=" Searchentry "path="/searchentry.do "/> <forward name=" Searchsubmit "path="/searchsubmit.do "/> </ global-forwards> <action-mappings> <action path= "/welcome" forward= "/web-inf/pages/welcome.htm"/> <action path= "/searchentry" forward= "/web-inf/pages/search.jsp"/> <action path= "/searchSubmit" Org.springfRamework.web.struts.DelegatingActionProxy "| (1) input= "/searchentry.do" validate= "true" Name= "Searchform" > <forward name= "Success" Path= "/web-inf/pages/" detail.jsp "/> <forward name= Failure" path= "/web-inf/pages/search.jsp"/> </action> </ action-mappings> <message-resources parameter= "applicationresources"/> <plug-in " Org.apache.struts.validator.ValidatorPlugIn "> <set-property property=" pathnames "value="/web-inf/ Validator-rules.xml,/web-inf/validation.xml "/> </plug-in> <plug-in classname=" Org.springframework.web.struts.ContextLoaderPlugIn "> <set-property property=" contextconfiglocation "value=" /web-inf/beans.xml "/> </plug-in> </struts-config>

Listing 5 is a typical struts-config.xml file, with only one small difference. It registers the name of the Spring proxy class rather than the name of the class that declares the action, as shown in (1).

The Delegatingactionproxy class uses action map names to find actions in the Spring environment. This is the environment in which we use the Contextloaderplugin declaration.

Registering a Struts action as a Spring bean is straightforward, as shown in Listing 6.

I used the action map to simply create a bean using the <bean> tag's name attribute (in this case, "/searchsubmit").

The JavaBean property of this action is populated like any Spring bean: Listing 6. Registers a Struts action program code in the Spring environment <?xml version= "1.0" encoding= "UTF-8"?> <! DOCTYPE beans Public "-//spring//dtd bean//en" "Springframework.org/dtd/spring-beans.dtd" target= "_blank" >http:// Www.springframework.org/dtd/spring-beans.dtd "> <beans> <bean id=" Bookservice "class=" Ca.nexcel.books.business.BookServiceImpl "/> <bean name="/searchsubmit "class=" Ca.nexcel.books.actions.SearchSubmit "> <property name=" bookservice "> <ref bean=" bookservice "/> </ property> </bean> </beans> Action Delegate The best of these three methods is the action delegate solution.

The Struts action does not understand spring and does not make any changes to the code for use in non-Spring applications.

Requestprocessor changes will not affect it, and it can take advantage of the Spring AOP features.

The advantages of an action delegate are more than that. Once you have spring control over your Struts action, you can use spring to add more energy to the action.

For example, without Spring, all Struts actions must be thread-safe. If you set the <bean> tag's Singleton property to False, your application will have a newly generated action object on each request, regardless of the method. You may not need this feature, but it's also good to put it in your toolbox. You can also take advantage of Spring's lifecycle approach.

For example, the Init-method property of the,<bean> tag is used to run a method when the Struts action is instantiated. Similarly, the Destroy-method property executes a method before the bean is deleted from the container. These methods are a good way to manage expensive objects, and they are managed in the same way as the Servlet lifecycle.

Intercept struts as mentioned earlier, one of the main advantages of consolidating struts and spring by delegating the struts action to the spring framework is that you can apply the spring AOP interceptor to your struts action.

By applying the Spring interceptor to the Struts action, you can handle crosscutting concerns with minimal cost. Although Spring offers a number of built-in interceptors, I'll show you how to create your own interceptor and apply it to a Struts action.

To use interceptors, you need to do three things: Create interceptors. Register the Interceptor. declares where to intercept the code.

This seemingly very simple few words are very powerful. For example, in Listing 7, I created a logging interceptor for the Struts action. This interceptor prints one sentence before each method call: Listing 7. A simple Logger Interceptor program code package ca.nexcel.books.interceptors; Import Org.springframework.aop.MethodBeforeAdvice; Import Java.lang.reflect.Method; public class Logginginterceptor implements Methodbeforeadvice {public void before (method method, object[] objects, Object O) throws Throwable {System.out.println ("Logging before!");} This interceptor is very simple.

The Before () method runs before each method in the intercept point. In this case, it prints out a word, in fact it can do anything you want to do.

The next step is to register the interceptor in the Spring configuration file, as shown in Listing 8: Listing 8. Registers the Interceptor program code in the Spring configuration file <?xml version= "1.0" encoding= "UTF-8"?> <! DOCTYPE beans Public "-//spring//dtd bean//en" "Springframework.org/dtd/spring-beans.dtd" target= "_blank" >http:// Www.springframework.org/dtd/spring-beans.dtd "> <beans> <bean id=" Bookservice "class=" Ca.nexcel.books.business.BookServiceImpl "/> <bean name="/searchsubmit "class=" Ca.nexcel.books.actions.SearchSubmit "> <property name=" bookservice "> <ref bean=" bookservice "/> </ Property> </bean> <!--interceptors--> <bean name= "Logger" class= " Ca.nexcel.books.interceptors.LoggingInterceptor "/> | (1) <!--autoproxies--> <bean name= "Loggingautoproxy" class=. Beannameautoproxycreator "> | (2) <property name= "Beannames" > <value>/searchSubmit</valuesgt; | (3) </property> <property name= "Interceptornames" > <list> <value>logger</value> | (4) </list> </property> </bean> </beans> As you may have noticed, listing 8 expands the application shown in Listing 6 to include an interceptor. The details are as follows: at (1), I registered this interceptor. At (2), I created a bean name Auto broker, which describes how to apply interceptors. There are other ways to define intercept points, but this is a common and simple method. At (3), I registered the Struts action as the bean to be intercepted. If you want to intercept other Struts actions, you only need to create additional <value> tags under "beannames". At (4), when the interception occurred, I performed the name of the Interceptor Bean created at (1). All of the interceptors listed here apply to "Beannames". That's it. As this example shows, placing your struts action under the control of the Spring framework provides a whole new set of choices for handling your struts application.

In this example, the use of action delegates makes it easy to use the Spring interceptor to improve logging capabilities in a Struts application.

Conclusion

In this article, you've learned three tips for consolidating the Struts action into the Spring framework.

Using spring's actionsupport to consolidate struts (which is what the first trick does) is simple and quick, but it combines the Struts action with the spring framework. If you need to migrate your application to a different framework, you need to rewrite the code.

The second solution cleverly unlocks the coupling of the code through the delegate requestprocessor, but its scalability is not strong, and when Struts's Requestprocessor becomes a series of commands, this approach does not last much longer.

The third approach is the best of the three methods: delegating the struts action to the spring framework can decouple the code, allowing you to take advantage of Spring's features (such as logging interceptors) in your Struts application.

Each of the three Struts-spring integration tips is implemented as a fully available application. See the Downloads section for a closer look at them.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.