[ZT]Advanced SiteMesh

本文介绍了一个灵活且易于使用的网页修饰框架SiteMesh。该框架利用Servlet2.3版本引入的过滤器功能,允许开发者轻松地为不同页面应用统一的外观和感觉,支持多种内容类型和映射策略。

引用地址:
http://www2.matrix.org.cn/resource/article/44/44550.html
英文原版:
http://www.onjava.com/pub/a/onjava/2004/09/22/sitemesh.html

假设你打算结合多种技术来构建一个企业级web站点。比如,你准备采用J2EE技术往你的web站点里添加新内容,而这个系统的其他部分是用CGI或者微软的IIS Server搭建的。

在这种情况下,怎样让你的应用系统从外观和感受(look and feel)上保持一致呢?一种办案就是采用J2EE技术全部重写,然后选用一种框架,比如Struts-Tiles,但这种办案的开发成本太高,不太现实。另一种可选方案是在你的应用系统的各个部分采用相同的Look and Feel。但这种方案会使维护站点变成噩梦,因为每当一个应用系统里面的Look and Feel需要改变的时候,你就需要让系统里的其他web应用保持同样的改变。

大多数用于解决这种商务需求的可用框架都有一个共同的缺点,他们不是平台相关就是框架相关。当你决定采用Tiles作为struts修饰器的时候,需要创建tiles定义文件tiles-defs.xml,然后在struts-config.xml里面声明forwards,引用这些tiles以修饰原始的JSP。

最简单的一种可能的解决方案是,全部采用纯html方式来生成你的web应用,每一个html页面都不需要知道自己将会被如何修饰,而是在外部采用某种机制来选择合适的修饰器修饰它们。这就是SiteMesh的功能。

SiteMesh是基于Java、J2EE和XML的开源框架,依赖于从Servlet 2.3版本里引入的新功能——过滤器(Filters)

安装和设置

按照以往的经验,学习任何新技术或新框架最好的办法,就是使用它来创建一个简单的应用程序。所以,我们将使用SiteMesh来创建一个简单的Struts应用程序。我们的应用程序包括三个页面:

•一个登录页面
•一个帮助页面,包括页头和页脚
•一个主页面,包括页头、页脚和页边菜单

下面是创建这个简单web应用程序的步骤:

1.SiteMesh基于过滤器,所以我们需要把SiteMesh过滤器通知给我们的web应用程序。在web.xml文件里加入如下几行:

<filter>
  <filter-name>sitemesh</filter-name>
  <filter-class>
      com.opensymphony.module.sitemesh.filter.PageFilter
  </filter-class>
  <init-param>
    <param-name>debug.pagewriter</param-name>
    <param-value>true</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>sitemesh</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

这几行是告诉web容器,所有对web应用的请求都会经由PageFilter“过滤”一下。PageFilter是sitemesh-2.1.jar里的一个类,你可以从http://www.opensymphony.com/sitemesh/download.html下载该jar包。

2.在WEB-INF目录下生成一个decorators.xml文件,内容如下:

<decorators defaultdir="/decorators">
  <!— 给需要页边菜单的页面配置页边菜单修饰器 -->
  <decorator name="sidemenu" page="sidemenu.jsp">
    <pattern>/home.jsp</pattern>
  </decorator>
  <!— 给需要页头和页脚的页面配置页头页脚修饰器 -->
  <decorator name="headerfooter" page="headerfooter.jsp">
    <pattern>/help.jsp</pattern>
  </decorator>
</decorators>

decorators.xml文件用来在你的应用程序里定义修饰器(decorators)。在这个文件里,每个<decorator>元素定义一个修饰器,name指定修饰器名,page指定修饰器所使用的JSP页面。<pattern>子元素指定这些修饰器如何应用到实际的页面上去。

在我们的示例web应用里,定义了两个修饰器:追加页头和页脚的headerfooter.jsp和追加页边菜单的sidemenu.jsp。我们想修饰help页面追加页头和页脚,所以我们追加了一个/help.jsp路径子元素给headerfooter.jsp修饰器。

3.在WebContent/decorators目录下创建headerfooter.jsp:

<%@ taglib
    uri="http://www.opensymphony.com/sitemesh/decorator"
    prefix="decorator" %>
