Monday, 5 August 2013

Struts to Spring mvc migration

Hi Friends,

Now I will share you step by step approach to migrate application from Struts 1.2 to Spring 3 using annotations.In struts to spring migration libraries, action classes, config files and jsp's will get changed as explained below :


STEP 1 : Replace struts libraries with spring libraries.


First step while migrating from struts to spring is replace your struts related libraries with spring libraries in lib folder. I have mentioned basic libraries of both stuts and spring for your clarification.

Struts basic libraries :
     1. struts.jar
     2. struts-legacy.jar
     etc.. 

Spring basic libraries :
     1. standard.jar
     2. org.springframework.asm-3.0.1.RELEASE-A.jar
     3. org.springframework.beans-3.0.1.RELEASE-A.jar
     4. org.springframework.context-3.0.1.RELEASE-A.jar
     5. org.springframework.core-3.0.1.RELEASE-A.jar
     6. org.springframework.expression-3.0.1.RELEASE-A.jar
     7. org.springframework.web.servlet-3.0.1.RELEASE-A.jar
     8. org.springframework.web-3.0.1.RELEASE-A.jar
     etc..

About *.tld's used in struts application, many tutorials on web says that it will remain same. Which makes me little unconfortable, as we are having some tld's which are solely used by struts. So we need to replace those struts tlds also. Following are the possible tld's which are need to be removed :

 <taglib>

<taglib-uri>tiles</taglib-uri>
<taglib-location>/WEB-INF/taglib/struts-tiles-1.1.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>nested</taglib-uri>
<taglib-location>/WEB-INF/taglib/struts-nested-1.1.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>logic</taglib-uri>
<taglib-location>/WEB-INF/taglib/struts-logic-1.1.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>html</taglib-uri>
<taglib-location>/WEB-INF/taglib/struts-html-1.1.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>bean</taglib-uri>
<taglib-location>/WEB-INF/taglib/struts-bean-1.1.tld</taglib-location>
</taglib>

We need to change tld's with spring tags, which I will explain in upcoming step for jsp.


STEP 2 : Change in web.xml file for struts to spring migration


In this step, we are going to change intializing of struts config file with spring's confing file.

In Struts :
  We initialize config for struts in following way, which need to be replace :

<servlet>
        <servlet-name>action</servlet-name>
        <servlet-class>
            org.apache.struts.action.ActionServlet
        </servlet-class>
        <init-param>
            <param-name>config</param-name>
            <param-value>/WEB-INF/struts-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>


In Spring :
   We initialize config for spring in following way :

   <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>

 

STEP 3 : Replace config files for struts to spring migration


Now it comes the replacement of config files from struts to spring.
In Struts :
   We use struts-confing.xml as config file for dispatching request.
<struts-config>
    <form-beans>
        <form-bean name="LoginForm"
            type="xyz.struts.helloworld.form.LoginForm" />
    </form-beans>
  
    <global-exceptions>
    </global-exceptions>
    <global-forwards></global-forwards>
  
    <action-mappings>
        <action path="/login" name="LoginForm" validate="true" input="/index.jsp" 
            type="xyz.struts.helloworld.action.LoginAction">
            <forward name="success" path="/welcome.jsp" />
            <forward name="failure" path="/index.jsp" />
        </action>
    </action-mappings>
    <message-resources parameter="resource.MessageResource"></message-resources>
</struts-config>
In Spring :
   We will use spring-servlet.xml. Here name for confign is generated as [servlet-name]-servlet.xml. And servlet-name is mentioned in web.xm, here we have used spring.
 <context:component-scan
        base-package="xyz.spring3.controller" />
          
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>
 Here, <context:component-scan> tag is used, so that spring will load all the components from given package i.e. "xyz.spring3.controller"
We can use different view resolvers, here I have used UrlBasedViewResolver. In which prefix and suffix are used to resolve the view by prefixing and suffixing values to the object returned by ModelAndView in action class.

 

STEP 4 : JSP changes for struts to spring migration


While migrating application from struts to spring, we need many changes in Jsp's. Which include tags replacement, tld's replacement and some other things as explained below :

1. tld replacement :

As I said earlier in step 1, we need to remove tld's of struts. So following entries in jsp's will be removed :

<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>
<%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles" %>

Replace these with following spring taglib's :

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>

We have removed taglib declarations. Now it's time for replacing its tags according to spring or normal html standards, as below :
                        STRUTS
                   SPRING (corresponding tag)
 <html:html>
<html> 
 <html:form>
<form:form> 
 <html:error>
<form:errors> 
 <html:text property="abc">
 <form:input path="abc">
<html:select property="abc">
      <option value="one">
<form:select path="abc">
     <option value="one">
<html:submit>
<input type="submit"> 
 <bean:message bundle="resource" key="abc">
<spring:message code="abc"> 
<html:checkbox property="abc">
<form:checkbox path="abc">
These are the mostly used tags. The list will go on...

Now next is the calling action from jsp. For this, we need to change form tag as below :

In Struts :

<html:form action="/addStudent" method="post">

In Spring :

<form:form method="POST" commandName="studentForm" name="studentForm" action="addStudent.do">


