欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

spring结合struts的代码详解

程序员文章站 2024-02-28 09:47:22
struts调用流程如下图所示。          看到这幅图一下子就能了解了struts的原理。spring的核心...

struts调用流程如下图所示。

spring结合struts的代码详解

         看到这幅图一下子就能了解了struts的原理。spring的核心就是ioc容器和aop,所以我们用spring主要是管理业务对象和事务的管理,所以主要是model层来让spring管理,这是我们的一种方案。

第一种集成方案在action中取得beanfactory

         还记的在上篇文章中,测试的时候是在单元测试中拿到的beanfactory,与struts结合就是在action中取得beanfactory。步骤如下。

1、          建立一个web项目。

2、          建立相关页面,代码如下所示。

      login.jsp代码入下所示。

<%@ pagelanguage="java" contenttype="text/html; charset=gb18030"
  pageencoding="gb18030"%>
<!doctype html public"-//w3c//dtd html 4.01 transitional//en""http://www.w3.org/tr/html4/loose.dtd">
<html>
<head>
<metahttp-equiv="content-type" content="text/html;charset=gb18030">
<title>insert titlehere</title>
</head>
<body>
    <formaction="login.do" method="post">
       用户:<input type="text"name="username"><br>
       密码:<input type="password"name="password"><br>
       <inputtype="submit" value="登录">
    </form>
</body>
</html>

login_success.jsp 

<%@ pagelanguage="java" contenttype="text/html; charset=gb18030"
  pageencoding="gb18030"%>
<!doctype html public"-//w3c//dtd html 4.01 transitional//en" "http://www.w3.org/tr/html4/loose.dtd">
<html>
<head>
<metahttp-equiv="content-type" content="text/html;charset=gb18030">
<title>insert titlehere</title>
</head>
<body>
    xx,用户登录成功!
 
</body>
</html>

3、 配置struts环境,关于struts的配置,拷贝struts和jstl的依赖包;在web.xml中配置actionservlet,提供struts-config.xml文件。前篇文中有说明,在此就不赘述了。

struts-config.xml代码如下所示。

<struts-config>
    <form-beans>
        <form-beanname="loginform"type="com.bjpowernode.usermgr.web.forms.loginactionform"></form-bean>
    </form-beans>
    <action-mappings>
        <actionpath="/login"
        type="com.bjpowernode.usermgr.web.actions.loginaction"
        name="loginform"
        scope="request"
        >
        <forwardname="success" path="/login_success.jsp"/>
        </action>
    </action-mappings>
     <message-resourcesparameter="resources.messageresources" />
</struts-config>

4、 配置spring环境,拷贝spring相关jar包,建立spring配置文件applicationcontext-beans.xml。

applicationcontext-beans.xml代码如下所示。

<beansxmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
      xmlns:aop="http://www.springframework.org/schema/aop"
      xmlns:tx="http://www.springframework.org/schema/tx"
      xsi:schemalocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd
     http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.0.xsd
     http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
    <beanid="usermanager"class="com.bjpowernode.usermgr.manager.usermanagerimpl"/>
</beans>

5、 建立相关的action和actionform。代码如下所示。

      loginaction.java代码如下所示。

public class loginaction extendsaction {
    @override
    publicactionforward execute(actionmapping mapping, actionform form,
           httpservletrequestrequest, httpservletresponse response)
           throwsexception {
       loginactionformlaf = (loginactionform)form;
       stringusername = laf.getusername();
       stringpassword = laf.getpassword();
        //但是我们每次都要去调用,去创建太麻烦了.
       //我们在这里只需要去配置listener就可以了,spring给实现好了.
       beanfactoryfactory = newclasspathxmlapplicationcontext("applicationcontext.xml");
       usermanagerusermanager = (usermanager)factory.getbean("usermanager");
       usermanager.login(username,password);
    }
}

      loginactionform.java代码如下所示。

public class loginactionformextends actionform {
    //表单上有什么提供什么属性.
    //名字一定要与表单中的一样.
    privatestring username;
    publicstring getusername() {
       returnusername;
    }
    publicvoid setusername(string username) {
       this.username= username;
    }
    privatestring password;
    publicstring getpassword() {
       returnpassword;
    }
    publicvoid setpassword(string password) {
       this.password= password;
    }
}

 6、 建立业务逻辑层,代码如下所示。

      usermanager代码如下所示。

public interface usermanager {
    publicvoid login(string username, string password);
}

      usermanagerimpl.java代码如下所示。

public class usermanagerimplimplements usermanager {
    publicvoid login(string username, string password) {
       system.out.println("usermanagerimpl"+"username="+ username);
    }
} 

7、 web.xml配置文件代码如下所示。

<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>
  <init-param>
   <param-name>debug</param-name>
   <param-value>2</param-value>
  </init-param>
  <init-param>
   <param-name>detail</param-name>
   <param-value>2</param-value>
  </init-param>
  <load-on-startup>2</load-on-startup>
 </servlet>

      就这样我们在loginaction中,使用beanfactory读取spring配置文件,找到usermanagerimpl实例。如果每次在action中读取application-beans.xml文件,我们是否可以在服务器启动的时候就就创建beanfactory呢?在这里我们可以使用spirng的工具webapplicationcontextutils.getrequiredwebapplicationcontext()从  servletcontext中  取得beanfactory,然后再web.xml中配置spring的listener。

