Announcement Announcement Module
Collapse
No announcement yet.
Why IOC couldn't be used in Spring successfully? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Why IOC couldn't be used in Spring successfully?

    Hi friends !

    I want to use IOC in my servlet in springframework. But what I get Ioc bean is null! If I get Bean Object ,Tomcat will throws NullPointerException!
    For example,My servlet is:
    Code:
    /*
     * Created on 2004-6-27
     *
     * To change the template for this generated file go to
     * Window>Preferences>Java>Code Generation>Code and Comments
     */
    package lyo.test.servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Iterator;
    import java.util.List;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import lyo.test.bean.*;
    import lyo.test.dao.*;
    import lyo.test.bussiness.*;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.FileSystemXmlApplicationContext;
    import org.springframework.beans.factory.BeanFactory;
    
    /**
     * @author Administrator
     *
     * To change the template for this generated type comment go to
     * Window>Preferences>Java>Code Generation>Code and Comments
     */
    public class UserActionServlet extends HttpServlet {
    	
    	private static Log log=LogFactory.getLog(UserActionServlet.class);
    	
    	private ParentDAO pdao;
    	
    	public void setPdao(ParentDAO pdao){
    		this.pdao=pdao;
    	}
    	public ParentDAO getPdao(){
    		return this.pdao;
    	}
    	
    	public void doGet(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{
                 doPost(req,resp);
       } 
       public void doPost(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{
       			PrintWriter pw=null;
    		resp.setContentType("text/html;charset=gb2312");
    		
    	     String sonname=req.getParameter("sonname");
    	     String parentname=req.getParameter("parentname");
    	     String parentid=req.getParameter("pid");
        &#91;b&#93;ParentDAO pdao=this.getPdao&#40;&#41;;&#91;/b&#93; <--NullPointerException    
    	     Parent p=new Parent&#40;&#41;;
    	     p.setName&#40;parentname&#41;;
    	    	    log.info&#40;"Get pdao --> "+this.getPdao&#40;&#41;&#41;;
    	     Long id=pdao.saveParent&#40;p&#41;;
    	     log.info&#40;"get id&#58; "+id&#41;;
    	     req.setAttribute&#40;"result","success"&#41;;
    	     req.getRequestDispatcher&#40;"edit.jsp"&#41;.forward&#40;req,resp&#41;;
    	 
       &#125;
    &#125;
    Then I will get a NullPointerException in this sentence "ParentDAO pdao=this.getPdao();"
    But I config my ParentDAO in config xml file .It is the following:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http&#58;//www.springframework.org/dtd/spring-beans.dtd">
    <beans>
    <bean id="MyDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <!-- results in a setDriverClassName&#40;String&#41; call -->
            <property name="driverClassName">
                <value>org.gjt.mm.mysql.Driver</value>
            </property>
            <property name="url">
                <value>jdbc&#58;mysql&#58;//localhost&#58;3306/spring?useUnicode=true&amp;characterEncoding=gb2312</value>
            </property>
            <property name="username">
                <value>root</value>
            </property>
    		<property name="password">
                <value>root</value>
            </property>
    		<property name="defaultAutoCommit"> 
                <value>false</value> 
            </property>
        </bean>
    	<!--
    <bean id="MyJNDIDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
      <property name="jndiName">
        <value>jdbc/mysql</value>
      </property>
    </bean>
    -->
    <bean id="MySessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
       <property name="mappingResources"> 
          <list>
            <value>lyo/test/bean/Parent.hbm.xml</value>
            <value>lyo/test/bean/Son.hbm.xml</value>
            <value>lyo/test/bean/C.hbm.xml</value>
    
          </list>
       </property>
       <property name="hibernateProperties">
          <props>
            <prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.query.substitutions">true=1 false=0</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.use_outer_join">false</prop>
          </props>
       </property>
       <property name="dataSource"><ref bean="MyDataSource"/></property>
    </bean>
    <bean id="sondao" class="lyo.test.dao.SonDAO">
       <property name="sessionFactory">
          <ref bean="MySessionFactory"/>
       </property>
    </bean>
    <bean id="parentdao" class="lyo.test.dao.ParentDAO">
       <property name="sessionFactory">
          <ref bean="MySessionFactory"/>
       </property>
    
    </bean>
    <bean id="userServlet" class="lyo.test.servlet.UserActionServlet">
       <property name="pdao">
          <ref bean="parentdao"/>
       </property>
    
    </bean>
    
    
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property>
            <property name="prefix"><value>/WEB-INF/forum/</value></property>
            <property name="suffix"><value>.jsp</value></property>
        </bean>
     
    
    </beans>
    If I change my code to:
    Code:
    String path=this.getServletConfig&#40;&#41;.getServletContext&#40;&#41;.getRealPath&#40;"."&#41;;
    	     System.out.println&#40;"Get path&#58; "+path&#41;;
    	     ApplicationContext spring=
    			new FileSystemXmlApplicationContext&#40;path+"/WEB-INF/springmodal-servlet.xml"&#41;;
    	      ParentDAO pdao= &#40;ParentDAO&#41;spring.getBean&#40;"parentdao"&#41;;
    Then I can get the pdao object successfully!
    Why IOC pattern couldn't be used in Spring? Help![/code][/b]

  • #2
    Spring does not injecting resources into HttpServlet. You have, then, two choice to acheive what you are trying to do:

    1. use Spring MVC
    UserActionServlet can then implement org.springframework.web.servlet.mvc.Controller. Please take a look at Developing a Spring Framework MVC application step-by-step.

    2. Continue to use HttpServlet
    a. load the applicationContext using org.springframework.web.context.ContextLoaderListe ner.
    b. get a reference to the ApplicationContext and pull the required resources. The best way to acheive this is by overriding the servlet init method and using WebApplicationContextUtils.getWebApplicationContex t.

    If I change my code to:
    Code:
    String path=this.getServletConfig&#40;&#41;.getServletContext&#40;&#41;.getRealPath&#40;"."&#41;; 
            System.out.println&#40;"Get path&#58; "+path&#41;; 
            ApplicationContext spring= 
             new FileSystemXmlApplicationContext&#40;path+"/WEB-INF/springmodal-servlet.xml"&#41;; 
             ParentDAO pdao= &#40;ParentDAO&#41;spring.getBean&#40;"parentdao"&#41;;
    Then I can get the pdao object successfully!
    Unless you put this code inside the HttpServlet.init method, you will reload the context on each servlet call!!!
    HTH

    Comment


    • #3


      Thks !

      I think spring shouldn't dependent special class,right? ;-( . It will be not convinent in web app development. I will choice two. I want to extend ActionServlet(Struts) and override it's init method. like this:
      Code:
       
      
       public void init&#40;&#41;&#123;
      String path=this.getServletConfig&#40;&#41;.getServletContext&#40;&#41;.getRealPath&#40;"."&#41;; 
              System.out.println&#40;"Get path&#58; "+path&#41;; 
              ApplicationContext spring= 
               new FileSystemXmlApplicationContext&#40;path+"/WEB-INF/springmodal-servlet.xml"&#41;; 
      &#91;b&#93; this.getServletContext&#40;&#41;.setAttribute&#40;"spring",spring&#41;;&#91;/b&#93;
      &#125;
      In my Servlet class. I will get the spring object like this:
      Code:
      public class UserActionServlet extends Action&#123;
      
       ...................................................
      public ActionForward execute&#40;..................&#41;&#123;
          ApplicationContext spring=  this.getServletContext&#40;&#41;.getAttribute&#40;"spring"&#41;;
      ParentDAO pdao= &#40;ParentDAO&#41;spring.getBean&#40;"parentdao"&#41;;
      &#125;
      I will try it ! Thank yoU! [/code]

      Comment


      • #4
        Following are the steps you should follow if you want to go the struts / Spring path:
        1. build the applicationContext.xml:
        I think you are already done with this.

        2. Configure the ContextLoaderListener:
        add the following lines to your web.xml:
        Code:
          <!-- Spring WebApplicationContext configuration location -->
          <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
              /WEB-INF/applicationContext.xml
            </param-value>
          </context-param>
        
          <!-- Spring WebApplicationContext loader listener -->
          <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
          </listener>
        3. create Struts actions:
        Spring has build-in Support for Struts actions to easy the access to WebApplicationContext. All you have to do is extend one of the org.springframework.web.struts actions (ActionSupport / DispatchActionSupport / LookupDispatchActionSupport / MappingDispatchActionSupport) instead of using the Struts base actions.

        4. access the WebApplicationContext:
        use the following to get beans registered in the applicationContext:
        Code:
        public class UserAction extends ActionSupport &#123;
          private ParentDAO pdao;
          /**
           * @see org.springframework.web.struts.ActionSupport#onInit&#40;&#41;
           */
          protected void onInit&#40;&#41; &#123;
            pdao = &#40;ParentDAO &#41; getWebApplicationContext&#40;&#41;.getBean&#40;"pdao"&#41;;
          &#125;
        
          /**
           * @see org.springframework.web.struts.ActionSupport#onDestroy&#40;&#41;
           */
          protected void onDestroy&#40;&#41; &#123;
            pdao = null;
          &#125;
        &#125;
        HTH

        Comment


        • #5
          &amp;#65306;&amp;#65289;

          Thank you! You are right! ;-)

          It can work property if I extends ActionSupport class.
          I want to know if I use simpleFormController, will it give me some convinent method? like struts' ActionForm. I can use "BeanUtils.copyProperties(POJO,Form)" to get all form's parameter in struts Action. I mean that If I use SimpleFormController, Will it give me some helper or useful class like ActionForm?

          Comment


          • #6
            This tutorial Developing a Spring Framework MVC application step-by-step may answer some of your questions. Also, take a look at the Spring Framework reference documentation Chapter 12. Web framework.
            HTH

            Comment


            • #7


              I will see it. Thks

              Comment

              Working...
              X