<html>
  <head>
    <title>
      My Site -
      <decorator:title default="Welcome!" />
    </title>
    <decorator:head />
  </head>
  <body>
    <table>
      <tr>
        <td>
          <H1>
            SiteMesh Corporation
          <H1>
        </td>
      </tr>
      <tr>
        <td><decorator:body /></td>
      </tr>
      <tr>
        <td> SiteMesh copyright</td>
      </tr>
    </table>
  </body>
</html>

一个SiteMesh修饰器其实就是一个使用SiteMesh自定义标签的JSP页面。在我们的web应用里,当用户请求help页面的时候,SiteMesh会拦截这个请求,然后再把它发送给web应用。而当应用返回响应的时候,SiteMesh会结合headerfooter.jsp文件解析这个响应,遇到<decorator:head/>就插入响应文件的<head>,遇到<decorator:body/>就插入响应文件的<body>。最后,被headerfooter.jsp修饰过的文件会被返回给客户端。

4.在WebContent目录下创建help.jsp:

<HTML>
<HEAD>
<%@ page
language="java"
contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"
%>
<TITLE>Help Page</TITLE>
</HEAD>
<BODY>
  Help Page
</BODY>
</HTML>

这是一个在web应用里很常见的help页面。

5.在浏览器里请求help.jsp页面,测试SiteMesh安装是否正常。浏览器将会返回一个包含页头和页脚的help页面。

SiteMesh架构

SiteMesh架构基于PageFilter——一个Servlet过滤器。容器接收到页面请求时,会把请求传递给PageFilter,PageFilter收集应用程序的响应细节,生成自定义的响应对象,然后连同请求一起传递给web应用程序。web应用程序把响应资源写入到自定义响应对象里,再返回给PageFilter。

1.解析阶段
当控制返回给PageFilter的时候,它会检查web应用生成响应的内容类型(content type),然后基于响应类型,生成不同的解析器来解析响应。比如,如果应用返回text/html类型的内容,SiteMesh会生成一个FastPageParser实例,并把web应用生成的页面传递给它。FastPageParser会解析这个页面,提取出这个页面的header、footer、title 等内容。

2.修饰阶段

解析结束后,SiteMesh开始修饰页面。这一阶段分成两部分:

a.决定如何修饰

SiteMesh有一个概念,叫做修饰器映射,实现这个概念的接口是DecoratorMapper(有init()和getDecorator()方法)。映射器在sitemesh.xml里声明。在sitemesh.xml文件里,每一个映射器都是它上一个映射器的父映射。当SiteMesh需要一个修饰器来修饰页面的时候,会在sitemesh.xml里查找映射器,生成找到的第一个映射器的实例并调用getDecorator()方法,在这个方法里尝试查找针对那个页面的修饰器。如果找到了就返回;否则,调用父映射器的getDecorator()方法,反复进行这个过程,直到找到正确的修饰器。

b.应用修饰

找到修饰器后,SiteMesh会把请求分发给它。修饰器JSP页面会访问在前阶段里解析出来的页面信息。使用各种SiteMesh自定义标签来提取页面信息不同的部分(比如header、footer和title)并把它们插入到输出文件合适的位置上去。

你可以在sitemesh.xml文件里自定义使用哪个页面解析器来解析指定的内容类型或者使用哪种修饰器映射方案,比如:

<?xml version="1.0" encoding="UTF-8"?>
<sitemesh>
  <property name="decorators-file" value="/WEB-INF/decorators.xml"/>
  <excludes file="${decorators-file}"/>
  <page-parsers>
    <parser content-type="text/html"
        class="com.opensymphony.module.sitemesh.parser.FastPageParser" />
  </page-parsers>
  <decorator-mappers>
    <mapper
        class="com.opensymphony.module.sitemesh.mapper.PageDecoratorMapper">
      <param name="property.1" value="meta.decorator" />
      <param name="property.2" value="decorator" />
    </mapper>
    <!-- Mapper for localization -->
    <mapper
        class="com.opensymphony.module.sitemesh.mapper.LanguageDecoratorMapper">
      <param name="match.en" value="en" />
      <param name="match.zh" value="zh" />
    </mapper>
    <!-- Mapper for browser compatibility -->
    <mapper
        class="com.opensymphony.module.sitemesh.mapper.AgentDecoratorMapper">
      <param name="match.MSIE" value="ie" />
      <param name="match.Mozilla/" value="ns" />
    </mapper>
    <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.ParameterDecoratorMapper">
      <param name="decorator.parameter" value="decorator" />
      <param name="parameter.name" value="confirm" />
      <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>

