摘要:首先这个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. struts-config.xml的配置

    1.<struts-config>  元素 <struts-cofnig> 元素是 Struts 配置文件的根元素.<struts-config> 元素有 8 个子 ...

  2. dubbo高级配置学习

    启动时检查 可以通过check="false"关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动. 关闭某个服务的启动时检查:(没有提供者时报错) < ...

  3. 单词计数,杭电0j-2072

    原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=2072 [Problem Description] lily的好朋友xiaoou333最近很空,他想了一 ...

  4. 浅谈一下web移动端基本

    屏幕尺寸.屏幕分辨率.屏幕像素密度 屏幕尺寸: 指屏幕的对角线的长度,单位是英寸,1英寸=2.54厘米. 常见的屏幕尺寸有2.4.2.8.3.5.3.7.4.2.5.0.5.5.6.0等. 屏幕分辨率 ...

  5. ES6入门2

    for-of循环: 新语法如下: for (var value of myArray) { console.log(value); } 它的优点是: 这是目前遍历数组最简洁和直接的语法: 它避免了fo ...

  6. 无锁模式的Vector

    这两天学习无锁的并发模式,发现相比于传统的 同步加锁相比,有两点好处1.无锁 模式 相比于 传统的 同步加锁  提高了性能 2.无锁模式 是天然的死锁免疫 下来介绍无锁的Vector--- LockF ...

  7. cuda学习1-初始庐山真面目

    cuda作为gpu计算中的代表,拥有着超级高的计算效率,其原因是gpu实际相当与一台超级并行机组,使用过MPI做并行计算的人们可能知道,所谓的并行计算,简单讲就是用多个U(计算单元)来完成一个U的计算 ...

  8. 读 Zepto 源码之集合元素查找

    这篇依然是跟 dom 相关的方法,侧重点是跟集合元素查找相关的方法. 读Zepto源码系列文章已经放到了github上,欢迎star: reading-zepto 源码版本 本文阅读的源码为 zept ...

  9. #417 Div2 C

    #417 Div2 C 题意 给出 n 个货物的基础价格和钱 S ,每个货物的最终价格要加上 购买商品总数 * 商品在原来序列中的序号. 问最多能买多少件,且花费最小. 分析 二分购买商品数量,每次判 ...

  10. Ubuntu环境下 matplotlib 图例中文乱码

    最近做了一个最小二乘法的代码编写并用 matplotlib 绘制了一张图,但是碰到了中文乱码问题.简单搜索之后,发现有人总结出了比较好的方案,亲测可行.推荐给大家. 本文前提条件是 已经 安装好 ma ...