2
回答
使用SiteMesh简化网页布局
【腾讯云】校园拼团福利,1核2G服务器10元/月!>>>   

在公司项目使用了 Appfuse ,其带有 SiteMesh 对于网页布局简化让我感觉很好用,本文旨在对对 Sitemesh 的基本原理和在项目中使用 Sitemesh 的实现流程、使用技巧的介绍。

1.   基本原理

SiteMesh 是以 Servlet 2.3API 为基础。它包含一个引擎,用来解析输出的网页或者网页片段,决定是否需要应用装饰器以及合并合适的装饰器。

       SiteMesh 与应用内容无关,适用的内容格式包括 Html JSP Servlet XSL ,甚至 CGI  

2.   实现流程

1)  当为 Servlet 容器指定一个 Http 请求时, SiteMesh 截取请求,使用一个 Servlet Filter ,然后捕捉 Html 结果。

2)  然后这个 Html 被解析,并且任何相关的内容都被提取到一个 Page 对象中。

3)  询问 DecoratorMapper 来确定那一个装饰器需要被应用。

4)  Servlet 向包含装饰器的 JSP 发送请求。

5 )装饰器生成带有从 page 对象中获得的内容的 Html 布局。

大致流程如下图:

 


         Sitemesh
这样的好处是,所有具体业务页面的开发者无需考虑该页面将处在最终输出页面的那个位置。无需 include 一大堆页面,以后如果系统整体改版,那么只需要改写装饰器页面及重新配置装饰规则即可完成,方便快捷,可维护性极好。

 

3.   在项目中使用 Sitemesh

1.         sitemesh_[version].jar 包加到 WEB-INF\lib

2.         web.xml 中增加

 

        < filter >  

              