在这个列表里,<property name="decorators-file">指定了用于定义修饰器的文件。<page-parsers>定义了SiteMesh可以处理的内容类型。每一个<parser>子元素指定哪一个解析器解析哪一种特定的内容类型。在我们的示例sitemesh.xml文件里,我们告诉SiteMesh使用FastPageParser解析text/html类型的内容。默认地,SiteMesh只可以处理HTML,但我们可以创建自己的解析器来处理其他的内容类型。

<decorator-mappers>子元素定义了映射方案,SiteMesh使用这个映射方案来查找修饰指定页面的修饰器。你可以使用<param>子元素来配置每一个映射器。SiteMesh会把这些配置信息包装成java.util.Properties对象传递给映射器的init()方法。

区域相关的修饰器

在我们的示例sitemesh.xml文件里,有下面几行标签:

<mapper class="com.opensymphony.module.sitemesh.mapper.LanguageDecoratorMapper">
  <param name="match.en" value="en" />
  <param name="match.zh" value="zh" />
</mapper>

当查找一个应用于页面的修饰器时,SiteMesh会首先读取请求头部的Accept-Language信息。如果匹配en区域,SiteMesh会在修饰器JSP文件名末尾追加-en。在我们的例子里,如果请求定义了修饰器headerfooter.jsp的help.jsp页面,并且使用的是区域是英国,SiteMesh会首先查找并应用headerfooter-en.jsp修饰器,如果找不到再去应用headerfooter.jsp。

浏览器相关的修饰器

可以使用AgentDecoratorMapper来保证浏览器的兼容性:

<mapper
class="com.opensymphony.module.sitemesh.mapper.AgentDecoratorMapper">
  <param name="match.MSIE" value="ie" />
  <param name="match.Mozilla/" value="ns" />
</mapper>

这意味着当SiteMesh查找一个修饰器来修饰页面的时候,会首先提取出请求头部的User-Agent信息。如果是IE,就加上-ie到修饰器的文件名末尾,并查找和应用这个修饰器。如果找不到这样的修饰器,则继续应用headerfooter.jsp。

高级SiteMesh

SiteMesh提供映射器,让每一个页面参与到寻找自己修饰器的过程中去。

PrintableDecoratorMapper

大多数的web站点都提供了一个获得可打印版本页面的功能。所谓可打印版本,一般是指去除了页头、页尾和页边菜单,并使用了另一套样式表的页面。在SiteMesh里,我们可以使用PrintableDecoratorMapper来提供这个功能。要使用这个映射器,需要在sitemesh.xml里追加如下几行:

<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>

传递给PrintableDecoratorMapper的三个配置参数会被包装成java.util.Properties对象传递给init()方法。

•decorator
  用来生成可打印版本页面的修饰器名。

•parameter.name
  用来通知SiteMesh我们需要一个可打印版本的请求参数名。比如在我们的例子里,通过在查询字符串里追加printable=true参数传递

•parameter.value
  设置可打印参数为何值时SiteMesh提供可打印版本的页面。

PageDecoratorMapper

页面可以通过定义META属性来重载指定修饰自己的修饰器名。

要使用这个映射器,需要在sitemesh.xml文件里加入如下几行:

<mapper
class="com.opensymphony.module.sitemesh.mapper.PageDecoratorMapper">
  <param name="property.1" value="meta.decorator" />
</mapper>

PageDecoratorMapper可以获取一个参数列表。在我们的例子里,提供了一个参数名,指定了通过META属性来取得修饰器名。所以如果我们希望使用test修饰器来修饰页面,则在该页头部加入:

<META name="decorator" content="test">

PageDecoratorMapper提供了一种静态的方法来让页面选择自己想要使用的修饰器。另外,页面还可以通过使用ParameterDecoratorMapper在运行时指定要使用的修饰器。

ParameterDecoratorMapper

要使用ParameterDecoratorMapper,在sitemesh.xml里追加如下几行:

<mapper
class= "com.opensymphony.module.sitemesh.mapper.ParameterDecoratorMapper">
  <param name="decorator.parameter" value="decorator" />
  <param name="parameter.name" value="confirm" />
  <param name="parameter.value" value="true" />