修改后,loginaction代码如下所示。

public class loginaction extendsaction {
    @override
    publicactionforward execute(actionmapping mapping, actionform form,
           httpservletrequestrequest, httpservletresponse response)
           throwsexception {
       loginactionformlaf = (loginactionform)form;
       stringusername = laf.getusername();
       stringpassword = laf.getpassword();
       //用工具包直接拿出来就可以了。
       beanfactoryfactory =webapplicationcontextutils.getrequiredwebapplicationcontext(request.getsession().getservletcontext());
       usermanagerusermanager = (usermanager)factory.getbean("usermanager");
       usermanager.login(username,password);
       returnmapping.findforward("success");
    }
}   

      加入相关配置,web.xml代码如下所示。

<context-param>
    <param-name>contextconfiglocation</param-name>
    <param-value>classpath:applicationcontext-*.xml</param-value>
 </context-param>
 <listener> 
    <listener-class>org.springframework.web.context.contextloaderlistener</listener-class>
 </listener>

这种方案缺点:

     我们在在action中仍然看到spring相关东西,看到spring相关类,要是程序只看到的是接口,那要怎么做呢?

     第二种方案,将struts的aciton交给spring来创建,让代理action负责拿到beanfactory,根据path名称到ioc中把对应的action取出来。

我们是在model层应用spring,在action中取得beanfactory,然后通过springioc来找到model层的bean。但是这这样存在一些问题,我们在action中使用的是spring相关的静态类,这就说明我们依赖的是spring的静态类,我们希望所依赖的是接口而不是类,符合设计原则,面向接口编程,这样也容易扩展和维护。于是在此基础上进行改进。

第二种方案是将struts的action交给spring创建,这样业务逻辑对象将被注入,这样就避免了依赖查找,而spring中会有一个代理action,通过代理actionproxy取得banfactory。方案一和方案二的对比图如下图所示。 

这样就不用spring的listener了,所以我们的web.xml配置文件代码如下所示。

<?xml version="1.0" encoding="utf-8"?> 
<web-app version="2.4"  
  xmlns="http://java.sun.com/xml/ns/j2ee"  
  xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"  
  xsi:schemalocation="http://java.sun.com/xml/ns/j2ee  
  http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 
 <welcome-file-list> 
  <welcome-file>index.jsp</welcome-file> 
 </welcome-file-list> 
  
 <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> 
  <init-param> 
   <param-name>debug</param-name> 
   <param-value>2</param-value> 
  </init-param> 
  <init-param> 
   <param-name>detail</param-name> 
   <param-value>2</param-value> 
  </init-param> 
  <load-on-startup>2</load-on-startup> 
 </servlet> 

同时再struts的配置文件,struts-config.xml中,在<action-mappings>标签中配置action,也不再配置我们自己建立的action,而是配置spring自己的代理action。代码如下所示。

<?xml version="1.0" encoding="iso-8859-1" ?> 
<!doctype struts-config public 
     "-//apache software foundation//dtd struts configuration 1.2//en" 
     "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd"> 
<struts-config> 
  <form-beans> 
    <form-bean name="loginform" type="com.bjpowernode.usermgr.web.forms.loginactionform"></form-bean> 
  </form-beans> 
  <action-mappings> 
    <action path="/login" 
    type="org.springframework.web.struts.delegatingactionproxy" 
    name="loginform" 
    scope="request" 
    > 
    <forward name="success" path="/login_success.jsp"/> 
    </action> 
  </action-mappings> 
   <message-resources parameter="resources.messageresources" /> 
</struts-config> 

spring对aciton的配置文件如下所示。applicationcontext-actions.xml.

<?xml version="1.0" encoding="utf-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" 
     xmlns:aop="http://www.springframework.org/schema/aop" 
     xmlns:tx="http://www.springframework.org/schema/tx" 
     xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd 
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> 
  <bean name="/login" class="com.bjpowernode.usermgr.web.actions.loginaction" scope="prototype"> 
    <property name="usermanager" ref="usermanager"/> 
  </bean> 
</beans> 

在这里配置对应的本系统实际的action,注意名字一定要和struts中代理action一致!并且设置每次创建一个新的action,而不是共用一个action,scope="prototype"。

这样在loginaction中,我们不用再看到创建model和工厂的细节,使用springioc,创建model,usermanager,并且配置文件中注入loginaction,这样loginaction代码如下所示。

public class loginaction extends action { 
  private usermanager usermanager; 
  // 让spring注入,loginaction让spring管理, 不是让strus创建而是由spring创建. 
  public void setusermanager(usermanager usermanager) { 
    this.usermanager = usermanager; 
  } 
  @override 
  public actionforward execute(actionmapping mapping, actionform form, 
      httpservletrequest request, httpservletresponse response) 
      throws exception { 
    loginactionform laf = (loginactionform) form; 
    string username = laf.getusername(); 
    string password = laf.getpassword(); 
    usermanager.login(username, password); 
    return mapping.findforward("success"); 
  } 
} 

小结:

spring框架就相当于我们的工具,我们把工具挖掘和使用的淋漓尽致才好,这可能就是人和工具的区别,人利用创造和利用工具,工具被创造和被利用。这中间的过程就是磨合了。