< filter-name > sitemesh </ filter-name >  

              
< filter-class > com.opensymphony.module.sitemesh.filter.PageFilter </ filter-class >  

       
</ filter >  

       
< filter-mapping >  

              
< filter-name > sitemesh </ filter-name >  

              
< url-pattern > /* </ url-pattern >  

       
</ filter-mapping >  

 

       表示对系统中所有 url 请求均使用 sitemesh Filter 进行拦截。

3.         WEB-INF 下配置 sitemesh.xml decorator.xml 配置文件。

Sitemesh.xml

 

< sitemesh >  

    
< property  name ="decorators-file"  value ="/WEB-INF/decorators.xml" />  

    
< excludes  file ="${decorators-file}" />  

    
< page-parsers >  

        
< parser  default ="true"  class ="com.opensymphony.module.sitemesh.parser.HTMLPageParser" />  

        
< parser  content-type ="text/html"  

class
="com.opensymphony.module.sitemesh.parser.HTMLPageParser" />  

        
< parser  content-type ="text/html;charset=ISO-8859-1"  

class
="com.opensymphony.module.sitemesh.parser.HTMLPageParser" />  

    
</ page-parsers >  

    
< decorator-mappers >  

                  
<!--  for print  -->  

        
< mapper  class ="com.opensymphony.module.sitemesh.mapper.PrintableDecoratorMapper" >  

                            
< param  name ="decorator"  value ="printable"   />  

                            
< param  name ="parameter.name"  value ="printable"   />  

                            
< param  name ="parameter.value"  value ="true"   />  

        
</ mapper >  

        
< mapper  class ="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper" >  

            
< param  name ="config"  value ="${decorators-file}" />  

        
</ mapper >  

    
</ decorator-mappers >  

</ sitemesh >  

 

 

Decorator.xml

 

< decorators  defaultdir ="/decorators" >  

    
< excludes >  

        
< pattern > /demos/* </ pattern >  

        
< pattern > /resources/* </ pattern >  

        
< pattern > /test* </ pattern >  

        
< pattern > /FCKeditor/* </ pattern >  

    
</ excludes >  

         
<!--  decorator for print(has parameter: printable=true) -->  

    
< decorator  name ="printable"  page ="decPrintable.jsp" />  

         
< decorator  name ="login"  page ="decLogin.jsp" >  

                   
< pattern > *login* </ pattern >            <! —url 映射模式 -- >  

         
</ decorator >  

    
< decorator  name ="default"  page ="decDefault.jsp" >  

        
< pattern > /* </ pattern >                  <! — 缺省的装饰器 -- >  

    
</ decorator >  

</ decorators >  

 

sitemesh.xml 中配置了两个 DecoratorMapper PrintableDecoratorMapper ConfigDecoratorMapper

PrintableDecoratorMapper 是供打印专用,在 url 后加上 printable=true 即会使用 decorator.xml 中指定的 printable 装饰器来对页面进行装饰,一般来说打印页面是只需要打印本页面的内容,其余的如头、脚、导航栏、左右菜单等是不需要打印的,通过装饰器可以轻松实现打印页面的过滤。

4.         创建一个装饰器 JSP 页面,我建议所有装饰器页面放到 decorators 目录,并且以 dec[ 功能 ].jsp 作为命名方式,如 decPrintable.jsp decDefault.jsp

下面是一个装饰器的代码:

 

 

<! DOCTYPE html PUBLIC  " -//W3C//DTD XHTML 1.0 Transitional//EN "
    
" http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd " >
        
<%--  Include common set of tag library declarations  for  each layout  --%>
<% @ include file = " /common/taglibs.jsp " %>

< html xmlns = " http://www.w3.org/1999/xhtml "  xml:lang = " en " >
    
< head >
         < decorator:head />
    
</ head >
< body
< decorator:getProperty property = " body.id "  writeEntireProperty = " true " />
< decorator:getProperty property = " body.onload "  writeEntireProperty = " true " />
< decorator:getProperty property = " body.onunload "  writeEntireProperty = " true " />
>       
        
<% @ include file = " /common/header.jsp " %>
             < h1 >< decorator:getProperty property = " page.heading " /></ h1 >  
            
<% @ include file = " /common/messages.jsp "   %>
            
< decorator:body />
         < jsp:include page = " /common/footer.jsp " />
</ body >
</ html >

 

注意其 <decorator:…> 标签,这些标签将被装饰的 page 页面的相应内容作为属性传入。 Page 页面的相关内容将放在 decorator 标签所指定的位置。

Title :标题

Head :头部,一般是公共的 js css meta

Body :被装饰的 page 的主体内容。

5 Sitemesh 通过在 sitemesh.xml 中配置 DecoratorMapper 配置映射器,通过在 decorator.xml 中配置装饰器文件及其匹配方式。当有页面需要输出到客户端时,将根据这些配置选择相应的装饰器来进行装饰,将装饰结果返回给客户界面。

举报
红薯
发帖于9年前 2回/3K+阅
共有2个评论 最后回答: 6年前

你好!为什么我在was中使用下面的配置

我的页面没有被装饰器装饰呢?

<?xml version="1.0" encoding="UTF-8"?>

<decorators defaultdir="/WEB-INF/decorators">
	<excludes> 
        <pattern>index.jsp</pattern> 
        <pattern>manager.jsp</pattern>
        <pattern>*fckeditor*</pattern> 
        <pattern>meta.ftl</pattern>
        <pattern>top.ftl</pattern>
        <pattern>bottom.ftl</pattern>
        <pattern>*affair*</pattern>
    </excludes>
    
    <decorator name="back" page="back.ftl">
		<pattern>*back*</pattern>
	</decorator>
	
	<decorator name="top_bottom" page="top_bottom.ftl">
		<pattern>*webPage*</pattern>
	</decorator>
</decorators>

 @红薯   

你好!

Struts2在没用整合SiteMesh之前register.jsp能显示actionerr,整合之后就不能显示了actionerror了?

 

这什么原因呢?这么解决?

期待您的回复。

顶部