有的網頁程式使用struts的Tiles布局架構開設計頁面,我認為並沒有使頁面更簡單,設定檔以及模板頁面太多,讓人混亂,但還是記錄一下,萬一哪天用到。。。
在程式的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">
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
WEB-INF/config/dao-config.xml,WEB-INF/config/view-config.xml,WEB-INF/config/controller-config.xml,WEB-INF/config/managerController-config.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.lzw</url-pattern>
</servlet-mapping>
</web-app>
如紅色字型部分,在tomcat載入程式的時候,程式就根據路徑來讀取這些設定檔,
view-config.xml是配置頁面中url請求的映射關係的檔案,如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="urlHandlerMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<!--前台-->
<prop key="/index.lzw">goodsController</prop>
<prop key="/goods*.lzw">goodsController</prop>
<prop key="/register.lzw">registerController</prop>
<prop key="/login.lzw">loginController</prop>
<prop key="/modifyMember.lzw">modifyMemberController</prop>
<prop key="/order.lzw">orderController</prop>
<prop key="/sellSort.lzw">sellSortController</prop>
<prop key="/placardDetails.lzw">placardDetailsController</prop>
<prop key="/goodsDetails.lzw">goodsDetailsController</prop>
<prop key="/type.lzw">typeController</prop>
<prop key="/cart*.lzw">cartController</prop>
<prop key="/cartSee.lzw">cartSeeController</prop>
<prop key="/cartCheckout.lzw">cartCheckoutController</prop>
<prop key="/orderDetails.lzw">orderDetailsController</prop>
<prop key="/searchController.lzw">searchController</prop>
<!--後台-->
<prop key="/loginM.lzw">loginMController</prop>
<prop key="/indexM.lzw">indexMController</prop>
<prop key="/superType.lzw">superTypeController</prop>
<prop key="/superAdd.lzw">superAddController</prop>
<prop key="/subType.lzw">subTypeController</prop>
<prop key="/subTypeAdd.lzw">subTypeAddController</prop>
<prop key="/goodsAdd.lzw">goodsAddController</prop>
<prop key="/goodsDetailM.lzw">goodsDetailsMController</prop>
<prop key="/goodsModify.lzw">goodsModifyController</prop>
<prop key="/goodsDel.lzw">goodsDelController</prop>
<prop key="/member*.lzw">memManagerController</prop>
<prop key="/orderM*.lzw">orderManagerController</prop>
<prop key="/placardManage.lzw">placardManageController</prop>
<prop key="/placardAdd.lzw">placardAddController</prop>
</props>
</property>
</bean><!--
<bean id="exceptionResolver"
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.Exception">Error</prop>
</props>
</property>
</bean>
--><bean id="tilesConfiger"
class="org.springframework.web.servlet.view.tiles.TilesConfigurer">
<property name="definitions">
<list>
<value>WEB-INF/config/tiles-template.xml</value>
<value>WEB-INF/config/tiles-defs.xml</value>
<value>WEB-INF/config/tiles-managerDefs.xml</value>
<value>WEB-INF/config/tiles-manageTemplate.xml</value>
</list>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass">
<value>
org.springframework.web.servlet.view.tiles.TilesJstlView
</value>
</property>
</bean>
</beans>
當我開啟首頁,首頁裡會發送一個請求/index.lzw,web.xml中指定所有的*.lzw請求全部由spring管理竟然不用struts做控制器??!),所以請求到達了view-config.xml,根據裡面的<prop key="/index.lzw">goodsController</prop>我們需要到controller-config.xml檔案中去找到該控制器所在java類,controller-config.xml檔案如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="searchController" class="com.lzw.SearchController">
<property name="dao">
<ref bean="daoProxyFactory" />
</property>
</bean>
<!-- 商品控制器-->
<bean id="goodsMethodResolver"
class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<props>
<prop key="/index.lzw">goodsShow</prop>
<prop key="/goodsNewGoods.lzw">newGoods</prop>
<prop key="/goodsSale.lzw">saleGoods</prop>
</props>
</property>
</bean>
<bean id="goodsController" class="com.lzw.NewGoodsController">
<property name="methodNameResolver">
<ref local="goodsMethodResolver" />
</property>
<property name="dao">
<ref bean="daoProxyFactory" />
</property>
<property name="saleGoodsLine">
<value>1</value>
</property>
<property name="newGoodsLine">
<value>3</value>
</property>
</bean>
.
.
.
</beans>
所以程式就知道要進com.lzw.NewGoodsController這個action去運行,如藍色字型顯示,設定檔對action中的相關執行個體變數進行賦值,如給saleGoodsLine和newGoodsLine賦值為1和3,給dao屬性進行依賴注入,daoProxyFactory可以從dao-config.xml中獲得,以便action中進行hibernate操作。<property name="methodNameResolver">從當前檔案中引用了goodsMethodResolver這個bean,如綠色字型顯示,這個bean的作用是通過/index.lzw這個url匹配了一個goodsShow方法,即要去action中執行goodsShow方法,此方法如下:
public class NewGoodsController extends MultiActionController{
private Dao dao;
private int saleGoodsLine=1;
private int newGoodsLine=4;
public ModelAndView goodsShow(HttpServletRequest request,HttpServletResponse response){
List list1=dao.getShowSaleGoodsList();
List list2=dao.getShowNewGoodsList();
Map model=new HashMap();
model.put("saleGoods", list1);
model.put("newGoods", list2);
model.put("saleGoodsLine", saleGoodsLine);
model.put("newGoodsLine", newGoodsLine);
return new ModelAndView("index",model);
}
}
action會講查詢到的相關資訊放入一個Map中傳遞給頁面。spring是怎麼判斷傳遞給哪個頁面?在view-config.xml檔案中引入了四個檔案:
<bean id="tilesConfiger"
class="org.springframework.web.servlet.view.tiles.TilesConfigurer">
<property name="definitions">
<list>
<value>WEB-INF/config/tiles-template.xml</value>
<value>WEB-INF/config/tiles-defs.xml</value>
<value>WEB-INF/config/tiles-managerDefs.xml</value>
<value>WEB-INF/config/tiles-manageTemplate.xml</value>
</list>
</property>
</bean>
這些便是tiles組件的設定檔,如上面紅體所示,action傳過來一個key為index的Map,在tiles-defs.xml中可以找到匹配的映射:
<tiles-definitions>
<!-- 首頁-->
<definition name="index" extends=".indexLayout" />
</tiles-definitions>
index指引程式去找.indexLayout這個definition,它在tiles-template.xml中:
<tiles-definitions>
<!--出錯頁面模板-->
<definition name="Error" path="/WEB-INF/jsp/template/error.jsp" />
<!--首頁模板-->
<definition name=".indexLayout"
path="/WEB-INF/jsp/template/indexTemplate.jsp">
<put name="title" value="欣想電子商城" /> <!--網站標題-->
<put name="navigation" value="/WEB-INF/jsp/navigation.jsp" /> <!--導覽列-->
<put name="left" value=".left" /> <!--左菜單-->
<put name="search" value=".search" /> <!--搜尋欄-->
<put name="content" value="/WEB-INF/jsp/productInfo.jsp" /> <!--內容分欄-->
<put name="right" value=".right" /> <!--右菜單-->
<put name="footer" value="/WEB-INF/jsp/footer.jsp" /> <!--著作權資訊-->
</definition>
上面主要講的是以spring做控制器配合tiles使用的一個基本過程,下面記錄一下struts的Tiles布局架構是如何工作的。例如首頁,建一個模板頁面:
<%@ page contentType="text/html; charset=gb2312" language="java"
errorPage="error.jsp"%>
<%@ taglib prefix="tiles"
uri="http://jakarta.apache.org/struts/tags-tiles"%>
<html>
<head>
<title><tiles:getAsString name="title" />
</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<link href="CSS/style.css" rel="stylesheet">
</head>
<body>
<center>
<table align="center" width="790" border="0" cellspacing="0"
cellpadding="0">
<tr>
<td class="tableBorder">
<tiles:insert attribute="navigation" /></td>
</tr>
<tr>
<td class="tableBorder" bgcolor="white">
<tiles:insert attribute="search" />
<table width="100%" height="500" border="0" cellpadding="0"
cellspacing="0">
<tr>
<td valign="top" width="198" align="right" bgcolor="#F0F0F0">
<tiles:insert attribute="left" /></td>
<td valign="top">
<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td valign="top" width="69%" bgcolor="white">
<tiles:insert attribute="content" /></td>
<td valign="top" width="31%">
<tiles:insert attribute="right" /></td>
</tr>
</table>
</td>
</tr>
</table>
<table width="790" border="0" align="center" cellpadding="0"
cellspacing="0">
<tr><td><tiles:insert attribute="footer" /></td></tr>
</table>
</td>
</tr>
</table>
</center>
</body>
</html>
可以看到多出使用了<tiles:insert attribute="navigation" /></td>這類標籤,attribute的值要和
tiles-template.xml中的<put name="navigation" value="/WEB-INF/jsp/navigation.jsp" />name值一致。這樣就把navigation.jsp的這個頁面插入進來,其他的同理。本文介紹的使用spring做控制器,如果使用struts做控制器那tiles的各個設定檔就要在struts的設定檔裡指明路徑:
<plug-in className="org.apache.struts.tiles.TilesPlugin" >
<set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" />
<set-property property="definitions-parser-validate" value="true" />
</plug-in>
·definitions-config參數:指定Tiles組件的設定檔,如果有多個設定檔,則它們之間用逗號分隔。
·definitions-parser-validate參數:指定XML解析器是否驗證Tiles設定檔,可選值包括true和false,預設值為true。
為了保證在Web應用啟動時載入TilesPlugin外掛程式,應該加入ActionServlet控制器,ActionServlet控制器在初始化時能載入所有的外掛程式。以下是在web.xml檔案中配置ActionServlet的代碼:
<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>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</tiles-definitions>
根據此definition,程式會將頁面構建出來。我們來看下productInfo.jsp這張頁面的一部分:
<table width="100%" height="200" border="0" cellpadding="0"
cellspacing="0">
<c:forEach begin="1" end="${saleGoodsLine*2 }" var="line" step="2">
<tr>
<c:forEach begin="${line-1}" end="${line}" var="goods" items="${saleGoods }">
<td width="49%" height="200" valign="top">
<table width="100%" border="0" cellpadding="0"
cellspacing="0">
<tr>
<td height="95" align="center">
<img src=\'#\'" /goods/${goods.picture }" width="90"
height="75"></td>
</tr>
<tr>
<td height="22" align="center">
<a href="goodsDetails.lzw?id=${goods.id }">
${goods.goodsName }</a></td>
</tr>
<tr>
<td height="20" align="center"
style="text-decoration:line-through;color:#FF0000">
原價: ${goods.price }</td>
</tr>
<tr>
<td height="20" align="center">
現價:${goods.nowPrice }</td>
</tr>
</table>
</td>
</c:forEach>
</tr>
</c:forEach>
</table>
頁面通過el運算式將存在Map中的值取出來。