Here commandName is going to map with corresponding formbean for that jsp. Next we will see, how action is getting called with spring 3 annotations.  (Remeber that we have removed struts-config.xml, so we don't have any mapping against action mention here)



STEP 5 : Action class changes for struts to spring migration


 Now following changes need to be done in action classes for struts to spring migration using annotations :



Struts action
Spring action
(corresponding replacement)
extends Action
@controller annotation above class declaration
public ActionForward execute(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
               throws Exception {
@RequestMapping("/addStudent.do")
@RequestMapping(method = { RequestMethod.GET, RequestMethod.POST })

public ModelAndView execute (HttpServletRequest request,
  HttpServletResponse response,
 @Valid @ModelAttribute("studentForm")        studentForm studentForm,
  BindingResult bindingResult)
throws Exception {

Here, in @RequestMapping annotation, action is getting mapped to corresponding action mentioned in jsp.
And in @ModelAttribute annotation, form is getting mapped which should be same as that of mentioned in commandName in jsp.
forward = mapping.findForward(“success”);
modelMap.put("studentForm",   studentForm);
return (new ModelAndView(“success”, modelMap));



Imports tobe added in Spring application :

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

 

STEP 6 : Validation changes for struts to spring migration

Step 6-1 : Changes in jsp

In Struts :
We add following line for instantiating actionErrors :
<%
 ActionErrors actionErrors = (ActionErrors)request.getAttribute("org.apache.struts.action.ERROR");
%>
This line will get removed in Spring application.
In Struts we use following tag for displaying error message :
<html:errors bundle="resource"/>
In Spring :
In Spring we use following tag for displaying error message :

<form:errors path="*" cssClass="error" />  
Here, in cssClass 'error', you can define css properties for error messages to display.

 Step 6-1 : Changes in Action class

In Struts :
Method signature as :
public ActionForward execute(
  ActionMapping mapping,
  ActionForm form,
  HttpServletRequest request,
  HttpServletResponse response)
  throws Exception {
For capturing errors :
   ActionErrors errors = new ActionErrors();
  ActionForward forward = new ActionForward();
   errors.add("name", new ActionMessage("id"));
In Spring :
Add following imports :
        import javax.validation.Valid; 
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.validation.BindingResult;
Create one instance of your formbean and aurowire it, as follow:
  public StudentForm studentFormValidator;
 @Autowired
 public void setStudentFormValidator(
   StudentForm studentFormValidator) {
  this.studentFormValidator = studentFormValidator;
 }
Method signature :
public ModelAndView execute(
   HttpServletRequest request,
   HttpServletResponse response,
   @Valid @ModelAttribute("StudentForm") StudentForm studentForm,
   BindingResult result) throws Exception {
For capturing errors, call a validate method at the start of business logic as :
 studentFormValidator.validate(studentForm, result, request);
Here, we need to create one validate method in form bean :
public void validate(Object object, Errors errors, HttpServletRequest request) {
--
if(condition){
 ---
}else{
errors.reject("error.fail"); 
}
Note : considering messages are stoared in applicationResources.properties
Here, we will get result of validation in 'result' parameter.
Now, you can proceed for business logic as :
if (!result.hasErrors()) {
--
//business logic goes here
--
}else{
forward = "failure";
modelMap.put("studentForm", studentForm);
return (new ModelAndView(“failure”, modelMap));
}
And and here we done with basic migration. Hope it will help you.



You may also like to read :

 

Addition or removal of element in list while iterating 
Java / J2ee interview questions for experience java developer

16 comments:

  1. Thanks for sharing such useful information :)
    We will surely use this approach... !!!

    ReplyDelete
  2. Helpful post, please post your thoughts on a replacement for Structs ActionMessage when used to display success messages.

    ReplyDelete
  3. can anybody tell how to convert the bean tags and html:link tags to spring

    ReplyDelete
  4. It’s a nice blog posted by you. I was seeking for this type of blog that have a fresh and interesting content.

    Java spring developers

    ReplyDelete
  5. Hi, great post.
    Where have you defined "success" and "failure" in the spring ModelAndView? Are the jsps renamed from welcome.jsp in Struts to success.jsp in Spring?

    ReplyDelete
    Replies
    1. hey thnkx for pointing it out.. in spring you have to actually pass jsp name instead of "success" or "failure" word. I have mentioned these words in blog, just for understanding purpose.

      Delete
  6. <%@ taglib uri="http://struts.apache.org/tags-html-noac" prefix="noac"%>

    Iam having the above tag in my jsp file. How can I change it

    ReplyDelete
  7. Thanks For sharing this. Its looking good

    ReplyDelete
  8. Superb. I really enjoyed very much with this article here. Really it is an amazing article I had ever read. I hope it will help a lot for all. Thank you so much for this amazing posts and please keep update like this excellent article. thank you for sharing such a great blog with us.
    microsoft azure training in bangalore
    rpa training in bangalore
    rpa training in pune
    best rpa training in bangalore

    ReplyDelete
  9. Write more; that’s all I have to say. It seems as though you relied on the video to make your point. You know what you’re talking about, why waste your intelligence on just posting videos to your blog when you could be giving us something enlightening to read?
    Python training in bangalore
    Python course in pune
    Python training in bangalore

    ReplyDelete
  10. Thanks for posting this info. I just want to let you know that I just check out your site and I find it very interesting and informative. I can't wait to read lots of your posts. https://jsongrid.com/json-formatter

    ReplyDelete
  11. I like your articles so much. Please keep writing . Do US people need a visa to Turkey from USA . Yes of course, the US is not included in the list of those countries which do not require a visa to visit in turkey.

    ReplyDelete