</mapper>

三个参数的意义分别如下:

•decorator.parameter
  指定修饰器所使用的请求参数名。

•parameter.name
  确定使用请求修饰器的确认参数名。

•parameter.value
  确定使用请求修饰器的确认参数值。

比如,如果你想使用test修饰器来修饰help.jsp,可以像下面这样访问help.jsp

help.jsp?decorator=test&confirm=true

除了以上这些映射器以外,SiteMesh还提供了更多有用的映射器,比如:

•FrameSetDecoratorMapper
  当页面是Frame的时候使用。

•CookieDecoratorMapper
  可以通过cookie来指定想要使用的修饰器。

•RobotDecoratorMapper
  当请求者被确人为robot的时候使用指定的修饰器。你可以手动的在请求头部追加robot关键字,或者通过修饰器来做。

Velocity 和 Freemarker 修饰器

SiteMesh并没有限制你只能修饰JSP页面。你可以自由的选择想要修饰的对象,比如Velocity或者Freemarker。Velocity和Freemarker是一种可被用于生成web页面的模板语言。这些语言比JSP更加的简单易用,但在可编程性方面不如JSP灵活。

SiteMesh通过两个servlet支持这两种模板语言,这两个servlet也被定义在SiteMesh.jar文件里。我们可以像这样在web.xml里声明这两个servlet:

<servlet>
  <servlet-name>sitemesh-velocity</servlet-name>
  <servlet-class>
    com.opensymphony.module.sitemesh.velocity.VelocityDecoratorServlet
  </servlet-class>
</servlet>
<!--Declare servlet for handling freemarker requests -->
<servlet>
  <servlet-name>sitemesh-freemarker</servlet-name>
  <servlet-class>
    com.opensymphony.module.sitemesh.freemarker.FreemarkerDecoratorServlet
  </servlet-class>
  <init-param>
    <param-name>TemplatePath</param-name>
    <param-value>/</param-value>
  </init-param>
  <init-param>
    <param-name>default_encoding</param-name>
    <param-value>ISO-8859-1</param-value>
  </init-param>
</servlet>
<!-- Velocity servlet should serve all requests with .vm extension-->
<servlet-mapping>
  <servlet-name>sitemesh-velocity</servlet-name>
  <url-pattern>*.vm</url-pattern>
</servlet-mapping>
<!-- FreeMarker servlet should serve all requests with .dec extension-->
<servlet-mapping>
  <servlet-name>sitemesh-freemarker</servlet-name>
  <url-pattern>*.dec</url-pattern>
</servlet-mapping>

当然,我们还需要在lib文件夹里引入freemarker.jar、velocity-dep.jar和velocity-tools-view.jar。这些jar文件已经包含在SiteMesh的发布包里了。下面让我们修改第一个示例应用,使用Velocity和Freemarker修饰器来取代JSP。在我们第一个示例应用里定义了两个修饰器:headerfooter和sidemenu。下面我们创建一个headerfooter.dec:

<html>
  <head>
    <title>My Site - $Advanced SiteMesh</title>
      ${head}
  </head>
  <body>
    <table border="1">
      <tr>
        <td>SiteMesh Corporation</td>
      </tr>
      <tr>
        <td>${body}</td>
      </tr>
      <tr>
        <td>SiteMesh copyright</td>
      </tr>
    </table>
  </body>
</html>

在这个页面里,我们使用Freemarker模板来请求header、footer和title,而不是使用JSP自定义标签,但页面布局是一样的。当容器接收到一个.dec扩展名的页面请求时,会把这个请求传递给FreemarkerDecoratorServlet,后者将会调用FreemarkerDecorator修饰生成的HTML页面。我们使用$Advanced SiteMesh模板来访问应用生成的web页面的title,${head}访问head,${body}访问body。Freemarker提供了非常丰富的模板,想深入研究的话可以参考http://www.javaworld.com/jw-01-2001/jw-0119-freemarker.html。

相似的,在decorators目录下创建sidemenu.vm文件,这是Velocity修饰器文件:

<html>
  <head>
    <title>My Site - $title</title>
      $head
  </head>
  <body>
    <table border="1">
      <tr>
        <td> SiteMesh Header </td>
      </tr>
      <tr>
        <td> Sidemenu </td>
        <td> $body </td>
      </tr>
      <tr>
        <td> SiteMesh Footer </td>
      </tr>
    </table>
  </body>
