摘要:首先这个Decorator解释一下这个单词:“装饰器”,我觉得其实可以这样理解,他就像我们用到的Frame,他把每个页面共有的东西提炼了出来,也可能我们也会用各种各样的include标签,将我们的常用页面给包括进来:比如说页面的top,bottom这些每个页面几乎都有,而且都一样,如果我们在每个页面都include,可以发现我们的程序有很多冗余,重复。相比之下装饰器给我们提供了一个较好的选择,他在你要显示的页面根本看不出任何include信息,可以说完全解耦。

一、SiteMesh介绍

SiteMesh是一个Java WEB项目的网页布局和修饰框架。使用SiteMesh后就不再需要在每个页面中都用<jsp:include>标签引入页头、页尾、导航等其他公用页面了。

  • 可以将网页的内容和页面结构分离,达到页面结构共享的目的。
  • 页面装饰效果耦合在目标页面中,无需使用include指令显示包含装饰效果,目标页面和装饰页面完全分离
  • 整个web应用可以使用相同的装饰页面,风格统一,整体效果更好
  • SiteMesh通过Filter拦截请求和响应,给原始页面加入装饰,再把装饰后的结果返回给客户端。
  • 根据页面URL匹配规则查找合适的装饰模板页
  • 提取被访问页的内容,放置到装饰模板中的适当位置。

二、业务场景使用

比如常见的就是crm系统,左边的树形菜单就是一致的,变化的右边主体部分(即被装饰的页面)。

三、SiteMesh工作原理

sitemesh应用Decorator模式,用filter截取request和response,把页面组件head,content,banner、bottom结合为一个完整的视图。通常我们都是用include标签在每个jsp页面中来不断的包含各种header, stylesheet, scripts and footer。见下图

当用户请求home.jsp,并且服务器处理完毕正准备返回数据之时,它被SiteMesh Filter拦截了下来,并且把数据包装成一个Page对象,具体是Page page = parsePage(request, response, chain)的调用,然后,它会去查询decorators.xml文件,看看该页面是否需要装饰[if (decorator != null && decorator.getPage() != null)]?是,则应用装饰器[applyDecorator(page, decorator, request, response)],否则,就发送原来的没经过装饰的页面[writeOriginal(response, page);]。

四、sitemesh应用配置

首先我们要到http://www.opensymphony.com/sitemesh/下载我们需要的jar包:sitemesh-2.4.jar

然后分三步走,第一步:web.xml配置;第二步:decorate.xml配置;第三步:装饰页面

4.1 web.xml配置

    <filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
</filter> <filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

4.2 decorate.xml 配置

在WEB-INF目录下新建一个decorators.xml文件(/decorator是你的包装jsp根路径在这里main.jsp和panel.jsp都是包装jsp,a.jsp,b,jsp是被包装jsp)

