sitemesh是什么?
百度的答案:
sitemesh
OS(OpenSymphony)的SiteMesh是一个用来在JSP中实现页面布局和装饰(layout and decoration)的框架组件,能够帮助网站开发人员较容易实现页面中动态内容和静态装饰外观的分离。
Sitemesh功能基础
Sitemesh是由一个基于Web页面布局、装饰及与现存Web应用整合的框架。它能帮助我们再由大量页面工程的项目中创建一致的页面布局和外观,如一致的导航条、一致的banner、一致的版权等。它不仅能处理动态的内容,如JSP、PHP、ASP、CGI等产生的内容,还能处理静态的内容,比如HTML的内容,使得它的内容也符合你的页面结构的要求。甚至它能像include那样将HTML文件作为一个面板的形式嵌入到别的文件中去。所有的这些,都是GOF的Decorator模式的最生动的实现。装饰模式是在不必改变原类文件和使用集成的情况下,动态地扩展一个对象的功能。它能通过创建一个包装对象,也就是装饰来包裹的对象。尽管它是由Java语言来实现的,但是它能与其他Web应用很好的集成
javaeye 的举例:
web开发当中,前端的页面逻辑很难被重用,当我们在每一个页面中用include来复用公共的header, css, js,footer时,会大量的出现重复的代码,无形中增加的开发人员的负担.sitemesh通过filter截取request和response,并给原始的页面加入一定的装饰(可能为header,footer...),然后把结果返回给客户端,并且被装饰的原始页面并不知道sitemesh的装饰,这也就达到了脱耦的目的。
SiteMesh 是opensymphony项目,下是官网中的介绍:
SiteMesh is a web-page layout and decoration framework and web- application integration framework to aid in creating large sites consisting of many pages for which a consistent look/feel, navigation and layout scheme is required.
SiteMesh intercepts requests to any static or dynamically generated HTML page requested through the web-server, parses the page, obtains properties and da
SiteMesh can also include entire HTML pages as a Panel within another page. This is similar to a Server-Side Include, except that the HTML document will be modified to create a visual window (using the document's Meta-da
SiteMesh is built using Java 2 with Servlet, JSP and XML technologies. This makes it ideal for use with J2EE applications, however it can be integrated with server-side web architectures that are not Java based such as CGI (Perl/Python/C/C++/etc), PHP, Cold Fusion, etc...
SiteMesh is very extensible and is designed in a way in which it is easy to extend for custom needs.
WEB-INF 下decorator.xml文件
- <decorators defaultdir="/WEB-INF/decorators">
- <!-- 不需要修饰的页面 -->
- <excludes>
- <pattern>/css/*</pattern>
- <pattern>/js/*</pattern>
- <pattern>/images/*</pattern>
- <pattern>/dojo/*</pattern>
- <pattern>/webwork/*</pattern>
- <pattern>/login.jsp*</pattern>
- <pattern>/register/*</pattern>
- </excludes>
- <decorator name="main" page="main.jsp">
- <pattern>/*</pattern>
- </decorator>
- </decorators>
<decorators defaultdir="/WEB-INF/decorators"> <!-- 不需要修饰的页面 --> <excludes> <pattern>/css/*</pattern> <pattern>/js/*</pattern> <pattern>/images/*</pattern> <pattern>/dojo/*</pattern> <pattern>/webwork/*</pattern> <pattern>/login.jsp*</pattern> <pattern>/register/*</pattern> </excludes> <decorator name="main" page="main.jsp"> <pattern>/*</pattern> </decorator> </decorators>
defaultdir为装饰页面所在的文件夹.
装饰页面main.jsp,主要的页面结构布局.
代码:
- <%@ page contentType="text/html;charset=utf-8" language="java"%>
- [color=red]<%@ taglib uri="sitemesh-decorator" prefix="decorator"%>
- <%@ taglib uri="sitemesh-page" prefix="page"%>[/color]
- <%
- String path = request.getContextPath();
- %>
- <HTML>
- <HEAD>
- <TITLE><decorator:title default="main page" /></TITLE>
- <decorator:head />
- <link rel="stylesheet" type="text/css"
- href="<%=path%>/css/default.css" />
- <link rel="stylesheet" type="text/css" href="<%=path%>/css/tab.css" />
- <script language="javas
cript" src="<%=path%>/js/formControl.js"></script> - <script language="javas
cript" src="<%=path%>/js/changePage.js"></script> - <META http-equiv=ImageToolbar content=no>
- </HEAD>
- <BODY id=main>
- <jsp:include flush="true" page="/commont/header.jsp"></jsp:include>
- <DIV id=container>
- <DIV id=content style="height:500px">
- <decorator:body /> <DIV id=navigation>
- <A accessKey=3 name=menu></A>
- <H2 class=hide>
- Navigation
- </H2>
- <UL id=menuroot>
- <LI>
- <A title="index" accessKey=1 href="<%=path%>/index.jsp">Index</A>
- </LI>
- <LI>
- <A title="ListUser" accessKey=3
- href="<%=path%>/user/listUsers.act
ion">ListUser</A> - </LI>
- <LI>
- <A title="listWorkSum" accessKey=4
- href="<%=path%>/worksum/listWorkSums.act
ion">listWorkSum</A> - </LI>
- <LI>
- <A title="ListUser" accessKey=3
- href="<%=path%>/clickstream/clickstreams.jsp">ClickStream</A>
- </LI>
- <LI>
- <A title="monitor" accessKey=6
- href="<%=path%>/monitor/jamonadmin.jsp">monitor</A>
- </LI>
- <LI>
- <A title="workflow" accessKey=6
- href="<%=path%>/workflow/default.jsp">workflow</A>
- </LI>
- <LI>
- <A title="workflow" accessKey=4
- href="<%=path%>/workflow/workflowLogin.act
ion">workflowAction</A> - </LI>
- <LI>
- <A title="soap" accessKey=6
- href="<%=path%>/soap/default.jsp">soap</A>
- </LI>
- <LI>
- <A title="Logout" accessKey=5 href="<%=path%>/logout.jsp">Logout</A>
- </LI>
- </UL>
- </DIV>
- </DIV>
- <DIV id=header>
- Copyright © 2003-2005 cherubo All Rights Reserved
- </DIV>
- <jsp:include page="/commont/footer.jsp" />
- </BODY>
- </HTML>
<%@ page contentType="text/html;charset=utf-8" language="java"%>[color=red]<%@ taglib uri="sitemesh-decorator" prefix="decorator"%><%@ taglib uri="sitemesh-page" prefix="page"%>[/color]<%String path = request.getContextPath();%><HTML> <HEAD> <TITLE><decorator:title default="main page" /></TITLE> <decorator:head /> <link rel="stylesheet" type="text/css" href="<%=path%>/css/default.css" /> <link rel="stylesheet" type="text/css" href="<%=path%>/css/tab.css" /> <script language="javas
上面页面
以下列着全部标签: Decorator Tags Page Tags
被用于建立装饰器页面. 被用于从原始内容页面访问装饰器.
<decorator:head />
<decorator:body />
<decorator:title />
<decorator:getProperty />
<decorator:usePage />
<page:applyDecorator />
<page:param
<decorator:head />
插入原始页面(被包装页面)的head标签中的内容(不包括head标签本身)。
<decorator:body />
插入原始页面(被包装页面)的body标签中的内容。
<decorator:title [ default="..." ] />
插入原始页面(被包装页面)的title标签中的内容,还可以添加一个缺省值。
被修饰的页面
- <html>
- <head>
- <title>main</title>
- </head>
- <body>
- <div style="PADDING-TOP: 50px;">
- <h1>
- Welcome Into NewiKi System
- </h1>
- <h3>In Newiki System,You Can:</h3>
- <h3>You can do Anything!</h3>
- <h3>It's Life ,Live It!</h3>
- <h3>You Are Freedom!</h3>
- </div>
- </body>
- </html>
<html><head> <title>main</title> </head><body><div style="PADDING-TOP: 50px;"><h1>Welcome Into NewiKi System </h1><h3>In Newiki System,You Can:</h3><h3>You can do Anything!</h3><h3>It's Life ,Live It!</h3><h3>You Are Freedom!</h3></div> </body></html>
很简单,很清楚的结构.
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>*.jsp</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>sitemesh</filter-name>
- <url-pattern>*.act
ion</url-pattern> - </filter-mapping>
其他的例子:
如果用jsp实现这种效果当然是可以的,到处是指令标签 Java代码
<%@includefile="header.jsp" %> <%@includefile="footer.jsp" %> 这样写起来分麻烦,而且一旦改动哪里,为了全局保持统一,到处都要改。 为此,需要用一种好的解决方法,这就是SiteMesh框架,SiteMesh是基于Java、J2EE和XML的开源框架,依赖于从Servlet 2.3版本里引入的新功能——过滤器(Filters),它的主要思想是装饰设计模式,把变化的和不变的分离开来,用不变的去修饰各种变化的内容。 1.下载sitemesh-2.3.jar,当前最新版本好像就是2.3把,放到lib包下 2.在web.xml中添加:
Xml代码
<filter> <filter-name>sitemesh</filter-name> <filterclass> com.opensymphony.module.sitemesh.filter.PageFilter </filter-class> </filter> <filter-mapping> <filter-name>sitemesh</filter-name> <servlet-name>dispatcher</servlet-name> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping> 3.在WEB-INF下面建立文件夹decorators,在decorators中新建几个jsp文件,多少取决于你的需要,我建立了3个,default.jsp,header.jsp和footer.jsp,其中default.jsp运用 Java代码
<%@includefile="header.jsp" %> <%@includefile="footer.jsp" %>指令标签,将两外2个包进去了,default.jsp现在就做为静态不变的部分了。用来修饰变化的部分,其中default.jsp的代码如下: Java代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title><decorator:title/> - xxxx网站</title> <decorator:head/></head><body class="<decorator:getProperty property="meta.class"/>" id="<decorator:getProperty property="meta.id"/>"><c:set var="channel"><decorator:getProperty property="meta.channel"/></c:set><div> <%@include file="header.jsp" %> <decorator:body/> <%@ include file="footer.jsp" %></div></body></html> 4.在WEB-INF下面建立文件decorators.xml,他是用来定义装饰页面的位置和装饰页面应当应用到哪些jsp中的。代码如下 Xml代码
<decorators defaultdir="/WEB-INF/decorators"> <decorator name="default" page="default.jsp"> <pattern>/*</pattern> <pattern>/*.jsp</pattern> </decorator></decorators> 5.在WEB-INF下面建立文件sitemesh.xml,用来告诉框架,什么类型需要用到什么解析器,用到什么映射器,代码如下: 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=UTF-8" class="com.opensymphony.module.sitemesh.parser.HTMLPageParser"/> </page-parsers> <decorator-mappers> <mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper"> <param name="config" value="${decorators-file}"/> </mapper> </decorator-mappers></sitemesh> 这样基本就完成了。很多自定义的内容,比如content-type="text/html;charset=UTF-8" ,也许你还要解析别的meta类型,那就自己再定义,而且sitemesh有很多不同的解析器和映射器,可以自己选择。 原理部分: 1.当web应用程序处理完后,控制返回给SiteMesh的Filter,它会检查web应用生成响应的内容类型(content type),然后基于响应类型,生成不同的解析器来解析响应,这些是在sitemesh.xml中定义的。我所定义的响应类型content-type="text/html"用 HTMLPageParser处理,SiteMesh就会成HTMLPageParser,并把web应用生成的页面传递给它,HTMLPageParser会解析这个页面,提取出这个页面的header、footer、title 等内容。 2.SiteMesh有一个概念,叫做修饰器映射,实现这个概念的接口是DecoratorMapper(有init()和getDecorator()方法)。映射器在sitemesh.xml里声明。在 sitemesh.xml文件里,每一个映射器都是它上一个映射器的父映射。当SiteMesh需要一个修饰器来修饰页面的时候,会在 sitemesh.xml里查找映射器,生成找到的第一个映射器的实例并调用getDecorator()方法,在这个方法里尝试查找针对那个页面的修饰器。如果找到了就返回;否则,调用父映射器的getDecorator()方法,反复进行这个过程,直到找到正确的修饰器。 3.找到修饰器后,SiteMesh会把请求分发给它。修饰器JSP页面(default.jsp)会访问在前阶段里解析出来的页面信息。使用各种SiteMesh自定义标签来提取页面信息不同的部分(比如header、footer和title)并把它们插入到输出文件合适的位置上去。(default.jsp中的<decorator:title/>,<decorator:head/><decorator:body/>等,都是插入信息的地方。) 4.等都插入好了,再发给前端展示出来。你完全不会感受到SiteMesh的存在,配置好了以后,使用就可以了。非常方便 |