</html>

使用$title模板取代<decorator:title/>,使用$head和$body Velocity模板来取代相应的JSP自定义标签。

结论

基于过滤器的SiteMesh是一个非常灵活和简单易用的修饰器框架。但它还是存在着一些问题。首先,从Servlet 2.3版本才开始支持过滤器,所以一些早期版本的应用服务器无法支持SiteMesh。在使用SiteMesh之前请先检查一下您想使用的应用服务器是否支持过滤器。

另外,过滤器只有在使用浏览器请求一个页面的时候才能生效。所以,如果你通过浏览器访问home.jsp,它将被修饰,但如果你使用Servlet的RequestDispatcher.include()或者forward()来控制home.jsp,修饰器就不起作用了。但是不用担心,从Servlet 2.4版本开始,你可以配置过滤器适用的环境,包括forward和include的情况下都可以使用了。
的情况下都可以使用了。

内容概要:本文提出一种面向高柔性柔性作业车间的混合调度优化算法——元胞邻域遗传-随机重启爬山混合调度优化算法,该算法深度融合元胞自动机的局部搜索机制与遗传算法的全局寻优能力,并创新性地引入随机重启爬山策略以增强跳出局部最优的能力,从而有效应对高柔性车间环境中工序灵活、设备多样、约束复杂的调度挑战;通过构建精细化的数学模型,算法在满足工艺顺序、资源能力等多重约束的前提下,以最小化最大完工时间等为目标,显著提升了调度方案的质量与求解效率,相关方法已通过Matlab编程实现,支持仿真实验与性能验证,为复杂制造系统的智能调度提供了理论支撑与技术路径; 适合人群:具备一定编程基础,熟悉Matlab工具,从事智能制造、工业工程、自动化或运筹优化方向的研究生、科研人员及工程技术人员; 使用场景及目标:① 解决高柔性作业车间中的复杂任务调度问题;② 提升多工序、多设备、多约束条件下生产调度的优化性能;③ 为智能优化算法在工业场景中的融合应用提供参考案例与代码实现基础; 阅读建议:建议读者结合文中提到的智能优化算法背景知识进行系统学习,重点关注元胞邻域结构设计与遗传算法的融合机制,动手运行并调试提供的Matlab代码,通过仿真实验加深对算法收敛性与调度效果的理解。
内容概要:本文系统阐述了基于CNN-SVM的混合数据分类预测方法在故障识别领域的应用,重点介绍如何将卷积神经网络(CNN)与支持向量机(SVM)相结合,以提升工业系统中故障分类的准确性与鲁棒性。该方法首先利用CNN强大的自动特征提取能力对原始高维、非平稳信号数据进行深层抽象,获取具有判别性的高级特征表示,随后将这些特征输入至SVM分类器中,充分发挥SVM在小样本、非线性分类任务中的泛化优势,从而构建出兼具深度学习强表达能力与传统机器学习高分类精度的融合模型。研究通过Matlab平台实现了完整的算法流程,涵盖数据预处理、CNN结构设计、特征提取、SVM训练与参数优化、模型评估等环节,并结合实际工业故障数据集进行了仿真实验,验证了该混合模型相较于单一模型在分类精度、稳定性及抗噪能力方面的显著提升。; 适合人群:具备一定机器学习理论基础和Matlab编程能力,从事电气工程、自动化控制、智能制造、设备状态监测等相关领域研究的研究生、工程师及科研人员,尤其适合致力于故障诊断、智能预测与工业大数据分析的技术从业者。; 使用场景及目标:①应用于旋转机械(如电机、轴承)、电力电子设备、传动系统等工业装备的多类别故障识别与状态分类;②解决传统诊断方法在复杂工况下特征提取困难、分类性能不稳定的问题,提高早期微弱故障的检出率;③为相关科研项目提供可复现的算法框架与代码实例,支撑高水平论文撰写与工程原型开发。; 阅读建议:建议读者结合所提供的Matlab代码进行动手实践,深入理解CNN特征提取层(如卷积核设计、池化操作)与SVM分类器(如核函数选择、惩罚系数调优)之间的协同机制,重点关注模型超参数调优策略与交叉验证方法,进而可将该混合架构迁移至其他分类任务中,探索其在不同数据场景下的适用性与优化空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值