1. 程式人生 > >spring和struts2整合詳解

spring和struts2整合詳解

首先,我們要了解,web.xml中的各種元素在web容器中的載入順序:listener(監聽器)>filter(過濾器)>servlet.

在web.xml中配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<filter>
		<filter-name>f</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>f</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:beans.xml</param-value>
	</context-param>

	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
</web-app>
前面我們說到:listener的啟動優先順序要大於filter,因為spring和struts2結合時,spring作為一個管理和組裝物件的角色,就必需優先載入,然後再生產物件後對struts2的action進行注入,所以,這就是我們一般用listener啟動spring的原因。其實spring還可以交給struts2來啟動,通過修改struts2org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
類的init方法,來產生spring的webApplicationContext物件,但這樣spring就依賴於struts2了,這不是我們希望看到的。

對於<context-param>節點:

web容器為每個專案都會對應一個servletConfig物件,這個物件類似與專案中的Applcation物件,都是整個專案的全域性物件,看原始碼會發現,spring通過listener載入時在ContextLoader中,將spring的webApplication物件放置到了servletConfig(實際是放到servletContext中,這裡的servletContext代表的是全域性的上下文)中,這樣就可以在專案的任意能得到servletConfig物件的地方得到spring物件來讀取spring的bean了。

而<context-param>節點就是用來為這個全域性物件配置引數的,這樣就可以在整個專案中都能使用,spring就是通過servletConfig來讀取web.xml中的路徑引數來過得beans.xml等一些spring的xml檔案的。而

<param-value>classpath:beans.xml</param-value>
中,為什麼這樣寫,是spring的規範,spring認為當得到classpath:這樣的值時就認為這是一個檔案,會在當前專案中尋找此檔案並解析,當然,也可以給路徑,例如:/WEB-INF/classes/beans.xml。

以上是web.xml的配置,配置完成後,接下來就是配置struts.xml,很簡單,首先要在struts.xml中配置一個常量: <constant name="struts.objectFactory" value="spring" />.其實,在你匯入了struts-spring-plugin-xx-xx.jar的包後,這個常量已經在這個包中設定好了,所以上面的常量配不配,都沒有關係,這裡,我們顯式配置一下,當你沒有匯入spring的外掛包,上面的常量值是 struts2本身的一個objectFactory的一個類。

配置Action時,很簡單,只要將action的class替換為成在spring中的action類的id值就行了,因為,你的struts.objectFactory設定的時spring時,當你訪問一個action時,spring會通過action對應的name找到class,再用這個class到spring中找到id為class的值的類,然後生產出action.

spring和struts2零配置整合(在這裡,我用spring是xml方式,struts2用零配置方式):

零配置無非是將xml的配置方式,變成註解的方式,首先個人看法是,用註解維護起來沒有xml方便,個人比較傾向與xml配置。

我們知道,用註解配置action 是:@Action(value="/action"),但將註解和spring聯絡起來,我們看文件知道,只需要@Action(value="/action" className="spring中的ID"),這樣,當放問這個action時,struts2就向spring要action,spring則會通過這個className來匹配id,然後返回匹配的action類的例項。

經高人指導,還發現另一種配置方式:註解:@Action("/action"),action只需要這樣註解就行了,在spring那邊用這個action類的全名作為bean的id,我們知道,註解中,是不需要為action指定class這個屬性的,其實並不代表這個屬性不存在,這個屬性的值就是@Action所在的類名,當訪問沒有設定className屬性的action時,struts2找spring要Action,spring就通過這個action類的全名來匹配id的bean,所以,所以我們將這個bean的id設定為action的類名時,spring就能匹配到,這樣的配置方式使得spring和struts2解藕度就很高。

例如:

action的程式碼:

public class MyLoginAction {
	private LoginVo lv = new LoginVo();
	
	private MyUserService mus;
	
	@Action(value="/mylogin")
	public String login(){
		System.out.println(lv.getUpwd()+"====="+lv.getUname());
		mus.findUserByUnameUpwd(lv.getUname(), lv.getUpwd());
		return null;
	}

	public MyUserService getMus() {
		return mus;
	}

	public void setMus(MyUserService mus) {
		this.mus = mus;
	}

	public LoginVo getLv() {
		return lv;
	}

	public void setLv(LoginVo lv) {
		this.lv = lv;
	}
}

spring的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:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
	default-lazy-init="false">

	<bean id="mdao" class="org.xuliang.dao.MyUserDao">
	</bean>
	<bean id="mservice" class="org.xuliang.services.MyUserService">
		<property name="mud" ref="mdao" />
	</bean>
	<bean id="org.xuliang.web.actions.MyLoginAction"  class="org.xuliang.web.actions.MyLoginAction">
	</bean>

</beans>