<?xml version="1.0" encoding="UTF-8"?>
<decorators>
<excludes>
<pattern>/resources/**</pattern>
<pattern>/system/login_index.do</pattern>
<pattern>/system/login.do</pattern>
<pattern>/system/close_window.do</pattern>
<pattern>/system/login_force.jsp</pattern>
<pattern>/system/info.jsp</pattern>
<pattern>/index.jsp</pattern>
<pattern>/usermemcached/**</pattern>
</excludes>
<decorator name="main" page="/system/main.do">
<pattern>/**</pattern>
</decorator>
</decorators>

用decrator指定装饰模板与URL的对应关系,也可以用excludes配置那些URL不需要模板控制。

4.3 装饰页面

<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="decorator" uri="http://www.opensymphony.com/sitemesh/decorator" %>
<html>
  <head>
    <title> <decorator:title default="default title"/> </title> 
    <decorator:head/>
  </head>
  <body /> >
     <div id="content" class="container" style="width: 100%;">
<c:if test="${not empty actionResult}">
<div class="alert alert-${actionResult.type}">
<button class="close" type="button" data-dismiss="alert">X</button>
<spring:message code="${actionResult.message}"></spring:message>
</div>
</c:if>
<!-- 所有被拦截器拦截后,匹配的url页面都会插入到此 -->
<decorator:body></decorator:body>
</div>
    ......
    <jsp:include page="/footer.jsp"></jsp:include>
  </body>
</html>

参数说明:

<decorator:head />

填充被装饰页面的head标签内容

<decorator:body />

填充被装饰页面的body标签内容

使用 sitemesh/decorator装饰器装饰jsp页面(原理及详细配置)的更多相关文章

  1. python 带参与不带参装饰器的使用与流程分析/什么是装饰器/装饰器使用注意事项

    一.什么是装饰器 装饰器是用来给函数动态的添加功能的一种技术,属于一种语法糖.通俗一点讲就是:在不会影响原有函数的功能基础上,在原有函数的执行过程中额外的添加上另外一段处理逻辑 二.装饰器功能实现的技 ...

  2. Python 使用装饰器装饰类

    1.装饰器装饰函数 了解过或学过装饰器的同学都知道,Python 中的装饰器是可以装饰函数的,如: # 定义一个装饰器 def decorator(func): def inner(*args,**k ...

  3. python 装饰器(八):装饰器实例(五)函数装饰器装饰类以及类方法

    函数装饰器装饰类 单例模式 from functools import wraps def singleton(cls): instances = {} @wraps(cls) def get_ins ...

  4. Python 装饰器装饰类中的方法

    title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] categ ...

  5. Python_函数的有用信息、带参数的装饰器、多个装饰器装饰一个函数

    函数的有用信息 代码1: def login(username, password): """ 此函数需要用户名,密码两个参数,完成的是登录的功能. :return: T ...

  6. python全栈开发day12-函数的有用信息、带参数的装饰器、多个装饰器装饰一个函数、global和nonlocal的进一步解析和总结

    1.上周回顾 1).函数名的应用 直接打印函数名,是函数的地址 变量 函数的参数 函数的返回值 可以当容器类数据类型的元素 2).闭包 内层函数对外层函数的非全局变量的引用,就是闭包. 并返回内部函数 ...

  7. python-day14--带参数的装饰器+多个装饰器装饰同一个函数

    1.# 带参数的装饰器def f1(flag): def f2(func): def inner(*args,**kwargs): if flag: '''执行函数之前要做的''' r=func(*a ...

  8. python 装饰器 (多个装饰器装饰一个函数---装饰器前套一个函数)

    #带参数的装饰器 #500个函数 # import time # FLAGE = False # def timmer_out(flag): # def timmer(func): # def inn ...

  9. Python中的多个装饰器装饰一个函数

    def wrapper1(func1): def inner1(): print('w1 ,before') func1() print('w1 after') return inner1 def w ...

  10. python编程系列---多个装饰器装饰一个函数的执行流程

    首先看一个例子 ''' 多个装饰器装饰一个函数 ''' # 定义第一个装饰器 def set_func1(func): def wrapper1(*args,**kwargs): print('装饰内 ...

随机推荐

  1. nodejs弯路-01之'express' 不是内部或外部命令

    最近正想用node+angular+mongodb来完成一个小项目,三样都算是从零开始学习吧. 一开始是想用express -e projectname去创建一个ejs模板的项目.(一两句话就可以把大 ...

  2. Git分支合并选择

    用Git进行多人协作开发时,必然会合并代码,解决冲突.然而合并代码也是需要点技巧的,如果对一些关键命令没有理解去使用的话,git的版本演进路线就会变得很乱,从而造成了日后维护的一些麻烦. Git上合并 ...

  3. 获取JUnit的执行结果

    junit执行之后会有一个结果展示,下面就来看一下怎么获取这些结果并将其存储为一个对象 junit代码如下: package test; import org.junit.After; import ...

  4. dbunit进行DAO层Excel单元测试

    DAO层测试难点 可重复性,每次运行单元测试,得到的数据是重复的 独立性,测试数据与实际数据相互独立 数据库中脏数据预处理 不能给数据库中数据带来变化 DAO层测试方法 使用内存数据库,如H2.优点: ...

  5. 1.搭建Maven 多模块应用 --Intellij IDEA 2016.3.5

    1.打开IDEA,file->new ->project  新建工程 2.建成的项目如下图,然后新建java class 模块: 右击工程名->new -> Module 3. ...

  6. Lua 设置table为只读属性

    项目中部分只读表易被人误改写,故决定在非线上环境里对这些表附加只读属性,方便在出现误改写的时候抛出lua错误,最终版代码如下: --[[-------------------------------- ...

  7. CAP原理、一致性模型、BASE理论和ACID特性

    CAP原理 在理论计算机科学中,CAP定理(CAP theorem),又被称作布鲁尔定理(Brewer's theorem),它指出对于一个分布式计算系统来说,不可能同时满足以下三点: 一致性(Con ...

  8. activeMQ的简单介绍

    1.什么叫activeMQ? ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现 ...

  9. PropertyGrid自定义控件

    PropertyGrid是一个很强大的控件,使用该控件做属性设置面板的一个好处就是你只需要专注于代码而无需关注UI的呈现,PropertyGrid会默认根据变量类型选择合适的控件显示.但是这也带来了一 ...

  10. 关于HBuilder的一些使用技巧。

    在HBuilder中一个名为扩展代码块的功能. 扩展代码块 看,它就在上方工具栏的工具选项中,分为自定义html代码块, 自定义js代码块, 自定义css代码块, 自定义jquery代码块. 以下便是 ...