论坛首页 Java企业应用论坛

Tiles,struts和 JavaServer Faces集成

浏览 1572 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-03-17  

     在大多数项目中,很多web开发人员能做的就是利用IDE自动为我们生成配置文件,但真正当我们自己想动手写个项目时,发现很多模块我们似懂非懂,无法入手。当然要学会这些项目中的每个模块以及如何集成它们,这还是需要平时的点滴的积累。

    经常我们利用基于eclipse开发IDE来创建我们的页面,但实质上它在后台自动帮我们生成多很多配置文件,如spring,bb,tiles。

    现在介绍的就如何复用我们的模版tiles.

 

它的方式很多种,多到每个语言都有各自的配置方式,但是万变不离其中,那就是复用一些常用的模版。

一.最原始的就是jsp:include方式:

<TABLE border="0">
			<TBODY>
				<TR>
					<TD colspan="2">
						<jsp:include page="/header.jsp" />
					</TD>
				</TR>
				<TR>
					<TD colspan="2">
						<jsp:include page="/body.jsp" />
					</TD>
				</TR>
				<TR>
					<TD colspan="2">
						<jsp:include page="/footer.jsp" />
					</TD>
				</TR>
			</TBODY>
		</TABLE>

 

这是个简单的利用标签来复用

 

二.利用struts-tiles.tld

<TABLE border="0">
			<TBODY>
				<TR>
					<TD colspan="2">
						<tiles:insert page="/header.jsp" flush="true" />
					</TD>
				</TR>
				<TR>
					<TD colspan="2">
						<tiles:insert page="/body.jsp" flush="true" />
					</TD>
				</TR>
				<TR>
					<TD colspan="2">
						<tiles:insert page="/footer.jsp" flush="true" />
					</TD>
				</TR>
			</TBODY>

		</TABLE>

 

    这个标签是在基于 struts上的tld,所以你必须加入如下两个文件
     1.struts-tiles.tld
     2.struts.jar 包

 

 

3.struts-tiles.tld与JSF的集成

    这种方式是比较常用的,它可以把相关页面利用tiles.xml集成起来,甚至利用模版和常用文件,你都可以不用新建你的JSP文件。下面就来感受一下它的妙处吧:

  3.1首先是快速搞个jsf+spring+hibernate的工程(没有的可以参照这里

                  http://lygle.iteye.com/admin/blogs/616800),然后建立三个JSP文件

     head.jsp

     body.jsp

     footer.jsp

再建立个模版文件

        layout.jsp

 

  

<f:view>
			<table width="778" border="1" align="center" cellpadding="0"
				cellspacing="0">
				<tr>
					<td>
						<f:subview id="header">
							<t:insert attribute="header" flush="false"></t:insert>
						</f:subview>
					</td>
				</tr>
				<tr>
					<td>
						<f:subview id="body">
							<t:insert attribute="body" flush="false"></t:insert>
						</f:subview>
					</td>
				</tr>
				<tr>
					<td>
						<f:subview id="footer">
							<t:insert attribute="footer" flush="false"></t:insert>
						</f:subview>
					</td>
				</tr>
			</table>
		</f:view>

 使它包含着上面的三个文件

 

   3.2修改JSF配置文件

        在配置文件加个导航规则

<navigation-case>
			<from-action>#{UserLoginBB.userLogin}</from-action>
			<from-outcome>ok</from-outcome>
			<to-view-id>/homePage.jsf</to-view-id>

		</navigation-case>

 

  这个规则假设是我们登录的动作,如果成功返回ok,然后跳转到"homePage.jsf"

注意这里的homePage.jsf事实上不存在的,它是利用tiles动态配置出来的一个页面。怎么配呢,继续往下看吧。

 

 

3.3配置web.xml跟tiles.xml

    确保web.xml里有引用到我们的tiles.xml

如:

	<context-param>
		<param-name>tiles-definitions</param-name>
		<param-value>/WEB-INF/tiles.xml</param-value>
	</context-param>

 

关键的tiles.xml

<!DOCTYPE tiles-definitions PUBLIC
 "-//Apache Software Foundation//DTD Tiles Configuration//EN"
 "http://jakarta.apache.org/struts/dtds/tiles-config.dtd">
<tiles-definitions>
	<definition name="layout" path="/layout.jsp">
		<put name="header" value="/header.jsp" />
		<put name="body" value="/body.jsp" />
		<put name="footer" value="/footer.jsp" />
	</definition>
	<definition name="layout2" path="/layout.jsp">
		<put name="footer" value="/header.jsp" />
		<put name="body" value="/body.jsp" />
		<put name="header" value="/footer.jsp" />
	</definition>

	<definition name="layout3" path="/layout.jsp">
		<put name="header" value="/header.jsp" />
		<put name="body" value="/body.jsp" />
		<put name="footer" value="/footer.jsp" />
	</definition>
	<definition name="/homePage.tiles" extends="layout3">
	</definition>
</tiles-definitions>

 

这个配置文件里,我配置一个name为homePage",并且它的模版继承自layout3

 

那么请问,当你跳转到"/homePage.jsf",这个不存在的文件,它怎么跟tiles.xml关系上呢。当你有这个疑问时,说明你可以继续往下看了。

 

 3.4.配置ViewHandle

   在faces-config.xml里配置一个请求监听,当我们请求/homePage.jsf,它能够监听到并把它转到

/homePage.tiles从而调用layout3模版里的页面。

这个过程我们就引用apache里的一个文件,稍作修改,最重要的就是renderView接收请求,并把请求转为

/homePage.tiles这个过程

有兴趣的话,可以下来调试看下.

部分代码如下:

 

 if (servletMapping.isExtensionMapping())
        {
            if (!viewId.endsWith(suffix))
            {
                int dot = viewId.lastIndexOf('.');
                if (dot == -1)
                {
                    //if (log.isTraceEnabled()) log.trace("Current viewId has no extension, appending default suffix " + suffix);
                    viewId = viewId + suffix;
                }
                else
                {
                    //if (log.isTraceEnabled()) log.trace("Replacing extension of current viewId by suffix " + suffix);
                    viewId = viewId.substring(0, dot) + suffix;
                }
                facesContext.getViewRoot().setViewId(viewId);
            }
        }
        else if (!viewId.endsWith(suffix))
        {
            // path-mapping used, but suffix is no default-suffix
            dispatch(externalContext, viewToRender, viewId);
            return;
        }

        String tilesId = viewId;
        int idx = tilesId.lastIndexOf('.');
        if (idx > 0)
        {
            tilesId = tilesId.substring(0, idx) + tilesExtension;
        }
        else
        {
            tilesId = tilesId  + tilesExtension;
        }
        ServletRequest request = (ServletRequest)externalContext.getRequest();
        ServletContext servletContext = (ServletContext)externalContext.getContext();

        ComponentDefinition definition = null;
        try
        {
            definition = getDefinitionsFactory().getDefinition(tilesId, request, servletContext);

            if (definition == null)
            {
                /**
                 * Check for the definition without the leading '/' character.  Allows user to specify Tiles definitions without a
                 * leading '/' char.
                 */
                int slashIndex = tilesId.indexOf("/");
                if (slashIndex == 0)
                {
                    tilesId = tilesId.substring(1);
                    definition = getDefinitionsFactory().getDefinition(tilesId, request, servletContext);
                }
            }

 

 

 

 

 

论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics