有的网页程序使用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="p_w_picpaths/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中的值取出来。