﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-gdufo-随笔分类-Appfuse</title><link>http://www.blogjava.net/gdufo/category/32566.html</link><description /><language>zh-cn</language><lastBuildDate>Sun, 07 Sep 2008 01:47:43 GMT</lastBuildDate><pubDate>Sun, 07 Sep 2008 01:47:43 GMT</pubDate><ttl>60</ttl><item><title>Appfuse的Quartz配置</title><link>http://www.blogjava.net/gdufo/archive/2008/09/06/227446.html</link><dc:creator>gdufo</dc:creator><author>gdufo</author><pubDate>Sat, 06 Sep 2008 14:42:00 GMT</pubDate><guid>http://www.blogjava.net/gdufo/archive/2008/09/06/227446.html</guid><wfw:comment>http://www.blogjava.net/gdufo/comments/227446.html</wfw:comment><comments>http://www.blogjava.net/gdufo/archive/2008/09/06/227446.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gdufo/comments/commentRss/227446.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gdufo/services/trackbacks/227446.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.blogjava.net/gdufo/archive/2008/09/06/227446.html'>阅读全文</a><img src ="http://www.blogjava.net/gdufo/aggbug/227446.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gdufo/" target="_blank">gdufo</a> 2008-09-06 22:42 <a href="http://www.blogjava.net/gdufo/archive/2008/09/06/227446.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SiteMesh的使用 </title><link>http://www.blogjava.net/gdufo/archive/2008/08/25/224283.html</link><dc:creator>gdufo</dc:creator><author>gdufo</author><pubDate>Mon, 25 Aug 2008 12:51:00 GMT</pubDate><guid>http://www.blogjava.net/gdufo/archive/2008/08/25/224283.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.blogjava.net/gdufo/archive/2008/08/25/224283.html'>阅读全文</a><img src ="http://www.blogjava.net/gdufo/aggbug/224283.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gdufo/" target="_blank">gdufo</a> 2008-08-25 20:51 <a href="http://www.blogjava.net/gdufo/archive/2008/08/25/224283.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Appfuse 中使用的 JSTL 标签库详细介绍资料</title><link>http://www.blogjava.net/gdufo/archive/2008/08/25/224251.html</link><dc:creator>gdufo</dc:creator><author>gdufo</author><pubDate>Mon, 25 Aug 2008 11:55:00 GMT</pubDate><guid>http://www.blogjava.net/gdufo/archive/2008/08/25/224251.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.blogjava.net/gdufo/archive/2008/08/25/224251.html'>阅读全文</a><img src ="http://www.blogjava.net/gdufo/aggbug/224251.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gdufo/" target="_blank">gdufo</a> 2008-08-25 19:55 <a href="http://www.blogjava.net/gdufo/archive/2008/08/25/224251.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Appfuse 中使用到的 DisplayTag</title><link>http://www.blogjava.net/gdufo/archive/2008/08/25/224250.html</link><dc:creator>gdufo</dc:creator><author>gdufo</author><pubDate>Mon, 25 Aug 2008 11:53:00 GMT</pubDate><guid>http://www.blogjava.net/gdufo/archive/2008/08/25/224250.html</guid><wfw:comment>http://www.blogjava.net/gdufo/comments/224250.html</wfw:comment><comments>http://www.blogjava.net/gdufo/archive/2008/08/25/224250.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gdufo/comments/commentRss/224250.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gdufo/services/trackbacks/224250.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.blogjava.net/gdufo/archive/2008/08/25/224250.html'>阅读全文</a><img src ="http://www.blogjava.net/gdufo/aggbug/224250.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gdufo/" target="_blank">gdufo</a> 2008-08-25 19:53 <a href="http://www.blogjava.net/gdufo/archive/2008/08/25/224250.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Appfuse2.x学习-Ajax</title><link>http://www.blogjava.net/gdufo/archive/2008/08/09/220977.html</link><dc:creator>gdufo</dc:creator><author>gdufo</author><pubDate>Sat, 09 Aug 2008 00:35:00 GMT</pubDate><guid>http://www.blogjava.net/gdufo/archive/2008/08/09/220977.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.blogjava.net/gdufo/archive/2008/08/09/220977.html'>阅读全文</a><img src ="http://www.blogjava.net/gdufo/aggbug/220977.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gdufo/" target="_blank">gdufo</a> 2008-08-09 08:35 <a href="http://www.blogjava.net/gdufo/archive/2008/08/09/220977.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AppFuse中DisplayTag乱码问题的解决(1.9)</title><link>http://www.blogjava.net/gdufo/archive/2008/08/06/220527.html</link><dc:creator>gdufo</dc:creator><author>gdufo</author><pubDate>Wed, 06 Aug 2008 15:00:00 GMT</pubDate><guid>http://www.blogjava.net/gdufo/archive/2008/08/06/220527.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.blogjava.net/gdufo/archive/2008/08/06/220527.html'>阅读全文</a><img src ="http://www.blogjava.net/gdufo/aggbug/220527.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gdufo/" target="_blank">gdufo</a> 2008-08-06 23:00 <a href="http://www.blogjava.net/gdufo/archive/2008/08/06/220527.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>结合appfuse学习acegi</title><link>http://www.blogjava.net/gdufo/archive/2008/08/04/220059.html</link><dc:creator>gdufo</dc:creator><author>gdufo</author><pubDate>Mon, 04 Aug 2008 15:56:00 GMT</pubDate><guid>http://www.blogjava.net/gdufo/archive/2008/08/04/220059.html</guid><wfw:comment>http://www.blogjava.net/gdufo/comments/220059.html</wfw:comment><comments>http://www.blogjava.net/gdufo/archive/2008/08/04/220059.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gdufo/comments/commentRss/220059.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gdufo/services/trackbacks/220059.html</trackback:ping><description><![CDATA[<div class="cnt" id="blog_text">
<p><font size="3"><font color="#0000ff"><strong>1.web.xml的配置<br />
</strong></font></p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><strong><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></strong><strong><span style="color: #000000">web.xml加入如下Filter的配置<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter</span></strong><strong><span>&gt;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&lt;</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">securityFilter</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-name</span></strong><strong><span>&gt;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&lt;</span><span style="color: #800000">filter-class</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">org.acegisecurity.util.FilterToBeanProxy</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-class</span></strong><strong><span>&gt;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&lt;</span><span style="color: #800000">init-param</span></strong><strong><span>&gt;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;</span><span style="color: #800000">param-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">targetClass</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">param-name</span></strong><strong><span>&gt;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;</span><span style="color: #800000">param-value</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">org.acegisecurity.util.FilterChainProxy</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">param-value</span></strong><strong><span>&gt;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/</span><span style="color: #800000">init-param</span></strong><strong><span>&gt;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/</span><span style="color: #800000">filter</span></strong><span><strong>&gt;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></strong></span></div>
<p><br />
<strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong><span style="font-size: 10pt"><strong>FilterToBeanProxy就是Acegi过滤器Bean的代理，功能是把http请求按顺序分派给过滤器Bean；<br />
说明：Acegi对WEB应用的支持主要是依靠servlet 过滤器（filter） 来实现的。每一个http request都将被这┕ 似鞑悴憷菇?并进行安全处理（包括认证和授权）。针对不同的安全处理，Acegi提供了不同的过滤器。过滤器的配置信息理论上应位于web.xml，但是我们又希望把Acegi的过滤器配置信息放在SpringFramework的配置文件里（applicationContext-security-acegi.xml），从而实现对这些过滤器的&#8220;控制反转&#8221;。解决这个问题的方法是采用Acegi提供的FilterToBeanProxy。FilterToBeanProxy顾名思义就是对Acegi过滤器Bean的代理，它的主要功能就是将http请求依次分派给对应的过滤器Bean。<br />
这个Filter需要一个参数targetClass(目标类)，意思是说代理哪个bean，为它配置的值是FilterChainProxy，就是由这个FilterChainProxy类负责将需要代理的这些Filter组成Filter代理&#8220;链&#8221;(这些Filter在Security.xml这个配置文件里以bean的形式进行配置了)<br />
</strong></span></font><font size="3"><span style="font-size: 10pt"><strong>web.xml加入如下内容<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;securityFilter&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/j_security_check&lt;/url-pattern&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/filter-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;securityFilter&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;*.html&lt;/url-pattern&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/filter-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;securityFilter&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;*.jsp&lt;/url-pattern&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/filter-mapping&gt;<br />
这个就好理解了，就是这样的url都让他被securityFilter这个过滤器过滤处理<br />
<br />
web.xml加入如下内容<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;context-param&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;/WEB-INF/applicationContext-*.xml,/WEB-INF/security.xml&lt;/param-value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/context-param&gt;<br />
这个就是让上下文载入/WEB-INF/applicationContext-*.xml,/WEB-INF/security.xml这些配置文件</strong></span></font></p>
<p><font size="3"><span style="font-size: 10pt"><strong><font color="#0000ff">2.security.xml的配置</font><br />
首先加入filterChainProxy这个bean的定义，因为前面在web.xml配置的filter需要这个bean<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="filterInvocationDefinitionSource"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PATTERN_TYPE_APACHE_ANT<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON定义了url比较前先转为小写， PATTERN_TYPE_APACHE_ANT定义了使用Apache ant的匹配模式<br />
这个bean将httpSessionContextIntegrationFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor这些bean组成了filter链，当发生需要web.xml配置的过滤器的对应的需要过滤的url的请求时，这些filter将会<font color="#ff0000">按照定义的顺序</font>被调用，这个过滤器的mapping是&#8220;/*&#8221;。<br />
既然配置了这些需要被调用的给filterChainProxy，那么就要对这些filter进行逐个配置，以便filterChainProxy能找到并调用他们。<br />
</strong><span style="color: #000000"><span style="font-size: 10pt"><font size="3"><span style="color: #000000"><span style="font-size: 10pt"><font size="3"><span style="color: #000000"><font size="3"><span style="color: #000000"><strong>httpSessionContextIntegrationFilter的配置及作用<br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" /></strong><span style="color: #000000"><strong>&lt;<span style="color: #000000">bean id<span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">httpSessionContextIntegrationFilter</span><span style="color: #000000">"</span></span></strong></font><font size="3"><span style="color: #000000"><strong> <br />
<span style="color: #000000"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">org.acegisecurity.context.HttpSessionContextIntegrationFilter</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span><br />
每次request前 <font color="#000000">HttpSessionContextIntegrationFilter</font>从Session中获取<u>Authentication对象并</u>组装ContextHolder。ContextHolder主要用于存放SecureContext，包括用户的权限信息，在request完后, 又把Authentication对象保存到Session中供下次request使用,此filter必须其他Acegi filter前使用，使之能跨越多个请求。</strong></font><strong>&nbsp;&nbsp;</strong></span></span></span></span></font><br />
<strong>authenticationProcessingFilter的配置及作用<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="authenticationManager" ref="authenticationManager"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="authenticationFailureUrl" value="/login.jsp?error=true"/&gt; 登录失败的url<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="defaultTargetUrl" value="/"/&gt;&nbsp;&nbsp;&nbsp;&nbsp; 登录成功后的url<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="filterProcessesUrl" value="/j_security_check"/&gt;&nbsp;&nbsp;&nbsp;&nbsp; 需要这个filter处理的url<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="rememberMeServices" ref="rememberMeServices"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />
该Filter负责处理登陆身份验证。当接受到与filterProcessesUrl所定义相同的请求时，它会首先通过 AuthenticationManager来验证用户身份。如果验证成功，则重定向到defaultTargetUrl所定义的成功登陆页面。如果验证失败，则再从rememberMeServices中获取用户身份，若再获取失败，则重定向到authenticationFailureUrl所定义登陆失败页面。<br />
<br />
</strong><strong><font size="3">securityContextHolderAwareRequestFilter的配置及作用<br />
</font>&lt;bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/&gt;<br />
该Filter负责通过Decorate Model(装饰模式)，装饰的HttpServletRequest对象。其Wapper是ServletRequest包装类 HttpServletRequestWrapper的子类(SavedRequestAwareWrapper或 SecurityContextHolderAwareRequestWrapper)，附上获取用户权限信息，request参数，headers, Date headers 和 cookies 的方法。<br />
在appfuse中使用的struts-menu.xml对用户菜单权限的控制参数role进行配置时必须结合该Filter，因为该filter有isUserInRole方法，而struts menu也是通过request.isUserInRole方法来控制菜单是否显示的<br />
RememberMeProcessingFilter的配置及作用<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="authenticationManager" ref="authenticationManager" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="rememberMeServices" ref="rememberMeServices" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />
该Filter负责在用户登录后在本地机上记录用户cookies信息，免除下次再次登陆。检查AuthenticationManager 中是否已存在Authentication对象，如果不存在则会调用RememberMeServices的aotoLogin方法来从cookies中获取Authentication对象<br />
<br />
AnonymousProcessingFilter的配置及作用<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="key" value="anonymous"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="userAttribute" value="anonymous,ROLE_ANONYMOUS"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />
该Filter负责为当不存在任何授权信息时，自动为Authentication对象添加userAttribute中定义的匿名用户权限<br />
<br />
ExceptionTranslationFilter的配置及作用<br />
&lt;bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="authenticationEntryPoint"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="loginFormUrl" value="/login.jsp" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="forceHttps" value="false" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="accessDeniedHandler"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="errorPage" value="/accessDenied.jsp" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br />
&lt;/bean&gt;<br />
该过滤器负责处理各种异常，然后重定向到相应的页面中。<br />
</strong><strong><font size="3">filterInvocationInterceptor的配置及作用<br />
</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="authenticationManager" ref="authenticationManager"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="accessDecisionManager" ref="accessDecisionManager"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="objectDefinitionSource"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PATTERN_TYPE_APACHE_ANT<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /signup.html*=ROLE_ANONYMOUS,admin,user<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /passwordHint.html*=ROLE_ANONYMOUS,admin,user<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**/*.html*=admin,user<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /clickstreams.jsp*=admin<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />
或<br />
&lt;bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor"&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;property name="authenticationManager" ref="authenticationManager"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 认证服务&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;property name="accessDecisionManager"&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean class="org.acegisecurity.vote.AffirmativeBased"&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="allowIfAllAbstainDecisions" value="false"/&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="decisionVoters"&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;list&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean class="org.acegisecurity.vote.RoleVoter"&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="rolePrefix" value=""/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //这里定义数据库中存放的角色和我们在这里声明的角色间是否需要加个前缀？这里没加&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/list&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;/property&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;property name="objectDefinitionSource"&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PATTERN_TYPE_APACHE_ANT&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /admin.htm*=a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这里就是数据库中对应的tyep a&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /student*=s&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 由于没有前缀和数据库里一样&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /teacher*=t&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/value&gt;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;&nbsp;&nbsp;<br />
&lt;/bean&gt; <br />
按照多数的ACEGI的配置文档，权限表的权限标识多以AUTH_或ROLE_开头，那么如果你的表中是这么存储的就可以在rolePrefix处配置一个开头标识（其实这仅仅是个标识，没有任何实际意义，appfuse就没有这么配置）<br />
<br />
该过滤器会首先调用AuthenticationManager判断用户是否已登陆认证，如还没认证成功，则重定向到登陆界面。认证成功，则并从 Authentication中获取用户的权限。然后从objectDefinitionSource属性获取各种URL资源所对应的权限。最后调用 AccessDecisionManager来判断用户所拥有的权限与当前受保华的URL资源所对应的权限是否相匹配。如果匹配失败，则返回403错误 (禁止访问)给用户。匹配成功则用户可以访问受保护的URL资源。<br />
</strong></span></span></font></span></span></span></font><br />
</p>
</div>
<img src ="http://www.blogjava.net/gdufo/aggbug/220059.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gdufo/" target="_blank">gdufo</a> 2008-08-04 23:56 <a href="http://www.blogjava.net/gdufo/archive/2008/08/04/220059.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sitemesh应用Decorator模式</title><link>http://www.blogjava.net/gdufo/archive/2008/08/04/219996.html</link><dc:creator>gdufo</dc:creator><author>gdufo</author><pubDate>Mon, 04 Aug 2008 09:21:00 GMT</pubDate><guid>http://www.blogjava.net/gdufo/archive/2008/08/04/219996.html</guid><description><![CDATA[<table style="border-collapse: collapse" bordercolor="#000000" height="1" cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td width="100%" height="63"><font size="2">sitemesh应用Decorator模式，用filter截取request和response,把页面组件head,content,banner结合为一个完整的视图。通常我们都是用include标签在每个jsp页面中来不断的包含各种header, stylesheet, scripts and footer，现在，在sitemesh的帮助下，我们可以开心的删掉他们了。如下图，你想轻松的达到复合视图模式，那末看完本文吧。</font>
            <p><img height="495" src="http://www.java3z.com/cwbwebhome/article/article2/img5/index_example-diagram.gif" width="704"  alt="" /></p>
            </td>
        </tr>
        <tr>
            <td width="100%" height="15"><span class="STYLE1"><font size="2">一、在WEB-INF/web.xml中copy以下filter的定义:</font></span><br />
            <p>&lt;?xml version="1.0" encoding="GBK"?&gt;<br />
            &lt;web-app xmlns="http://java.sun.com/xml/ns/j2ee"<br />
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />
            xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"<br />
            version="2.4"&gt;</p>
            <p>&lt;filter&gt;<br />
            &nbsp;&nbsp;&lt;filter-name&gt;sitemesh&lt;/filter-name&gt;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;filter-class&gt;com.opensymphony.module.sitemesh.filter.PageFilter&lt;/filter-class&gt;<br />
            &nbsp;&nbsp;&lt;/filter&gt;</p>
            <p>&nbsp;&nbsp;&lt;filter-mapping&gt;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;filter-name&gt;sitemesh&lt;/filter-name&gt;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br />
            &nbsp;&nbsp;&lt;/filter-mapping&gt;</p>
            <p>&lt;/web-app&gt;</p>
            <font size="2"><span class="STYLE1">二、copy所需sitemesh-2.3.jar到WEB-INF\lib下。</span>（这里可以下载<a href="http://www.opensymphony.com/sitemesh/" target="_blank">http://www.opensymphony.com/sitemesh</a>/）<br />
            <br />
            <span class="STYLE1">三、 </span></font><span class="STYLE1"><font size="2">建立WEB-INF/decorators.xml描述各装饰器页面。</font></span> <br />
            <br />
            <table style="border-collapse: collapse" bordercolor="#000000" height="1" cellspacing="0" cellpadding="0" width="80%" bgcolor="#efefef" border="1">
                <tbody>
                    <tr>
                        <td width="100%">
                        <pre><font size="2">&lt;decorators defaultdir="/decorators"&gt;
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;decorator name="main" page="main.jsp"&gt;
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;pattern&gt;*&lt;/pattern&gt;
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/decorator&gt;
                        &lt;/decorators&gt;</font></pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <p><font size="2">&nbsp;&nbsp;上面配置文件指定了装饰器页面所在的路径，并指定了一个名为main的装饰器，该装饰器默认装饰web应用根路径下的所有页面。<br />
            <br />
            <span class="STYLE1">四、 </span></font><span class="STYLE1"><font size="2">建立装饰器页面 /decorators/main.jsp</font></span><strong><font size="2"></font></strong></p>
            <li>
            <table style="border-collapse: collapse" bordercolor="#000000" height="1" cellspacing="0" cellpadding="0" width="80%" bgcolor="#efefef" border="1">
                <tbody>
                    <tr>
                        <td width="100%">&lt;%@ page contentType="text/html; charset=GBK"%&gt;<br />
                        &lt;%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator"%&gt; &lt;html&gt;<br />
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;head&gt;<br />
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;title&gt;&lt;decorator:title default="装饰器页面..." /&gt;&lt;/title&gt;<br />
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;decorator:head /&gt;<br />
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/head&gt;<br />
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;body&gt;<br />
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sitemesh的例子&lt;hr&gt;<br />
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;decorator:body /&gt;<br />
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;hr&gt;chen56@msn.com<br />
                        &nbsp;&nbsp;&nbsp;&nbsp;&lt;/body&gt;<br />
                        &lt;/html&gt;<br />
                        <pre>&nbsp;</pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <p class="STYLE1">五、<font size="2">建立一个的被装饰页面 /index.jsp(内容页面)</font> </p>
            <li>
            <table style="border-collapse: collapse" bordercolor="#000000" height="1" cellspacing="0" cellpadding="0" width="80%" bgcolor="#efefef" border="1">
                <tbody>
                    <tr>
                        <td width="100%">
                        <pre><font size="2">&lt;%@ page contentType="text/html; charset=GBK"%&gt;
                        &lt;html&gt;
                        &nbsp;&nbsp;&nbsp;&nbsp; &lt;head&gt;
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;title&gt;Agent Test&lt;/title&gt;
                        &nbsp;&nbsp;&nbsp;&nbsp; &lt;/head&gt;
                        &nbsp;&nbsp;&nbsp;&nbsp; &lt;body&gt;
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;p&gt;本页只有一句，就是本句.&lt;/p&gt;
                        &nbsp;&nbsp;&nbsp;&nbsp; &lt;/body&gt;
                        &lt;/html&gt;</font></pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <ol></ol>
                <p><font size="2">最后访问index.jsp，将生成如下页面：</font> </p>
                <p><font size="2"><img height="363" src="http://www.java3z.com/cwbwebhome/article/article2/img5/index_sitemesh.jpg" width="411" border="0"  alt="" /></font> </p>
                <p><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;而且，所有的页面也会如同index.jsp一样，被sitemesh的filter使用装饰模式修改成如上图般模样，却不用再使用include标签。</font><br />
                <br />
                <br />
                <br />
                </p>
                </li>
                </td>
            </tr>
        </tbody>
    </table>
    <table style="border-collapse: collapse" bordercolor="#000000" height="1" cellspacing="0" cellpadding="0" width="100%" border="0">
        <tbody>
            <tr>
                <td width="100%" bgcolor="#000080" height="19"><strong><font color="#ffffff" size="2">装饰器&nbsp;&nbsp;&nbsp;&nbsp; decorator概念</font></strong> </td>
            </tr>
            <tr>
                <td width="100%" height="63"><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;为了建立可复用的web应用程序,一个通用的方法是建立一个分层系统，如同下面一个普通的web应用：</font>
                <ul>
                    <li><font size="2">前端:JSP和Servlets，或jakarta的velocity</font> 。。。
                    <li><font size="2">控制层框架 Controller ： (Struts/Webwork)</font>
                    <li><font size="2">业务逻辑 Business ：主要业务逻辑</font>
                    <li><font size="2">持久化框架 ：hibernate/jdo</font> </li>
                </ul>
                <p><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;可糟糕的是前端的页面逻辑很难被复用，当你在每一个页面中用数之不尽的include来复用公共的header, stylesheet, scripts，footer时，一个问题出现了-重复的代码，每个页面必须用copy来复用页面结构，而当你需要创意性的改变页面结构时，灾难就爱上了你。</font></p>
                <p><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sitemesh通过filter截取request和response，并给原始的页面加入一定的装饰(可能为header,footer...)，然后把结果返回给客户端，并且被装饰的原始页面并不知道sitemesh的装饰，这也就达到了脱耦的目的。</font></p>
                <p><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;据说即将新出台的Portlet规范会帮助我们标准的实现比这些更多更cool的想法，但可怜的我还不懂它到底是一个什末东东，有兴趣的人可以研究<br />
                <a href="http://jakarta.apache.org/jetspeed">jetspeed</a>，或<a href="http://www.jcp.org/en/jsr/detail?id=168">JSR (Java Specification Request) 168</a>,但我想sitemesh如此简单，我们不妨先用着。</font></p>
                <p>　</p>
                </td>
            </tr>
            <tr>
                <td width="100%" bgcolor="#000080" height="19"><strong><font color="#ffffff" size="2">让我们看看怎样配置环境</font> </strong></td>
            </tr>
            <tr>
                <td width="100%" height="15"><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;除了要copy到WEB-INF/lib中的sitemesh.jar</font><font size="2">外，还有2个文件要建立到WEB-INF/：</font>
                <ul>
                    <li><font size="2">sitemesh.xml (可选)&nbsp;&nbsp;</font>
                    <li><font size="2">decorators.xml </font></li>
                </ul>
                <h2><font size="2">sitemesh.xml 可以设置2种信息:</font></h2>
                <p><font size="2"><strong>Page Parsers</strong> ：负责读取stream的数据到一个Page对象中以被SiteMesh解析和操作。(不太常用，默认即可)</font></p>
                <p><font size="2"><strong>Decorator Mappers</strong> : 不同的装饰器种类，我发现2种比较有用都列在下面。一种通用的mapper,可以指定装饰器的配置文件名，另一种可打印的装饰器，可以允许你当用http://localhost/aaa/a.html?printable=true方式访问时给出原始页面以供打印(免得把header,footer等的花哨的图片也搭上)<br />
                <br />
                <em>(但一般不用建立它，默认设置足够了：com/opensymphony/module/sitemesh/factory/sitemesh-default.xml）：</em></font> </p>
                <p><font size="2"><strong>范例：</strong></font> </p>
                <table style="border-collapse: collapse" height="1" cellspacing="0" cellpadding="0" width="100%" bgcolor="#e3e3e3" border="1">
                    <tbody>
                        <tr>
                            <td width="100%"><code><font face="新宋体" size="2">&lt;sitemesh&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp; &lt;page-parsers&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parser default="true" class="com.opensymphony.module.sitemesh.parser.DefaultPageParser" /&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parser content-type="text/html" class="com.opensymphony.module.sitemesh.parser.FastPageParser" /&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;parser content-type="text/html;charset=ISO-8859-1" class="com.opensymphony.module.sitemesh.parser.FastPageParser" /&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp; &lt;/page-parsers&gt;<br />
                            <br />
                            &nbsp;&nbsp;&nbsp;&nbsp; &lt;decorator-mappers&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper"&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="config" value="/WEB-INF/decorators.xml" /&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/mapper&gt;<br />
                            </font></code><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;mapper class="com.opensymphony.module.sitemesh.mapper.PrintableDecoratorMapper"&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="decorator" value="printable" /&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="parameter.name" value="printable" /&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="parameter.value" value="true" /&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/mapper&gt;<code><br />
                            <font face="新宋体">&nbsp;&nbsp;</font></code></font><code><font face="新宋体" size="2">&lt;/decorator-mappers&gt;<br />
                            &lt;/sitemesh&gt; </font></code></td>
                        </tr>
                    </tbody>
                </table>
                <p><font size="2"><strong>decorators.xml</strong> ：定义构成复合视图的所有页面构件的描述(主要结构页面，header,footer...)，如下例：</font></p>
                <table style="border-collapse: collapse" height="1" cellspacing="0" cellpadding="0" width="100%" bgcolor="#e3e3e3" border="1">
                    <tbody>
                        <tr>
                            <td width="100%"><font size="2">&lt;decorators defaultdir="/decorators"&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp; &lt;decorator name="main" page="main.jsp"&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;pattern&gt;*&lt;/pattern&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp; &lt;/decorator&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp; &lt;decorator name="printable" page="printable.jsp" role="customer" webapp="aaa" /&gt;<br />
                            &lt;/decorators&gt;</font></td>
                        </tr>
                    </tbody>
                </table>
                <ul>
                    <li><font size="2">defaultdir: 包含装饰器页面的目录</font>
                    <li><font size="2">page : 页面文件名</font>
                    <li><font size="2">name : 别名</font>
                    <li><font size="2">role : 角色，用于安全</font>
                    <li><font size="2">webapp : 可以另外指定此文件存放目录</font>
                    <li><font size="2">Patterns : 匹配的路径，可以用*,那些被访问的页面需要被装饰。</font> </li>
                </ul>
                <p><font size="2">　</font> </p>
                </td>
            </tr>
            <tr>
                <td width="100%" bgcolor="#000080" height="13"><strong><font color="#ffffff" size="2">最重要的是写出装饰器本身(也就是那些要复用页面，和结构页面)。</font></strong> </td>
            </tr>
            <tr>
                <td width="100%" height="15"><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;其实，重要的工作就是制作装饰器页面本身(也就是包含结构和规则的页面)，然后把他们描述到decorators.xml中。</font>
                <p><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;让我们来先看一看最简单的用法：其实最常用也最简单的用法就是我们的hello例子，面对如此众多的技术，我想只要达到功能点到为止即可，没必要去研究太深(除非您有更深的需求)。</font></p>
                <table style="border-collapse: collapse" bordercolor="#000000" height="1" cellspacing="0" cellpadding="0" width="80%" bgcolor="#efefef" border="1">
                    <tbody>
                        <tr>
                            <td width="100%">
                            <pre><font size="2">&lt;%@ page contentType="text/html; charset=GBK"%&gt;
                            &lt;%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %&gt;
                            &lt;html&gt;
                            &nbsp;&nbsp;&nbsp;&nbsp; &lt;head&gt;
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;title&gt;&lt;decorator:title default="装饰器页面..." /&gt;&lt;/title&gt;
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;decorator:head /&gt;
                            &nbsp;&nbsp;&nbsp;&nbsp; &lt;/head&gt;
                            &nbsp;&nbsp;&nbsp;&nbsp; &lt;body&gt;
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sitemesh的例子&lt;hr&gt;
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;decorator:body /&gt;
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;hr&gt;chen56@msn.com
                            &nbsp;&nbsp;&nbsp;&nbsp; &lt;/body&gt;
                            &lt;/html&gt;
                            </font></pre>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <p><font size="2">我们在装饰器页面只用了2个标签：</font></p>
                <p><font size="2">&lt;decorator:title default="装饰器页面..." /&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ： 把请求的原始页面的title内容插入到&lt;title&gt;&lt;/title&gt;中间。</font></p>
                <p><font size="2">&lt;decorator:body /&gt; ： 把请求的原始页面的body内的全部内容插入到相应位置。</font></p>
                <p><font size="2">然后我们在decorator.xml中加入以下描述即可： </font></p>
                <p><font size="2">&lt;decorator name="main" page="main.jsp"&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;pattern&gt;*&lt;/pattern&gt;<br />
                &lt;/decorator&gt;<br />
                </font></p>
                <p><font size="2">这样，请求的所有页面都会被重新处理，并按照main.jsp的格式重新展现在你面前。</font></p>
                <p>　 </p>
                </td>
            </tr>
            <tr>
                <td width="100%" bgcolor="#000080" height="19"><strong><font color="#ffffff" size="2">让我们看看更多的用法。(抄袭sitemesh文档)</font></strong> </td>
            </tr>
            <tr>
                <td width="100%" height="15"><font size="2">以下列着全部标签：</font>
                <table width="80%" align="center">
                    <tbody>
                        <tr>
                            <td valign="top"><strong><font size="2">Decorator Tags</font></strong></td>
                            <td valign="top"><strong><font size="2">Page Tags</font></strong></td>
                        </tr>
                        <tr>
                            <td valign="top"><font size="2">被用于建立装饰器页面.</font></td>
                            <td valign="top"><font size="2">被用于从原始内容页面访问装饰器.</font></td>
                        </tr>
                        <tr>
                            <td valign="top"><font size="3"><a href="http://docs.huihoo.com/java/sitemesh/2.html#decorator:head"><code><font face="新宋体" color="#800080">&lt;decorator:head /&gt;</font></code></a><br />
                            <a href="http://docs.huihoo.com/java/sitemesh/2.html#decorator:body"><code><font face="新宋体" color="#800080">&lt;decorator:body /&gt;</font></code></a><br />
                            <a href="http://docs.huihoo.com/java/sitemesh/2.html#decorator:title"><code><font face="新宋体" color="#800080">&lt;decorator:title /&gt;</font></code></a><br />
                            <a href="http://docs.huihoo.com/java/sitemesh/2.html#decorator:getProperty"><code><font face="新宋体" color="#800080">&lt;decorator:getProperty /&gt;</font></code></a><br />
                            <a href="http://docs.huihoo.com/java/sitemesh/2.html#decorator:usePage"><code><font face="新宋体" color="#800080">&lt;decorator:usePage /&gt;</font></code></a><br />
                            </font></td>
                            <td valign="top"><font size="3"><a href="http://docs.huihoo.com/java/sitemesh/2.html#page:applyDecorator"><code><font face="新宋体" color="#800080">&lt;page:applyDecorator /&gt;</font></code></a><br />
                            <a href="http://docs.huihoo.com/java/sitemesh/2.html#page:param"><code><font face="新宋体" color="#800080">&lt;page:param</font></code></a></font></td>
                        </tr>
                    </tbody>
                </table>
                　
                <p><strong><a name="decorator:head"><font color="#000000" size="2">&lt;decorator:head /&gt;</font></a></strong></p>
                <p><font size="2">插入原始页面(被包装页面)的head标签中的内容(不包括head标签本身)。</font></p>
                <strong><a name="decorator:body"><font color="#000000" size="2">&lt;decorator:body /&gt;</font></a></strong>
                <p><font size="2">插入原始页面(被包装页面)的body标签中的内容。</font></p>
                <p><strong><a name="decorator:title"><font color="#000000" size="2">&lt;decorator:title [ default="..." ] /&gt;</font></a></strong></p>
                <p><font size="2">插入原始页面(被包装页面)的title标签中的内容，还可以添加一个缺省值。</font></p>
                <p><font size="2">例：</font></p>
                <p><font size="2">/decorator/main.jsp中 （装饰器页面）: &lt;title&gt;</font><a name="decorator:title"><font color="#000000" size="2">&lt;decorator:title default="却省title-hello"&nbsp;&nbsp;&nbsp;&nbsp; /&gt;</font></a><font size="2"><a name="decorator:title"><font color="#000000"> - 附加标题</font></a>&lt;/title&gt;</font></p>
                <p><font size="2">/aaa.jsp中 (原始页面)：&lt;title&gt;<a name="decorator:title"><font color="#000000">aaa页面</font></a>&lt;/title&gt;</font></p>
                <p><font size="2">访问/aaa.jsp的结果：&lt;title&gt;<a name="decorator:title"><font color="#000000">aaa页面</font></a> <a name="decorator:title"><font color="#000000">- 附加标题</font></a>&lt;/title&gt;</font></p>
                <p><strong><a name="decorator:getProperty"><font color="#000000" size="2">&lt;decorator:getProperty property="..." [ default="..." ] [ writeEntireProperty="..." ]/&gt;</font></a></strong></p>
                <p><font size="2">在标签处插入原始页面(被包装页面)的原有的<a name="decorator:title"><font color="#000000">标签的属性</font></a>中的内容，还可以添加一个缺省值。</font></p>
                <p><font size="2">sitemesh文档中的例子很好理解：</font><br />
                <font size="2">The decorator: </font><font size="3"><font face="新宋体"><code>&lt;body bgcolor="white"&lt;decorator:getProperty property="body.onload" writeEntireProperty="true" /&gt;&gt;</code><br />
                </font></font><font size="2">The undecorated page: </font><font size="3"><font face="新宋体"><code>&lt;body onload="document.someform.somefield.focus();"&gt;</code><br />
                </font></font><font size="2">The decorated page: </font><font face="新宋体" size="3"><code>&lt;body bgcolor="white" onload="document.someform.somefield.focus();"&gt;</code></font></p>
                <p><font size="2"><strong>注意，</strong></font><code><font face="新宋体" size="2">writeEntireProperty="true"会在插入内容前加入一个空格。</font></code></p>
                <p><font size="2"><strong><a name="decorator:usePage"><font color="#000000">&lt;decorator:usePage id="..." /&gt;</font></a></strong><br />
                象jsp页面中的&lt;jsp:useBean&gt;标签一样，可以使用被包装为一个Page对象的页面。 (懒的用)</font></p>
                <p><font size="2">例：可用<a name="decorator:usePage"><font color="#000000">&lt;decorator:usePage id="page" /&gt;<strong> ：</strong></font></a></font><a name="decorator:usePage"><font color="#000000" size="3">&lt;%=</font></a><font size="3"><code><font face="新宋体"><nobr>page.getTitle()%&gt;达到</nobr>&lt;decorator:title/&gt;的访问结果。</font></code></font></p>
                <p><font size="2"><a name="page:applyDecorator"><strong><font color="#000000">&lt;page:applyDecorator name="..." [ page="..." title="..." ] &gt;<br />
                </font></strong></a><strong><a name="page:param"><font color="#000000">&lt;page:param name="..."&gt; ... &lt;/page:param&gt;</font></a></strong><br />
                <strong><a name="page:param"><font color="#000000">&lt;page:param name="..."&gt; ... &lt;/page:param&gt;</font></a><br />
                &lt;/page:applyDecorator&gt;</strong></font></p>
                <p><font size="2">应用包装器到指定的页面上，一般用于被包装页面中主动应用包装器。这个标签有点不好理解，我们来看一个例子：</font></p>
                <p><font size="2">包装器页面 /decorators/panel.jsp：&lt;p&gt;&lt;decorator:title /&gt;&lt;/p&gt;&nbsp;&nbsp;&nbsp;&nbsp; ... &lt;p&gt;&lt;decorator:body /&gt;&lt;/p&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp; 并且在decorators.xml中有&lt;decorator name="panel" page="panel.jsp"/&gt;<br />
                <br />
                一个公共页面，即将被panel包装：/public/date.jsp:&nbsp;&nbsp;<br />
                &nbsp;&nbsp;&nbsp;&nbsp; ... &lt;%=new java.util.Date()%&gt;&nbsp;&nbsp;&nbsp;&nbsp; ...&lt;decorator:getProperty property="myEmail" /&gt;<br />
                <br />
                被包装页面 /page.jsp ： <br />
                &nbsp;&nbsp;&nbsp;&nbsp; &lt;title&gt;page的应用&lt;/title&gt; <br />
                &nbsp;&nbsp;&nbsp;&nbsp; .....&nbsp;&nbsp;</font><a name="page:applyDecorator"><font size="2"><br />
                <font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp; &lt;page:applyDecorator name="panel" page="/_public/date.jsp" &gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;page:param name="myEmail"&gt; chen_p@neusoft.com &lt;/page:param&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp; &lt;/page:applyDecorator&gt;</font><strong><br />
                </strong></font></a></p>
                <p><font size="2">最后会是什末结果呢？除了/page.jsp会被默认的包装页面包装上header,footer外，page.jsp页面中还内嵌了date.jsp页面，并且此date.jsp页面还会被panel.jsp包装为一个title加body的有2段的页面，第1段是date.jsp的title，第2段是date.jsp的body内容。</font></p>
                <p><font size="2">另外，<a name="page:applyDecorator"><font color="#000000">page:applyDecorator</font></a>中包含的page:param标签所声明的属性值还可以在包装页面中用</font><a name="decorator:getProperty"><font color="#000000" size="2">decorator:getProperty</font></a><font size="2">标签访问到。 </font></p>
                </td>
            </tr>
        </tbody>
    </table>
    <hr color="#ff0000" size="1" />
    <table style="border-collapse: collapse" bordercolor="#000000" height="1" cellspacing="0" cellpadding="0" width="100%" border="0">
        <tbody>
            <tr>
                <td width="100%" bgcolor="#000080" height="19"><font color="#ffffff" size="2">可打印的界面装饰</font> </td>
            </tr>
            <tr>
                <td width="100%" height="63"><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;前面说过有1种可打印的装饰器，可以允许你当用http://localhost/aaa/a.html?printable=true方式访问时，应用其他的装饰器(自己指定)，给出原始页面以供打印(免得把header,footer等的花哨的图片也搭上)。</font>
                <p><font size="2">让我们来看一看怎样实现他：</font></p>
                <p><font size="2">1.首先在WEB-INFO/sitemesh.xml中设置：<br />
                &nbsp;&nbsp;&nbsp;&nbsp; &lt;mapper class="com.opensymphony.module.sitemesh.mapper.PrintableDecoratorMapper"&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="decorator" value="printable" /&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="parameter.name" value="printable" /&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="parameter.value" value="true" /&gt;<br />
                &nbsp;&nbsp;&nbsp;&nbsp; &lt;/mapper&gt;<br />
                这样就可以通过?printable=true来使用名为printable的装饰器，而不是用原来的装饰器。</font></p>
                <p><font size="2">2.在WEB-INFO/decorators.xml中定义相应的printable装饰器<br />
                &nbsp;&nbsp;&nbsp;&nbsp; &lt;decorator name="printable" page="printable.jsp"/&gt;</font></p>
                <p><font size="2">3.最后编写printable装饰器/decorators/printable.jsp </font></p>
                <table style="border-collapse: collapse" bordercolor="#000000" height="1" cellspacing="0" cellpadding="0" width="80%" bgcolor="#efefef" border="1">
                    <tbody>
                        <tr>
                            <td width="100%" bgcolor="#efefef"><font size="2">&lt;%@ taglib uri="sitemesh-decorator" prefix="decorator" %&gt;<br />
                            &lt;html&gt;<br />
                            &lt;head&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp; &lt;title&gt;&lt;decorator:title /&gt;&lt;/title&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp; &lt;decorator:head /&gt;<br />
                            &lt;/head&gt;<br />
                            &lt;body&gt;<br />
                            <br />
                            &nbsp;&nbsp;&nbsp;&nbsp; &lt;h1&gt;&lt;decorator:title /&gt;&lt;/h1&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp; &lt;p align="right"&gt;&lt;i&gt;(printable version)&lt;/i&gt;&lt;/p&gt;<br />
                            <br />
                            &nbsp;&nbsp;&nbsp;&nbsp; &lt;decorator:body /&gt;<br />
                            <br />
                            &lt;/body&gt;<br />
                            &lt;/html&gt;</font></td>
                        </tr>
                    </tbody>
                </table>
                <p><font size="2">这样就可以让一个原始页面通过?printable=true开关来切换不同的装饰器页面。</font></p>
                <p>　 </p>
                </td>
            </tr>
        </tbody>
    </table>
    <table style="border-collapse: collapse" bordercolor="#000000" height="1" cellspacing="0" cellpadding="0" width="100%" border="0">
        <tbody>
            <tr>
                <td width="100%" bgcolor="#000080" height="19"><font color="#ffffff" size="2">中文问题</font></td>
            </tr>
            <tr>
                <td width="100%" height="63"><font size="2">由于sitemesh内部所使用的缺省字符集为iso-8859-1，直接使用会产生乱码，我们可以通过以下方法纠正之：</font>
                <ul>
                    <li><font size="2">方法1：可以在您所用的application server的配置文件中找一找，有没有设置encoding或<code></code></font><code><font face="新宋体" size="2">charset的项目，然后设成gbk或gb2312即可</font></code>
                    <li><code><font face="新宋体" size="2">方法2：这也是我们一直使用的方法。<br />
                    1.在每一个jsp页里设置: &lt;%@ page contentType="text/html; charset=gbk"%&gt; 来告诉server你所要求的字符集。<br />
                    2.在每个jsp页的head中定义：&lt;META HTTP-EQUIV="content-type" CONTENT="text/html; charset=gbk"&gt; 来告诉浏览器你所用的字符集。</font></code> </li>
                </ul>
                </td>
            </tr>
        </tbody>
    </table>
    <table style="border-collapse: collapse" bordercolor="#000000" height="1" cellspacing="0" cellpadding="0" width="100%" border="0">
        <tbody>
            <tr>
                <td width="100%" bgcolor="#000080" height="19"><font color="#ffffff" size="2">总结：使用sitemesh最通常的途径：</font></td>
            </tr>
            <tr>
                <td width="100%" height="15">
                <p><font size="2">1.配置好环境，</font> </p>
                <p><font size="2">2.在WEB-INFO/decroators.xml中描述你将建立的包装器。</font> </p>
                <p><font size="2">3.开发在decroators.xml中描述的包装器，最好存放在/_decorators目录下</font></p>
                <p><font size="2">4.ok ，可以看看辛勤的成果了 :)</font></p>
                </td>
            </tr>
        </tbody>
    </table>
<img src ="http://www.blogjava.net/gdufo/aggbug/219996.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gdufo/" target="_blank">gdufo</a> 2008-08-04 17:21 <a href="http://www.blogjava.net/gdufo/archive/2008/08/04/219996.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Appfuse 中的 Struts2中参数设置</title><link>http://www.blogjava.net/gdufo/archive/2008/08/04/219947.html</link><dc:creator>gdufo</dc:creator><author>gdufo</author><pubDate>Mon, 04 Aug 2008 07:26:00 GMT</pubDate><guid>http://www.blogjava.net/gdufo/archive/2008/08/04/219947.html</guid><description><![CDATA[<p><span style="font-size: 10pt">Appfuse 中的 Struts2中参数设置</span></p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">constant&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="struts.devMode"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="false"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">constant&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="struts.i18n.encoding"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="UTF-8"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">constant&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="struts.action.extension"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="html"</span><span style="color: #0000ff">/&gt;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">这里将默认的.action&nbsp;改成&nbsp;.html结尾</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">constant&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="struts.objectFactory"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="spring"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">constant&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="struts.custom.i18n.resources"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="ApplicationResources,errors"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">constant&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="struts.multipart.maxSize"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="2097152"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">constant&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="struts.ui.theme"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="css_xhtml"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">constant&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="struts.codebehind.pathPrefix"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="/WEB-INF/pages/"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">constant&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="struts.enable.SlashesInActionNames"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="true"</span><span style="color: #0000ff">/&gt;</span></div>
...........
<img src ="http://www.blogjava.net/gdufo/aggbug/219947.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gdufo/" target="_blank">gdufo</a> 2008-08-04 15:26 <a href="http://www.blogjava.net/gdufo/archive/2008/08/04/219947.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts Menu 祥解</title><link>http://www.blogjava.net/gdufo/archive/2008/06/26/210947.html</link><dc:creator>gdufo</dc:creator><author>gdufo</author><pubDate>Thu, 26 Jun 2008 13:16:00 GMT</pubDate><guid>http://www.blogjava.net/gdufo/archive/2008/06/26/210947.html</guid><description><![CDATA[http://blog.csdn.net/phevose/archive/2007/06/02/1635563.aspx<br />
<br />
官方英文版向导（<a href="http://struts-menu.sourceforge.net/userguide.html"></a><a href="http://struts-menu.sourceforge.net/userguide.html" target="_blank"><font color="#666666">http://struts-menu.sourceforge.net/userguide.html</font></a>）
<p>一、从1.X升级到2.X需要做以下事情：<br />
1、改变你的taglib声明中的URI。<br />
<font style="background-color: #ffe000">&nbsp;&lt;% at taglib uri="</font><a href="http://struts-menu%20dot%20sf.net/tag"><font style="background-color: #ffe000"></font><font style="background-color: #ffe000">" prefix="menu" %&gt;<br />
</font>2、改变&lt;plug-in&gt;,使用新的包名"net.sf.navigator." 。<br />
&nbsp;<font style="background-color: #ffe000">&lt;plug-in className="net.sf.navigator.menu.MenuPlugIn"&gt;</font><br />
3、改变你的menu-config.xml文件，使用新的包名"net.sf.navigator." 。<br />
<font style="background-color: #ffe000">&nbsp;&lt;Displayer name="Simple"<br />
&nbsp;&nbsp; type="net.sf.navigator.displayer.SimpleMenuDisplayer"/&gt;</font></a><a href="http://struts-menu.sf.net/tag" target="_blank"><font color="#666666">http://struts-menu.sf.net/tag</font></a></p>
<p>二、快速开始：<br />
1、下载最新的struts-menu版本；<br />
2、解包到本地目录；<br />
3、下载Tomcat或者其它Servlet容器；<br />
4、把struts-menu.war包放入Tomcat安装目录的wabapps目录下，并重启Tomcat服务。<br />
5、打开htpp://localhost:8080/struts-menu/</p>
<p>三、把Struts Menu整合到你的应用程序中：<br />
Struts Menu能够被轻易的整合到你的Struts应用程序中，它也可以整合到一个非Struts的应用程序中，但是我不喜欢这样做，所以在此没有提供相应的教程。这里将一步步的带你整合这个标签库。<br />
你需要把struts-menu.jar放到你的WEB-INF/lib目录下。然后使用URI标签声明你的JSP文件中想使用的这个标签库。<br />
如果使用Struts Menu 2.1，你还需要 Jakarta's Standard Tag Library JAR包放入你的WEB-INF/lib目录下。下载地址：<a href="http://ibiblio.org/maven/taglibs/jars/standard-1.0.4.jar"></a><a href="http://ibiblio.org/maven/taglibs/jars/standard-1.0.4.jar" target="_blank"><font color="#666666">http://ibiblio.org/maven/taglibs/jars/standard-1.0.4.jar</font></a>，这个文件包括例程WAR包文件和二进制发布包。<br />
1、放入struts-menu.jar包到你的应用程序的WEB-INF/lib目录中。<br />
2、在你的struts-config.xml文件中加入plug-in设置。<br />
</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">plug-in&nbsp;</span><span style="color: #ff0000">className</span><span style="color: #0000ff">="net.sf.navigator.menu.MenuPlugIn"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">set-property&nbsp;</span><span style="color: #ff0000">property</span><span style="color: #0000ff">="menuConfig"</span><span style="color: #ff0000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value</span><span style="color: #0000ff">="/WEB-INF/menu-config.xml"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">plug-in</span><span style="color: #0000ff">&gt;</span></div>
<p><br />
3、你将需要在你的应用程序的/WEB-INF/menu-config.xml文件中定义你的菜单，这里提供一个简单的片断：<br />
</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Menu&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="contactMenu"</span><span style="color: #ff0000">&nbsp;title</span><span style="color: #0000ff">="Contact"</span><span style="color: #ff0000">&nbsp;location</span><span style="color: #0000ff">="?Contact"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Item&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="email"</span><span style="color: #ff0000">&nbsp;title</span><span style="color: #0000ff">="E-Mail"</span><span style="color: #ff0000">&nbsp;location</span><span style="color: #0000ff">="?EMail"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Item&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="phone"</span><span style="color: #ff0000">&nbsp;title</span><span style="color: #0000ff">="Phone"</span><span style="color: #ff0000">&nbsp;location</span><span style="color: #0000ff">="?Phone"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Menu</span><span style="color: #0000ff">&gt;</span></div>
<p><br />
　　更多全面的例程，请查看应用程序的web/WEB-INF目录中的menu-config.xml文件，你可以截取一段作为你需要的菜单。完整的属性列表，可以查看MenuBase class's javadocs（<a href="http://struts-menu.sourceforge.net/apidocs/net/sf/navigator/menu/MenuBase.html"></a><a href="http://struts-menu.sourceforge.net/apidocs/net/sf/navigator/menu/MenuBase.html" target="_blank"><font color="#666666">http://struts-menu.source......avigator/menu/MenuBase.html</font></a>）。<br />
4、在你的JSP文件的顶部加入taglib声明：<br />
&nbsp;</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">%&nbsp;at&nbsp;</span><span style="color: #ff0000">taglib&nbsp;uri</span><span style="color: #0000ff">=""</span><span style="color: #ff0000">&nbsp;prefix</span><span style="color: #0000ff">="menu"</span><span style="color: #ff0000">&nbsp;%</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<p><br />
<a href="http://struts-menu%20dot%20sf.net/tag">5、在你的JSP文件中要放置菜单的位置加入taglib代码：<br />
</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">menu:useMenuDisplayer&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="TabbedMenu"</span><span style="color: #ff0000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;bundle</span><span style="color: #0000ff">="org.apache.struts.action.MESSAGE"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">menu:displayMenu&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Home"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">menu:displayMenu&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="About"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">menu:useMenuDisplayer</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<p><br />
属性name="TabbedMenu"被定义在menu-config.xml文件的顶部：<br />
</a></p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Displayer&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="TabbedMenu"</span><span style="color: #ff0000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />type</span><span style="color: #0000ff">="net.sf.navigator.displayer.TabbedMenuDisplayer"</span><span style="color: #0000ff">/&gt;</span></div>
<p><a href="http://struts-menu.sf.net/tag" target="_blank"><font color="#666666">http://struts-menu.sf.net/tag</font></a></p>
<p><font style="background-color: #a0ff00">(译注：其实到此步即可在你的JSP文件中添加相应的菜单了，只不过是没有结合Velocity。在menu-config.xml文件的头部可以定义多个Displayer，每个Displayer都有name和type属性，name属性与JSP文件中menu:useMenuDisplayer标签的name属性相对应，即表明使用何种样式，具体的样式定义便在type属性中定义，type属性中是一个class。在menu-config.xml文件中的菜单定义中的name属性则与JSP文件中的menu:displayMenu标签的name属性相对应。)</font></p>
<p>使用定制的Velocity模版实施你的菜单，你需要整合Velocity到你的WEB应用程序中。如果需要这样做的话，请完成下面的步骤：<br />
1、确定你的menu-config.xml文件有&#8220;Velocity&#8221;的displayer定义：<br />
</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Displayer&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Velocity"</span><span style="color: #ff0000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type</span><span style="color: #0000ff">="net.sf.navigator.displayer.VelocityMenuDisplayer"</span><span style="color: #0000ff">/&gt;</span></div>
<p><br />
2、加入Velocity的JARs包到你的WEB-INF/lib目录中，下载velocity-1.4-rc1.jar（<a href="http://www.ibiblio.org/maven/velocity/jars/velocity-1.4-rc1.jar"></a><a href="http://www.ibiblio.org/maven/velocity/jars/velocity-1.4-rc1.jar" target="_blank"><font color="#666666">http://www.ibiblio.org/ma......y/jars/velocity-1.4-rc1.jar</font></a>）和velocity-tools-view-1.0.jar（<a href="http://www.ibiblio.org/maven/velocity-tools/jars/velocity-tools-view-1.0.jar"></a><a href="http://www.ibiblio.org/maven/velocity-tools/jars/velocity-tools-view-1.0.jar" target="_blank"><font color="#666666">http://www.ibiblio.org/ma......velocity-tools-view-1.0.jar</font></a>）。 <br />
3、加入globalMacros.vm（<a href="http://cvs.sourceforge.net/viewcvs.py/*checkout*/struts-menu/navigator/web/WEB-INF/classes/globalMacros.vm?content-type=text%2Fplain&amp;rev=1.1"></a><a href="http://cvs.sourceforge.net/viewcvs.py/" target="_blank"><font color="#666666">http://cvs.sourceforge.net/viewcvs.py/</font></a>*checkout*/struts-menu/navigator/web/WEB-INF/classes/globalMacros.vm?content-type=text%2Fplain&amp;rev=1.1（右键另存为））到你的WEB-INF/lib目录中。<br />
4、改变你的JSP文件中displayer的值为&#8220;Velocity&#8221;，&#8220;config&#8221;属性指向一个文件（如config="/templates/tabs.html"）或者如果tabs.htm在你的WEB-INF/classes目录中的话，则可设config="tabs.html"。</p>
<p>这里提供了一些使用Velocity的displayer例子，可在sample application（<a href="http://demo.raibledesigns.com/struts-menu/index.jsp"></a><a href="http://demo.raibledesigns.com/struts-menu/index.jsp" target="_blank"><font color="#666666">http://demo.raibledesigns.com/struts-menu/index.jsp</font></a>）中查看。它总是在你的菜单需要的时候显示CSS，JavaScript和图像文件。下面有一些在当前的Struts Menu中用到的Velocity模版的例子的链接：<br />
&nbsp;CoolMenus: Demo（<a href="http://demo.raibledesigns.com/struts-menu/velocity-coolmenu4.jsp"></a><a href="http://demo.raibledesigns.com/struts-menu/velocity-coolmenu4.jsp" target="_blank"><font color="#666666">http://demo.raibledesigns......menu/velocity-coolmenu4.jsp</font></a>）, <br />
Template（<a href="http://struts-menu.sourceforge.net/templates/coolmenus.html"></a><a href="http://struts-menu.sourceforge.net/templates/coolmenus.html" target="_blank"><font color="#666666">http://struts-menu.sourceforge.net/templates/coolmenus.html</font></a>） <br />
&nbsp;NiceTabs: Demo, Template <br />
&nbsp;Tabs: Demo, Template <br />
&nbsp;XTree: Demo, Template </p>
<p>所有相关的有用的文件如果你需要的话都可以在下面的站点上下载：<br />
&nbsp;Images （<a href="http://struts-menu.sourceforge.net/menu-images/"></a><a href="http://struts-menu.sourceforge.net/menu-images/" target="_blank"><font color="#666666">http://struts-menu.sourceforge.net/menu-images/</font></a>）<br />
&nbsp;Stylesheets （<a href="http://struts-menu.sourceforge.net/styles/"></a><a href="http://struts-menu.sourceforge.net/styles/" target="_blank"><font color="#666666">http://struts-menu.sourceforge.net/styles/</font></a>）<br />
&nbsp;Scripts （<a href="http://struts-menu.sourceforge.net/scripts/"></a><a href="http://struts-menu.sourceforge.net/scripts/" target="_blank"><font color="#666666">http://struts-menu.sourceforge.net/scripts/</font></a>）<br />
&nbsp;Templates （<a href="http://struts-menu.sourceforge.net/templates/"></a><a href="http://struts-menu.sourceforge.net/templates/" target="_blank"><font color="#666666">http://struts-menu.sourceforge.net/templates/</font></a>）</p>
<p>更多的基于roles的显示/隐藏菜单的信息，请查看FAQs（<a href="http://struts-menu.sourceforge.net/faq.html"></a><a href="http://struts-menu.sourceforge.net/faq.html" target="_blank"><font color="#666666">http://struts-menu.sourceforge.net/faq.html</font></a>）。</p>
<p>四、在Struts之外使用Struts Menu:<br />
在2.2版中，Menu Repository能够使用MenuContextListener载入：<br />
</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;Loads&nbsp;the&nbsp;menu-config.xml&nbsp;for&nbsp;struts-menu&nbsp;at&nbsp;startup,<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;by&nbsp;default&nbsp;from&nbsp;"/WEB-INF/menu-config.xml".<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;To&nbsp;override&nbsp;this,&nbsp;add&nbsp;a&nbsp;context-param&nbsp;named&nbsp;"menuConfigLocation"<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;web.xml&nbsp;file.<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">listener</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">listener-class</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">net.sf.navigator.menu.MenuContextListener</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">listener-class</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">listener</span><span style="color: #0000ff">&gt;</span></div>
<p>&nbsp;</p>
<p>或者如果你使用Spring，甚至更容易。仅仅需要加入下面的部分到你的applicationContext.xml文件中：<br />
</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">bean&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">="menu"</span><span style="color: #ff0000">&nbsp;class</span><span style="color: #0000ff">="net.sf.navigator.menu.MenuLoader"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">property&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="menuConfig"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">value</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">/WEB-INF/menu-config.xml</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">value</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">property</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">bean</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;The&nbsp;menuConfig&nbsp;property&nbsp;is&nbsp;an&nbsp;optional&nbsp;attribute.&nbsp;&nbsp;It&nbsp;is&nbsp;set&nbsp;to<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/WEB-INF/menu-config.xml&nbsp;by&nbsp;default.&nbsp;</span><span style="color: #008000">--&gt;</span></div>
<p><br />
感谢Dan Luputan提供MenuLoader类的源代码。</p>
<p>五、从源文件编译：<br />
要从源文件编译这个项目，执行下面的步骤：<br />
1、下载并安装Maven（<a href="http://maven.apache.org/"></a><a href="http://maven.apache.org/" target="_blank"><font color="#666666">http://maven.apache.org/</font></a>）；<br />
2、创建一个环境变量MAVEN＿HOME指出你的Maven的安装目录，然后添加$MAVEN_HOME/bin到你的PATH变量中；<br />
3、操纵这个目录你可以扩展源代码，执行&#8220;maven.jar&#8221;创建target/struts-menu.jar。</p>
<p>要展开struts-menu例程，需要下面的步骤：<br />
1、下载和安装Tomcat；<br />
2、创建一个环境变量CATALINA＿HOME指出你的Tomcat的安装目录；<br />
3、执行&#8220;maven deploy&#8221;把应用程序展开到Tomcat中；<br />
4、打开<a href="http://localhost:8080/struts-menu"></a><a href="http://localhost:8080/struts-menu" target="_blank"><font color="#666666">http://localhost:8080/struts-menu</font></a>在你喜爱的浏览器中。</p>
<p>如果你喜欢使用Eclipse开发项目，请参考此份开发向导（<a href="http://struts-menu.sourceforge.net/devguide.html"></a><a href="http://struts-menu.sourceforge.net/devguide.html" target="_blank"><font color="#666666">http://struts-menu.sourceforge.net/devguide.html</font></a>）。</p>
<p>&nbsp;</p>
<p>struts-menu2.3做动态菜单</p>
<p>1 web.xml<br />
struts-menu2.3版本不用建立在struts框架之上，但需要struts的jar包<br />
要做的是在web.xml文件中配置一个监听</p>
<p>&nbsp;</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">context-param</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">param-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">menuConfigLocation</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">param-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">param-value</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">/WEB-INF/menu-config.xml</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">param-value</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">context-param</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">listener</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">listener-class</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">net.sf.navigator.menu.MenuContextListener</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">listener-class</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">listener</span><span style="color: #0000ff">&gt;</span></div>
<p><br />
其中context-param是可选的，/WEB-INF/menu-config.xml是struts-menu的默认配置文件的路径，如果要改变文件的名字或路径要改写context-param</p>
<p>2 menu-config.xml</p>
<p>需要配置菜单的显示样式，如下：</p>
<p>&nbsp;</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;?</span><span style="color: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"&nbsp;</span><span style="color: #0000ff">?&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuConfig</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Displayers</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Displayer&nbsp;&nbsp;&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="DropDown"</span><span style="color: #ff0000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type</span><span style="color: #0000ff">="net.sf.navigator.displayer.DropDownMenuDisplayer"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Displayer&nbsp;&nbsp;&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Simple"</span><span style="color: #ff0000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type</span><span style="color: #0000ff">="net.sf.navigator.displayer.SimpleMenuDisplayer"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Displayer&nbsp;&nbsp;&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="CoolMenu"</span><span style="color: #ff0000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type</span><span style="color: #0000ff">="net.sf.navigator.displayer.CoolMenuDisplayer"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Displayer&nbsp;&nbsp;&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="CoolMenu4"</span><span style="color: #ff0000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type</span><span style="color: #0000ff">="net.sf.navigator.displayer.CoolMenuDisplayer4"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Displayer&nbsp;&nbsp;&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="MenuForm"</span><span style="color: #ff0000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type</span><span style="color: #0000ff">="net.sf.navigator.example.PermissionsFormMenuDisplayer"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Displayer&nbsp;&nbsp;&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="ListMenu"</span><span style="color: #ff0000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type</span><span style="color: #0000ff">="net.sf.navigator.displayer.ListMenuDisplayer"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Displayer&nbsp;&nbsp;&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="TabbedMenu"</span><span style="color: #ff0000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type</span><span style="color: #0000ff">="net.sf.navigator.displayer.TabbedMenuDisplayer"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Displayer&nbsp;&nbsp;&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Velocity"</span><span style="color: #ff0000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type</span><span style="color: #0000ff">="net.sf.navigator.displayer.VelocityMenuDisplayer"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Displayers</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">MenuConfig</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<p><br />
3 dynamicmenu.jsp</p>
<p>menu的数据结构<br />
&nbsp;&nbsp;&nbsp; MenuRepository：包含了所有的菜单数据，它的里面保存菜单的形式是二维表的形式。一个菜单就是一条记录<br />
&nbsp;&nbsp;&nbsp; MenuComponent： 代表一个菜单，也就是二维表中的一条记录，父菜单和子菜单在这里区分，如果它的getParent（）方法返回为空，那么它就是顶级菜单，它下面的子菜单设置它为父菜单方法：setParent（MenuComponent parent），该菜单的下面还可以有子菜单。<br />
&nbsp;&nbsp;&nbsp; 最后要做的是把所有设置好的菜单项，用repository.addMenu(mc) 方法加入到repository中。那么一个级联菜单就做好了，示例代码：</p>
<p>&nbsp;</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">MenuRepository&nbsp;repository</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;MenuRepository();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;MenuComponent&nbsp;mc</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;MenuComponent();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;mc.setName(</span><span style="color: #000000">"</span><span style="color: #000000">myMenu</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;mc.setTitle(</span><span style="color: #000000">"</span><span style="color: #000000">File</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;MenuComponent&nbsp;copy</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;MenuComponent();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;copy.setTitle(</span><span style="color: #000000">"</span><span style="color: #000000">copy</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;copy.setParent(mc);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;MenuComponent&nbsp;open</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;MenuComponent();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;open.setTitle(</span><span style="color: #000000">"</span><span style="color: #000000">Open</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;open.setParent(mc);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;MenuComponent&nbsp;close</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;MenuComponent();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;close.setTitle(</span><span style="color: #000000">"</span><span style="color: #000000">New</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;close.setParent(mc);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;MenuComponent&nbsp;case1&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;MenuComponent();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;case1.setParent(close);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;case1.setTitle(</span><span style="color: #000000">"</span><span style="color: #000000">case1</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;repository.addMenu(mc);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;repository.addMenu(open);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;repository.addMenu(close);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;repository.addMenu(copy);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<p>下面是菜单的显示：</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&nbsp;MenuRepository&nbsp;defaultRepository&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(MenuRepository)<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;application.getAttribute(MenuRepository.MENU_REPOSITORY_KEY);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;repository.setDisplayers(defaultRepository.getDisplayers());</span></div>
<p>上面代码的含义：<br />
&nbsp;&nbsp;&nbsp; 取得菜单的显示样式，设置给repository，也就是上面menu-config.xml中设置的八种样式。</p>
<p>&nbsp;&nbsp;&nbsp; pageContext.setAttribute("net.sf.navigator.menu.MENU_REPOSITORY",repository);<br />
把菜单装入到.jsp文件中，赋值给属性"net.sf.navigator.menu.MENU_REPOSITORY" 然后jsp的menu标签就会从该属性中取得菜单的显示样式和数据<br />
<br />
=================<br />
使用Struts Menu实现权限管理<br />
<br />
<br />
Struts Menu也是Matt Raible的作品，我以前一直在找能够在Java里面指定实现页面上树形菜单和下拉菜单的东西，我去年找到一个JS的东西，可以从XML文件中读取结构，我使用XSLT来生成显示的菜单，后来感觉不灵活，也没有用到项目上，2004年11月开始接触AppFuse，发现里面有个Struts Menu，从例子看起来外观还不错，用起来，发现更不错，可以在配置文件中指定那些角色可以看到当前的链接，如果roles中没有指定的角色进入系统后，则自动隐藏。我在去年的一个小项目用了一下，发现还行，至少不用我把逻辑嵌入到一堆JS里面。<br />
<br />
因为今年上半年要对以前的一个系统进行升级，要根据用户或者角色的权限把一些菜单隐藏起来，如果使用Struts Menu的roles的话，则角色是写死在代码里面的，就是"硬编码"(hardcode)，而且这里的角色是Application Server上配置的，在Tomcat上配置还算简单，在WebLogic等大型的服务器程序上配置，必须使用他们提供的Console软件，否则，要自己写好几个文件，比较繁琐，而且这些角色是在安装是就指定的，如果用户以后想添加新的角色名字，还要修改应用服务器的配置文件（不管是手工，还是代码处理）。<br />
<br />
如果你的系统负责处理权限，如生成用户、角色，还要为角色、用户指定有操作哪些模块的哪些操作，一个系统很可能有几十个或者上百个角色（往极端情况去想，呵呵），那么如果能够动态的控制显示哪些菜单项是我们系统中必须解决的问题，而Struts Menu完全胜任这样的要求，具体实现可以参看Struts Menu的下载文件中的文档，需要重点看的是http://demo.raibledesigns.com/struts-menu/dynamicMenu.jsp(动态构建菜单结构)和http://struts-menu.sourceforge.net/security.html（这篇文章我视而不见，以为没有用处，谢谢倦兔的提醒，^_^）。这两篇文章的用法是独立的，并不一定都要实现，如果你的菜单项是固定的，短期不会有所变动，那么可以写死到配置文件中，然后用第二篇文章中说的那样，写一个类，实现接口PermissionsAdapter，isAllowed方法中传入菜单项的名字，然后决定是否显示该项菜单，<br />
<br />
String[] menus = request.getParameterValues("menuNames");<br />
<br />
注释：menuNames是从数据库中读出的记录的集合（数组），你也可以用其他机构，<br />
<br />
然后放入使用request.setAttribute("menuNames", String[] 变量) 放入request中。<br />
<br />
PermissionsAdapter permissions = new SimplePermissionsAdapter(menus);//menus是菜单名字的数组<br />
request.getSession().setAttribute("YourAdapter", permissions);} //"YourAdapter"随便起的名字，<br />
</p>
<img src ="http://www.blogjava.net/gdufo/aggbug/210947.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gdufo/" target="_blank">gdufo</a> 2008-06-26 21:16 <a href="http://www.blogjava.net/gdufo/archive/2008/06/26/210947.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转)我的APPFUSE2.0.1开发过程的问题记录和解决办法 </title><link>http://www.blogjava.net/gdufo/archive/2008/06/25/210688.html</link><dc:creator>gdufo</dc:creator><author>gdufo</author><pubDate>Wed, 25 Jun 2008 14:10:00 GMT</pubDate><guid>http://www.blogjava.net/gdufo/archive/2008/06/25/210688.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: (转)我的APPFUSE2.0.1开发过程的问题记录和解决办法 &nbsp;&nbsp;<a href='http://www.blogjava.net/gdufo/archive/2008/06/25/210688.html'>阅读全文</a><img src ="http://www.blogjava.net/gdufo/aggbug/210688.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gdufo/" target="_blank">gdufo</a> 2008-06-25 22:10 <a href="http://www.blogjava.net/gdufo/archive/2008/06/25/210688.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>