﻿<?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-空间站-文章分类-Struts</title><link>http://www.blogjava.net/i369/category/18051.html</link><description>北极心空</description><language>zh-cn</language><lastBuildDate>Wed, 28 May 2008 18:14:27 GMT</lastBuildDate><pubDate>Wed, 28 May 2008 18:14:27 GMT</pubDate><ttl>60</ttl><item><title>当JsonPlugin遇到CGLib</title><link>http://www.blogjava.net/i369/articles/203608.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Wed, 28 May 2008 10:26:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/203608.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/203608.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/203608.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/203608.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/203608.html</trackback:ping><description><![CDATA[<p>JsonPlugin在分析类结构并序列化时，对于CGLig动态生成的类也是按照一般类来看待的。这就导致了如下的问题：<br />
<br />
在一个应用中，某些情况下，一个服务类返回的实体并不是原有实体类的对象，而是CGLib动态生成的子类。例如使用Hibernate的时候，某些情况下DAO返回的是EntityClassName$$EnhancerByCGLIB$$ac21e这样的类的对象。Hibernate在这个子类中添加了hibernateLazyInitializer等等的附加属性。由于jsonplugin并不区分类和动态生成的类，所以也会试图序列化hibernateLazyInitializer属性，从而导致出现如下的异常：</p>
java.sql.SQLException: Positioned Update not supported.<br />
&nbsp;at com.mysql.jdbc.ResultSet.getCursorName(ResultSet.java:1800)<br />
<br />
另外，CGLIB生成的类，某些方法上的@JSON标记奇怪的丢失了。导致标记了@JSON(serialize=false)的属性也被序列化。<br />
<br />
在网上查了很久没有发现相关的文章，所以无奈就自己动手修改jsonplugin的代码了。<br />
<br />
类：com.googlecode.jsonplugin.JSONWriter，修改bean()方法：<br />
<br />
<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; line-height: 22px; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;bean(Object&nbsp;object)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;JSONException&nbsp;{<br />
</span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.add(</span><span style="color: #000000">"</span><span style="color: #000000">{</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
</span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BeanInfo&nbsp;info;<br />
</span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;{<br />
</span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class&nbsp;clazz&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;object.getClass();<br />
</span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;info&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;((object&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.root)&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.ignoreHierarchy)&nbsp;</span><span style="color: #000000">?</span><span style="color: #000000">&nbsp;Introspector<br />
</span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getBeanInfo(clazz,&nbsp;clazz.getSuperclass())<br />
</span><span style="color: #008080">11</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;Introspector.getBeanInfo(clazz);<br />
</span><span style="color: #008080">12</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">13</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PropertyDescriptor[]&nbsp;props&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;info.getPropertyDescriptors();<br />
</span><span style="color: #008080">14</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">15</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">boolean</span><span style="color: #000000">&nbsp;hasData&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">;<br />
</span><span style="color: #008080">16</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;i&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;props.length;&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">i)&nbsp;{<br />
</span><span style="color: #008080">17</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PropertyDescriptor&nbsp;prop&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;props[i];<br />
</span><span style="color: #008080">18</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;name&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;prop.getName();<br />
</span><span style="color: #008080">19</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;accessor&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;prop.getReadMethod();<br />
</span><span style="color: #008080">20</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;baseAccessor&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">这里增加一个临时变量作为真实希望序列化的属性的accessor方法引用</span><span style="color: #008000"><br />
</span><span style="color: #008080">21</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(clazz.getName().indexOf(</span><span style="color: #000000">"</span><span style="color: #000000">$$EnhancerByCGLIB$$</span><span style="color: #000000">"</span><span style="color: #000000">)&nbsp;</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">)&nbsp;{&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">如果是CGLIB动态生成的类</span><span style="color: #008000"><br />
</span><span style="color: #008080">22</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;{<br />
</span><span style="color: #008080">23</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">下面的逻辑是根据CGLIB动态生成的类名，得到原本的实体类名<br />
</span><span style="color: #008080">24</span>&nbsp;<span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">例如&nbsp;EntityClassName$$EnhancerByCGLIB$$ac21e这样<br />
</span><span style="color: #008080">25</span>&nbsp;<span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">的类，将返回的是EntityClassName这个类中的相应方法，若<br />
</span><span style="color: #008080">26</span>&nbsp;<span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">获取不到对应方法，则说明要序列化的属性例如hibernateLazyInitializer之类<br />
</span><span style="color: #008080">27</span>&nbsp;<span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">不在原有实体类中，而是仅存在于CGLib生成的子类中，此时baseAccessor<br />
</span><span style="color: #008080">28</span>&nbsp;<span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">保持为null</span><span style="color: #008000"><br />
</span><span style="color: #008080">29</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;baseAccessor&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;Class.forName(<br />
</span><span style="color: #008080">30</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clazz.getName().substring(</span><span style="color: #000000">0</span><span style="color: #000000">,<br />
</span><span style="color: #008080">31</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clazz.getName().indexOf(</span><span style="color: #000000">"</span><span style="color: #000000">$$</span><span style="color: #000000">"</span><span style="color: #000000">)))<br />
</span><span style="color: #008080">32</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getDeclaredMethod(accessor.getName(),<br />
</span><span style="color: #008080">33</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;accessor.getParameterTypes());<br />
</span><span style="color: #008080">34</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(Exception&nbsp;ex)&nbsp;{<br />
</span><span style="color: #008080">35</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.debug(ex.getMessage());<br />
</span><span style="color: #008080">36</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080">37</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080">38</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">若不是CGLib生成的类，那么要序列化的属性的accessor方法就是该类中的方法。</span><span style="color: #008000"><br />
</span><span style="color: #008080">39</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;baseAccessor&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;accessor;<br />
</span><span style="color: #008080">40</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">41</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">这个判断，根据上面的逻辑，使得仅存在于CGLIB生成子类中的属性跳过JSON序列化</span><span style="color: #008000"><br />
</span><span style="color: #008080">42</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(baseAccessor&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">43</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">44</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">下面的JSON&nbsp;Annotation的获取也修改为从baseAccessor获取，这样避免了<br />
</span><span style="color: #008080">45</span>&nbsp;<span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">由于CGLIB生成子类而导致某些方法上的JSON&nbsp;Annotation丢失导致处理不该<br />
</span><span style="color: #008080">46</span>&nbsp;<span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">序列化的属性</span><span style="color: #008000"><br />
</span><span style="color: #008080">47</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JSON&nbsp;json&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;baseAccessor.getAnnotation(JSON.</span><span style="color: #0000ff">class</span><span style="color: #000000">);<br />
</span><span style="color: #008080">48</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(json&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)&nbsp;{<br />
</span><span style="color: #008080">49</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(</span><span style="color: #000000">!</span><span style="color: #000000">json.serialize())<br />
</span><span style="color: #008080">50</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">continue</span><span style="color: #000000">;<br />
</span><span style="color: #008080">51</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(json.name().length()&nbsp;</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">)<br />
</span><span style="color: #008080">52</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;json.name();<br />
</span><span style="color: #008080">53</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080">54</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">55</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">ignore&nbsp;"class"&nbsp;and&nbsp;others</span><span style="color: #008000"><br />
</span><span style="color: #008080">56</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">this</span><span style="color: #000000">.shouldExcludeProperty(clazz,&nbsp;prop))&nbsp;{<br />
</span><span style="color: #008080">57</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">continue</span><span style="color: #000000">;<br />
</span><span style="color: #008080">58</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080">59</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;expr&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />
</span><span style="color: #008080">60</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">this</span><span style="color: #000000">.buildExpr)&nbsp;{<br />
</span><span style="color: #008080">61</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expr&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.expandExpr(name);<br />
</span><span style="color: #008080">62</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">this</span><span style="color: #000000">.shouldExcludeProperty(expr))&nbsp;{<br />
</span><span style="color: #008080">63</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">continue</span><span style="color: #000000">;<br />
</span><span style="color: #008080">64</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080">65</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expr&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.setExprStack(expr);<br />
</span><span style="color: #008080">66</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080">67</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(hasData)&nbsp;{<br />
</span><span style="color: #008080">68</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.add(</span><span style="color: #000000">'</span><span style="color: #000000">,</span><span style="color: #000000">'</span><span style="color: #000000">);<br />
</span><span style="color: #008080">69</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080">70</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hasData&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">true</span><span style="color: #000000">;<br />
</span><span style="color: #008080">71</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">72</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;value&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;accessor.invoke(object,&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Object[</span><span style="color: #000000">0</span><span style="color: #000000">]);<br />
</span><span style="color: #008080">73</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.add(name,&nbsp;value,&nbsp;accessor);<br />
</span><span style="color: #008080">74</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">this</span><span style="color: #000000">.buildExpr)&nbsp;{<br />
</span><span style="color: #008080">75</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.setExprStack(expr);<br />
</span><span style="color: #008080">76</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080">77</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080">78</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080">79</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(Exception&nbsp;e)&nbsp;{<br />
</span><span style="color: #008080">80</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">throw</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;JSONException(e);<br />
</span><span style="color: #008080">81</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080">82</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">83</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.add(</span><span style="color: #000000">"</span><span style="color: #000000">}</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
</span><span style="color: #008080">84</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br />
这样修改之后，原有类中不能存在的属性将不会被序列化，同时，由于不检查生成的类的方法上的JSON标记，而是检查原有类上的标记，这样避免了由于CGLIB导致的Annotation丢失的问题。<br />
<br />
在此依然向诸位询问是否JSONPlugin有处理这样的情况的方法。 
<img src ="http://www.blogjava.net/i369/aggbug/203608.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/i369/" target="_blank">芦苇</a> 2008-05-28 18:26 <a href="http://www.blogjava.net/i369/articles/203608.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Translation]JSON与struts2[转]</title><link>http://www.blogjava.net/i369/articles/203606.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Wed, 28 May 2008 10:20:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/203606.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/203606.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/203606.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/203606.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/203606.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 下载地址: http://code.google.com/p/jsonplugin/downloads/list&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Apache提供的一个插件包，可以把Action中的数据以JSON做个封装然后返回。它会将整个action中的变量转化为J...&nbsp;&nbsp;<a href='http://www.blogjava.net/i369/articles/203606.html'>阅读全文</a><img src ="http://www.blogjava.net/i369/aggbug/203606.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/i369/" target="_blank">芦苇</a> 2008-05-28 18:20 <a href="http://www.blogjava.net/i369/articles/203606.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>［译］Struts Menu开发向导 [转]</title><link>http://www.blogjava.net/i369/articles/188258.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Mon, 24 Mar 2008 07:31:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/188258.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/188258.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/188258.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/188258.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/188258.html</trackback:ping><description><![CDATA[官方英文版向导（<a href="http://struts-menu.sourceforge.net/userguide.html"><a href="http://struts-menu.sourceforge.net/userguide.html" target="_blank"><font color="#666666">http://struts-menu.sourceforge.net/userguide.html</font></a></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"><a href="http://struts-menu.sf.net/tag" target="_blank"><font color="#666666">http://struts-menu.sf.net/tag</font></a></font></a><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></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 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></a>，这个文件包括例程WAR包文件和二进制发布包。<br />
1、放入struts-menu.jar包到你的应用程序的WEB-INF/lib目录中。<br />
2、在你的struts-config.xml文件中加入plug-in设置。<br />
<font style="background-color: #ffe000">&nbsp;&lt;plug-in className="net.sf.navigator.menu.MenuPlugIn"&gt;<br />
&nbsp;&nbsp; &lt;set-property property="menuConfig"<br />
&nbsp;&nbsp;&nbsp;&nbsp; value="/WEB-INF/menu-config.xml"/&gt;<br />
&nbsp;&lt;/plug-in&gt;</font><br />
3、你将需要在你的应用程序的/WEB-INF/menu-config.xml文件中定义你的菜单，这里提供一个简单的片断：<br />
<font style="background-color: #ffe000">&nbsp;&lt;Menu name="contactMenu" title="Contact" location="?Contact"&gt;<br />
&nbsp;&nbsp; &lt;Item name="email" title="E-Mail" location="?EMail"/&gt;<br />
&nbsp;&nbsp; &lt;Item name="phone" title="Phone" location="?Phone"/&gt;<br />
&nbsp;&lt;/Menu&gt;</font><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 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></a>）。<br />
4、在你的JSP文件的顶部加入taglib声明：<br />
&nbsp;<font style="background-color: #ffe000">&lt;% at taglib uri="</font><a href="http://struts-menu%20dot%20sf.net/tag"><font style="background-color: #ffe000"><a href="http://struts-menu.sf.net/tag" target="_blank"><font color="#666666">http://struts-menu.sf.net/tag</font></a></font></a><font style="background-color: #ffe000">" prefix="menu" %&gt;</font><br />
5、在你的JSP文件中要放置菜单的位置加入taglib代码：<br />
<font style="background-color: #ffe000">&nbsp;&lt;menu:useMenuDisplayer name="TabbedMenu"<br />
&nbsp;&nbsp; bundle="org.apache.struts.action.MESSAGE"&gt;<br />
&nbsp;&nbsp; &lt;menu:displayMenu name="Home"/&gt;<br />
&nbsp;&nbsp; &lt;menu:displayMenu name="About"/&gt;<br />
&nbsp;&lt;/menu:useMenuDisplayer&gt;</font><br />
　　属性name="TabbedMenu"被定义在menu-config.xml文件的顶部：<br />
<font style="background-color: #ffe000">&nbsp;&lt;Displayer name="TabbedMenu"<br />
&nbsp;&nbsp; type="net.sf.navigator.displayer.TabbedMenuDisplayer"/&gt;</font></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 />
<font style="background-color: #ffe000">&nbsp;&lt;Displayer name="Velocity" <br />
&nbsp;&nbsp;&nbsp;&nbsp; type="net.sf.navigator.displayer.VelocityMenuDisplayer"/&gt;</font><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 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></a>）和velocity-tools-view-1.0.jar（<a href="http://www.ibiblio.org/maven/velocity-tools/jars/velocity-tools-view-1.0.jar"><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></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 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</a>（右键另存为））到你的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 href="http://demo.raibledesigns.com/struts-menu/index.jsp" target="_blank"><font color="#666666">http://demo.raibledesigns.com/struts-menu/index.jsp</font></a></a>）中查看。它总是在你的菜单需要的时候显示CSS，JavaScript和图像文件。下面有一些在当前的Struts Menu中用到的Velocity模版的例子的链接：<br />
&nbsp;CoolMenus: Demo（<a href="http://demo.raibledesigns.com/struts-menu/velocity-coolmenu4.jsp"><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></a>）, <br />
&nbsp;&nbsp;　 Template（<a href="http://struts-menu.sourceforge.net/templates/coolmenus.html"><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></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 href="http://struts-menu.sourceforge.net/menu-images/" target="_blank"><font color="#666666">http://struts-menu.sourceforge.net/menu-images/</font></a></a>）<br />
&nbsp;Stylesheets （<a href="http://struts-menu.sourceforge.net/styles/"><a href="http://struts-menu.sourceforge.net/styles/" target="_blank"><font color="#666666">http://struts-menu.sourceforge.net/styles/</font></a></a>）<br />
&nbsp;Scripts （<a href="http://struts-menu.sourceforge.net/scripts/"><a href="http://struts-menu.sourceforge.net/scripts/" target="_blank"><font color="#666666">http://struts-menu.sourceforge.net/scripts/</font></a></a>）<br />
&nbsp;Templates （<a href="http://struts-menu.sourceforge.net/templates/"><a href="http://struts-menu.sourceforge.net/templates/" target="_blank"><font color="#666666">http://struts-menu.sourceforge.net/templates/</font></a></a>）</p>
<p>更多的基于roles的显示/隐藏菜单的信息，请查看FAQs（<a href="http://struts-menu.sourceforge.net/faq.html"><a href="http://struts-menu.sourceforge.net/faq.html" target="_blank"><font color="#666666">http://struts-menu.sourceforge.net/faq.html</font></a></a>）。</p>
<p>四、在Struts之外使用Struts Menu:<br />
在2.2版中，Menu Repository能够使用MenuContextListener载入：<br />
<font style="background-color: #ffe000">&nbsp;&lt;!--<br />
&nbsp;&nbsp;&nbsp; - Loads the menu-config.xml for struts-menu at startup,<br />
&nbsp;&nbsp;&nbsp; - by default from "/WEB-INF/menu-config.xml".<br />
&nbsp;&nbsp;&nbsp; - To override this, add a context-param named "menuConfigLocation"<br />
&nbsp;&nbsp;&nbsp; - web.xml file.<br />
&nbsp;&nbsp;&nbsp; --&gt;<br />
&nbsp;&lt;listener&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;listener-class&gt;net.sf.navigator.menu.MenuContextListener&lt;/listener-class&gt;<br />
&nbsp;&lt;/listener&gt;</font></p>
<p>或者如果你使用Spring，甚至更容易。仅仅需要加入下面的部分到你的applicationContext.xml文件中：<br />
<font style="background-color: #ffe000">&nbsp;&lt;bean id="menu" class="net.sf.navigator.menu.MenuLoader"&gt;<br />
&nbsp;&nbsp; &lt;property name="menuConfig"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;/WEB-INF/menu-config.xml&lt;/value&gt;<br />
&nbsp;&nbsp; &lt;/property&gt;<br />
&nbsp;&lt;/bean&gt;<br />
&nbsp;&lt;!-- The menuConfig property is an optional attribute.&nbsp; It is set to<br />
&nbsp;&nbsp;&nbsp;&nbsp; /WEB-INF/menu-config.xml by default. --&gt;</font><br />
感谢Dan Luputan提供MenuLoader类的源代码。</p>
<p>五、从源文件编译：<br />
要从源文件编译这个项目，执行下面的步骤：<br />
1、下载并安装Maven（<a href="http://maven.apache.org/"><a href="http://maven.apache.org/" target="_blank"><font color="#666666">http://maven.apache.org/</font></a></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 href="http://localhost:8080/struts-menu" target="_blank"><font color="#666666">http://localhost:8080/struts-menu</font></a></a>在你喜爱的浏览器中。</p>
<p>如果你喜欢使用Eclipse开发项目，请参考此份开发向导（<a href="http://struts-menu.sourceforge.net/devguide.html"><a href="http://struts-menu.sourceforge.net/devguide.html" target="_blank"><font color="#666666">http://struts-menu.sourceforge.net/devguide.html</font></a></a>）。 </p>
<img src ="http://www.blogjava.net/i369/aggbug/188258.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/i369/" target="_blank">芦苇</a> 2008-03-24 15:31 <a href="http://www.blogjava.net/i369/articles/188258.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Strus 2的新表单标志的使用 [转]</title><link>http://www.blogjava.net/i369/articles/183622.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Tue, 04 Mar 2008 02:30:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/183622.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/183622.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/183622.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/183622.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/183622.html</trackback:ping><description><![CDATA[<div class="postTitle"><a class="postTitle2" id="viewpost1_TitleUrl" href="http://www.blogjava.net/max/archive/2007/05/18/118442.html">Strus 2的新表单标志的使用</a> </div>
<p>&nbsp;Struts 2为大家提供了不少常用的很酷的表单标志，简化了我们程序员的工作。不过，由于这些都是新标志，大家可能在使用上还存在不少疑问。本文将就朋友们的回复、留言或Email上的问题，分别对这些酷标志进行讲述。</p>
<h2>表单标志使用小技巧</h2>
<p>Struts 2的表单标志在输出（render）HTML时，使用了模板的概念，增加了复杂性（因为它不像Struts 1.x的表单标志，它通常都是一个标志对应HTML的一个元素），因此大家在使用时，需要一些技巧：</p>
<ol>
    <li>Struts 2的UI标志的表单标志默认是以表格布局，按钮是右对齐的。如果你不喜欢此风格，你可以简单地将&lt;s:form /&gt;标志的&#8220;theme&#8221;属性设为&#8220;simple&#8221;，然后用以往的做法自已布局表单元素（注意：此法有利有弊，弊就是当你将&#8220;theme&#8221;属性设为&#8220;simple&#8221;时，表单标志以最简单方式输出HTML，所以你可能失去一些默认输出提供的便利，如：友好的错误信息的显示，或客户端的表单验证等）。当然更好的做法是通过CSS或自定义主题（theme）然后应用到整个应用程序，这样可以获得一致的页面风格，加强用户体验（我会在以后的文章对此进行讲解）；
    <li>当你在页面上加入某些标志（如：&lt;s:doubleselect /&gt;等）时，应该通过action来访问页面，而不是通过*.jsp的URL直接访问。 </li>
</ol>
<p>下面我将分别对这些标志进行讲述：</p>
<h2>1、&lt;s:checkboxlist /&gt;</h2>
<p>大家对&lt;s:checkboxlist /&gt;的最大的疑问可能是：&#8220;如何在默认情况下，选中某些checkbox？&#8221;</p>
<p>答案其实很简单，只需要将其&#8220;value&#8221;属性设为你的要选中的值，如以代码所示：</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"><span style="color: #000000; background-color: #ffff00">&lt;%</span><span style="color: #000000; background-color: #f5f5f5">@ page language</span><span style="color: #000000; background-color: #f5f5f5">=</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">java</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5"> contentType</span><span style="color: #000000; background-color: #f5f5f5">=</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">text/html; charset=utf-8</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5"> pageEncoding</span><span style="color: #000000; background-color: #f5f5f5">=</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">utf-8</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5"> </span><span style="color: #000000; background-color: #ffff00">%&gt;</span><span style="color: #000000"><br />
</span><span style="color: #000000; background-color: #ffff00">&lt;%</span><span style="color: #000000; background-color: #f5f5f5">@ taglib prefix</span><span style="color: #000000; background-color: #f5f5f5">=</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">s</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5"> uri</span><span style="color: #000000; background-color: #f5f5f5">=</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">/struts-tags</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5"> </span><span style="color: #000000; background-color: #ffff00">%&gt;</span><span style="color: #000000"><br />
<br />
</span><span style="color: #0000ff">&lt;!</span><span style="color: #ff00ff">DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">html </span><span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="http://www.w3.org/1999/xhtml"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">head</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">title</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">Struts 2 Cool Tags - </span><span style="color: #ff0000">&amp;lt;</span><span style="color: #000000">s:checkboxlist/ </span><span style="color: #ff0000">&amp;gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">title</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:head </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">head</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">body</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"> &nbsp; &nbsp;<br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">h2</span><span style="color: #0000ff">&gt;</span><span style="color: #ff0000">&amp;lt;</span><span style="color: #000000">s:checkboxlist/</span><span style="color: #ff0000">&amp;gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">h2</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:form </span><span style="color: #ff0000">action</span><span style="color: #0000ff">="Store"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:checkboxlist </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="skills1"</span><span style="color: #ff0000">&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; label</span><span style="color: #0000ff">="Skills 1"</span><span style="color: #ff0000">&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list</span><span style="color: #0000ff">="{ 'Java', '.Net', 'RoR', 'PHP' }"</span><span style="color: #ff0000">&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value</span><span style="color: #0000ff">="{ 'Java', '.Net' }"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:checkboxlist </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="skills2"</span><span style="color: #ff0000">&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; label</span><span style="color: #0000ff">="Skills 2"</span><span style="color: #ff0000">&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list</span><span style="color: #0000ff">="#{ 1:'Java', 2: '.Net', 3: 'RoR', 4: 'PHP' }"</span><span style="color: #ff0000">&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; listKey</span><span style="color: #0000ff">="key"</span><span style="color: #ff0000">&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; listValue</span><span style="color: #0000ff">="value"</span><span style="color: #ff0000">&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value</span><span style="color: #0000ff">="{ 1, 2, 3 }"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:form</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">body</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">html</span><span style="color: #0000ff">&gt;</span></div>
<span style="font-size: smaller; font-style: italic">清单1 WebContent/checkboxlist.jsp</span>
<p>分布运行应用程序，在浏览器中键入：<a href="http://localhost:8080/Struts2_CoolTags/checkboxlist.jsp">http://localhost:8080/Struts2_CoolTags/checkboxlist.jsp</a>，出现如下图所示页面：</p>
<p><img alt="checkboxlist.jsp页面" src="http://www.blogjava.net/images/blogjava_net/max/22548/r_checkboxlist.gif" /><br />
<span style="font-size: smaller; font-style: italic">清单2 checkboxlist.jsp页面</span></p>
<h2>2、&lt;s:doubleselect /&gt;</h2>
<p>大家看Struts 2的showcase的例子，&lt;s:doubleselect /&gt;的用法如下所示：</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"><span style="color: #000000">&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:doubleselect<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #ff0000">tooltip</span><span style="color: #0000ff">="Choose Your State"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; label</span><span style="color: #0000ff">="State"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name</span><span style="color: #0000ff">="region"</span><span style="color: #ff0000"> list</span><span style="color: #0000ff">="{'North', 'South'}"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value</span><span style="color: #0000ff">="'South'"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doubleValue</span><span style="color: #0000ff">="'Florida'"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doubleList</span><span style="color: #0000ff">="top == 'North' ? {'Oregon', 'Washington'} : {'Texas', 'Florida'}"</span><span style="color: #ff0000">&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doubleName</span><span style="color: #0000ff">="state"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; headerKey</span><span style="color: #0000ff">="-1"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; headerValue</span><span style="color: #0000ff">="---------- Please Select ----------"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; emptyOption</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/&gt;</span></div>
<span style="font-size: smaller; font-style: italic">清单3 Showcase中&lt;s:doubleselect /&gt;</span>
<p>很多朋友问：&#8220;上面的&#8216;list&#8217;属性只有两个值，如果我有三个或更多的值，&#8216;doublelist&#8217;属性应该如何设定呢？&#8221;</p>
<p>我建议的做法是先定义一个Map类型的对象，键为&#8220;list&#8221;的集合，值则为&#8220;doubleList&#8221;的集合，然后&#8220;doubleList&#8221;的OGNL写成&#8220;#myMap[top]&#8221;，如以下代码所示：</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"><span style="color: #000000; background-color: #ffff00">&lt;%</span><span style="color: #000000; background-color: #f5f5f5">@ page language</span><span style="color: #000000; background-color: #f5f5f5">=</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">java</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5"> contentType</span><span style="color: #000000; background-color: #f5f5f5">=</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">text/html; charset=utf-8</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5"> pageEncoding</span><span style="color: #000000; background-color: #f5f5f5">=</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">utf-8</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5"> </span><span style="color: #000000; background-color: #ffff00">%&gt;</span><span style="color: #000000"><br />
</span><span style="color: #000000; background-color: #ffff00">&lt;%</span><span style="color: #000000; background-color: #f5f5f5">@ taglib prefix</span><span style="color: #000000; background-color: #f5f5f5">=</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">s</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5"> uri</span><span style="color: #000000; background-color: #f5f5f5">=</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">/struts-tags</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5"> </span><span style="color: #000000; background-color: #ffff00">%&gt;</span><span style="color: #000000"><br />
<br />
</span><span style="color: #0000ff">&lt;!</span><span style="color: #ff00ff">DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">html </span><span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="http://www.w3.org/1999/xhtml"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">head</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">title</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">Struts 2 Cool Tags - </span><span style="color: #ff0000">&amp;lt;</span><span style="color: #000000">s:doubeselect/ </span><span style="color: #ff0000">&amp;gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">title</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:head </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">head</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">body</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"> &nbsp; &nbsp;<br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">h2</span><span style="color: #0000ff">&gt;</span><span style="color: #ff0000">&amp;lt;</span><span style="color: #000000">s:doubleselect/</span><span style="color: #ff0000">&amp;gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">h2</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:form </span><span style="color: #ff0000">action</span><span style="color: #0000ff">="Store"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:set </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="foobar"</span><span style="color: #ff0000">&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;value</span><span style="color: #0000ff">="#{'Java': {'Spring', 'Hibernate', 'Struts 2'}, '.Net': {'Linq', ' ASP.NET 2.0'}, 'Database': {'Oracle', 'SQL Server', 'DB2', 'MySQL'}}"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:doubleselect </span><span style="color: #ff0000">list</span><span style="color: #0000ff">="#foobar.keySet()"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doubleName</span><span style="color: #0000ff">="technology"</span><span style="color: #ff0000">&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doubleList</span><span style="color: #0000ff">="#foobar[top]"</span><span style="color: #ff0000">&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; label</span><span style="color: #0000ff">="Technology"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:form</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">body</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">html</span><span style="color: #0000ff">&gt;</span></div>
<span style="font-size: smaller; font-style: italic">清单4 WebContent/doubleselect.jsp</span>
<p>分布运行应用程序，在浏览器中键入：<a href="http://localhost:8080/Struts2_CoolTags/doubleselect.action">http://localhost:8080/Struts2_CoolTags/doubleselect.action</a>，出现如下图所示页面：</p>
<p><img alt="doubleselect.jsp页面" src="http://www.blogjava.net/images/blogjava_net/max/22548/r_doubleselect.gif" /><br />
<span style="font-size: smaller; font-style: italic">清单5 doubleselect.jsp页面</span></p>
<h2>3、&lt;s: token /&gt;</h2>
<p>这个标志可能大家不常用，不过本人认为它还是挺有用的。在使用Struts 1.x时，因为跳转通常是用Forward（而不是Redirect）实现的，所以当用户完成请求后，按&#8220;F5&#8221;刷新页面时，就会重新提交上次的请求，这样经常会出错。要解决这个问题，&lt;s:token /&gt;可以帮你忙。</p>
<h3>实现原理</h3>
<p>在页面加载时，&lt;s: token /&gt;产生一个GUID（Globally Unique Identifier，全局唯一标识符）值的隐藏输入框如：</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"><span style="color: #0000ff">&lt;</span><span style="color: #800000">input </span><span style="color: #ff0000">type</span><span style="color: #0000ff">="hidden"</span><span style="color: #ff0000"> name</span><span style="color: #0000ff">="struts.token.name"</span><span style="color: #ff0000"> value</span><span style="color: #0000ff">="struts.token"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">input </span><span style="color: #ff0000">type</span><span style="color: #0000ff">="hidden"</span><span style="color: #ff0000"> name</span><span style="color: #0000ff">="struts.token"</span><span style="color: #ff0000"> value</span><span style="color: #0000ff">="BXPNNDG6BB11ZXHPI4E106CZ5K7VNMHR"</span><span style="color: #0000ff">/&gt;</span></div>
<span style="font-size: smaller; font-style: italic">清单6 &lt;s:token /&gt;的HTML输出</span>
<p>同时，将GUID放到会话（session）中；在执行action之前，&#8220;token&#8221;拦截器将会话token与请求token比较，如果两者相同，则将会话中的token删除并往下执行，否则向actionErrors加入错误信息。如此一来，如果用户通过某种手段提交了两次相同的请求，两个token就会不同。</p>
<h3>具体实现</h3>
<p>首先看一下Action的代码：</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">package</span><span style="color: #000000"> tutorial;<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">import</span><span style="color: #000000"> com.opensymphony.xwork2.ActionSupport;<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_115_471_Open_Image" onclick="this.style.display='none'; Codehighlighter1_115_471_Open_Text.style.display='none'; Codehighlighter1_115_471_Closed_Image.style.display='inline'; Codehighlighter1_115_471_Closed_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_115_471_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_115_471_Closed_Text.style.display='none'; Codehighlighter1_115_471_Open_Image.style.display='inline'; Codehighlighter1_115_471_Open_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">class</span><span style="color: #000000"> CoolTagAction </span><span style="color: #0000ff">extends</span><span style="color: #000000"> ActionSupport </span><span id="Codehighlighter1_115_471_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_115_471_Open_Text"><span style="color: #000000">{ &nbsp; &nbsp;<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /> &nbsp; &nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000"> </span><span style="color: #0000ff">static</span><span style="color: #000000"> </span><span style="color: #0000ff">final</span><span style="color: #000000"> </span><span style="color: #0000ff">long</span><span style="color: #000000"> serialVersionUID </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">6820659617470261780L</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /> &nbsp; &nbsp;<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /> &nbsp; &nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000"> String message;<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /> &nbsp; &nbsp; &nbsp; &nbsp;<br />
<img id="Codehighlighter1_244_265_Open_Image" onclick="this.style.display='none'; Codehighlighter1_244_265_Open_Text.style.display='none'; Codehighlighter1_244_265_Closed_Image.style.display='inline'; Codehighlighter1_244_265_Closed_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_244_265_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_244_265_Closed_Text.style.display='none'; Codehighlighter1_244_265_Open_Image.style.display='inline'; Codehighlighter1_244_265_Open_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" /> &nbsp; &nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000"> String getMessage() </span><span id="Codehighlighter1_244_265_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_244_265_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /> &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000"> message;<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" /> &nbsp; &nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_308_337_Open_Image" onclick="this.style.display='none'; Codehighlighter1_308_337_Open_Text.style.display='none'; Codehighlighter1_308_337_Closed_Image.style.display='inline'; Codehighlighter1_308_337_Closed_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_308_337_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_308_337_Closed_Text.style.display='none'; Codehighlighter1_308_337_Open_Image.style.display='inline'; Codehighlighter1_308_337_Open_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" /> &nbsp; &nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> setMessage(String message) </span><span id="Codehighlighter1_308_337_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_308_337_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /> &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.message </span><span style="color: #000000">=</span><span style="color: #000000"> message;<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" /> &nbsp; &nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /> &nbsp; &nbsp;<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /> &nbsp; &nbsp;@Override<br />
<img id="Codehighlighter1_377_468_Open_Image" onclick="this.style.display='none'; Codehighlighter1_377_468_Open_Text.style.display='none'; Codehighlighter1_377_468_Closed_Image.style.display='inline'; Codehighlighter1_377_468_Closed_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_377_468_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_377_468_Closed_Text.style.display='none'; Codehighlighter1_377_468_Open_Image.style.display='inline'; Codehighlighter1_377_468_Open_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" /> &nbsp; &nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000"> String execute() </span><span id="Codehighlighter1_377_468_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_377_468_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /> &nbsp; &nbsp; &nbsp; &nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">Executing action, your message is </span><span style="color: #000000">"</span><span style="color: #000000"> </span><span style="color: #000000">+</span><span style="color: #000000"> message);<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /> &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000"> SUCCESS;<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" /> &nbsp; &nbsp;}</span></span><span style="color: #000000"> &nbsp; &nbsp;<br />
<img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span></div>
<span style="font-size: smaller; font-style: italic">清单7 src/tutorial/CoolTagAction.java</span>
<p>以上代码一目了然，再看看JSP的写法：</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"><span style="color: #000000">%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %&gt;<br />
</span><span style="color: #000000; background-color: #ffff00">&lt;%</span><span style="color: #000000; background-color: #f5f5f5">@ taglib prefix</span><span style="color: #000000; background-color: #f5f5f5">=</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">s</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5"> uri</span><span style="color: #000000; background-color: #f5f5f5">=</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">/struts-tags</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5"> </span><span style="color: #000000; background-color: #ffff00">%&gt;</span><span style="color: #000000"><br />
<br />
</span><span style="color: #0000ff">&lt;!</span><span style="color: #ff00ff">DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">html </span><span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="http://www.w3.org/1999/xhtml"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">head</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">title</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">Struts 2 Cool Tags - </span><span style="color: #ff0000">&amp;lt;</span><span style="color: #000000">s:token/ </span><span style="color: #ff0000">&amp;gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">title</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:head </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">head</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">body</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"> &nbsp; &nbsp;<br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">h2</span><span style="color: #0000ff">&gt;</span><span style="color: #ff0000">&amp;lt;</span><span style="color: #000000">s:token/</span><span style="color: #ff0000">&amp;gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">h2</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:actionerror </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:form </span><span style="color: #ff0000">action</span><span style="color: #0000ff">="Token"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:textfield </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="message"</span><span style="color: #ff0000"> label</span><span style="color: #0000ff">="Message"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:token </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:submit </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:form</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">body</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">html</span><span style="color: #0000ff">&gt;</span></div>
<span style="font-size: smaller; font-style: italic">清单8 WebContent/token.jsp</span>
<p>JSP也很简单，就是加入&lt;s:token /&gt;标志。接下来是Actoin配置的XML片段：</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"><span style="color: #0000ff">&lt;?</span><span style="color: #ff00ff">xml version="1.0" encoding="UTF-8"</span><span style="color: #0000ff">?&gt;</span><span style="color: #000000"><br />
<br />
</span><span style="color: #0000ff">&lt;!</span><span style="color: #ff00ff">DOCTYPE struts PUBLIC<br />
&nbsp; &nbsp; "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"<br />
&nbsp; &nbsp; "http://struts.apache.org/dtds/struts-2.0.dtd"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">struts</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">package </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Struts2_COOL_TAGS_DEMO"</span><span style="color: #ff0000"> extends</span><span style="color: #0000ff">="struts-default"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">action </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Token"</span><span style="color: #ff0000"> class</span><span style="color: #0000ff">="tutorial.CoolTagAction"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">interceptor-ref </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="defaultStack"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">interceptor-ref </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="token"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">result </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="invalid.token"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">/token.jsp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">result</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">result</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">/token.jsp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">result</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">action</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">action </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="*"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">result</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">/{1}.jsp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">result</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">action</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">package</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">struts</span><span style="color: #0000ff">&gt;</span></div>
<span style="font-size: smaller; font-style: italic">清单9 src/struts.xml</span>
<p>以上XML片段值注意的是加入了&#8220;token&#8221;拦截器和&#8220;invalid.token&#8221;结果，因为&#8220;token&#8221;拦截器在会话token与请求token不一致时，将会直接返回&#8220;invalid.token&#8221;结果。</p>
<p>发布运行应用程序，在浏览器中键入：<a href="http://localhost:8080/Struts2_CoolTags/token.jsp">http://localhost:8080/Struts2_CoolTags/token.jsp</a>，出现如下图所示页面：</p>
<p><img alt="正常显示的token.jsp页面" src="http://www.blogjava.net/images/blogjava_net/max/22548/r_token1.gif" /><br />
<span style="font-size: smaller; font-style: italic">清单10 正常显示的token.jsp页面</span></p>
<p>随便填点东西并提交页面，一切正常返回以上页面，然后按&#8220;F5&#8221;刷新页面，在弹出的对话框中点击&#8220;Retry&#8221;，出现如下图所示页面：</p>
<p><img alt="重复提交出错显示" src="http://www.blogjava.net/images/blogjava_net/max/22548/r_token2.gif" /><br />
<span style="font-size: smaller; font-style: italic">清单11 重复提交出错显示</span></p>
<h2>4、&lt;s:datetimepicker /&gt;、&lt;s:optiontransferselect /&gt;和&lt;s:updownselect /&gt;</h2>
<p>这几个标志的使用相对简单，所以我想小举一例即可，以下是JSP的代码：</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"><span style="color: #0000ff">&lt;!</span><span style="color: #ff00ff">DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">html </span><span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="http://www.w3.org/1999/xhtml"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">head</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">title</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">Struts 2 Cool Tags - Others</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">title</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:head </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">head</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">body</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"> &nbsp; &nbsp;<br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">h2</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">Others</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">h2</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:form </span><span style="color: #ff0000">action</span><span style="color: #0000ff">="Store"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:datetimepicker </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="birthday"</span><span style="color: #ff0000"> label</span><span style="color: #0000ff">="Birthday"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:updownselect<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #ff0000">label </span><span style="color: #0000ff">= "Favourite Countries"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list</span><span style="color: #0000ff">="#{'england':'England', 'america':'America', 'germany':'Germany'}"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name</span><span style="color: #0000ff">="prioritisedFavouriteCountries"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; headerKey</span><span style="color: #0000ff">="-1"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; headerValue</span><span style="color: #0000ff">="--- Please Order Them Accordingly ---"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; emptyOption</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:optiontransferselect &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #ff0000">label</span><span style="color: #0000ff">="Favourite Cartoons Characters"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name</span><span style="color: #0000ff">="leftSideCartoonCharacters"</span><span style="color: #ff0000">&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; leftTitle</span><span style="color: #0000ff">="Left Title"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rightTitle</span><span style="color: #0000ff">="Right Title"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list</span><span style="color: #0000ff">="{'Popeye', 'He-Man', 'Spiderman'}"</span><span style="color: #ff0000">&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; multiple</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; headerKey</span><span style="color: #0000ff">="headerKey"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; headerValue</span><span style="color: #0000ff">="--- Please Select ---"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; emptyOption</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doubleList</span><span style="color: #0000ff">="{'Superman', 'Mickey Mouse', 'Donald Duck'}"</span><span style="color: #ff0000">&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doubleName</span><span style="color: #0000ff">="rightSideCartoonCharacters"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doubleHeaderKey</span><span style="color: #0000ff">="doubleHeaderKey"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doubleHeaderValue</span><span style="color: #0000ff">="--- Please Select ---"</span><span style="color: #ff0000">&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doubleEmptyOption</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doubleMultiple</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp; &nbsp; </span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:form</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">body</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">html</span><span style="color: #0000ff">&gt;</span></div>
<span style="font-size: smaller; font-style: italic">清单12 WebContent\others.jsp页面</span>
<p>发布运行应用程序，在浏览器中键入：<a href="http://localhost:8080/Struts2_CoolTags/others.jsp">http://localhost:8080/Struts2_CoolTags/others.jsp</a>，出现如下图所示页面：</p>
<p><a href="http://www.blogjava.net/images/blogjava_net/max/22548/o_others.gif"><img alt="点击查看大图" src="http://www.blogjava.net/images/blogjava_net/max/22548/r_others.gif" /></a><br />
<span style="font-size: smaller; font-style: italic">清单13 其它表单标志页面</span></p>
<h2>总结</h2>
<p>Struts 2在标志上的确比Struts 1.x丰富了许多，同时模板机制也给程序员带来不少方便（如果你不太喜欢个性化的风格）。另外，Struts 2还有一些AJAX（如<a title="autocompleter" href="http://www.blogjava.net/max/admin/autocompleter.html">&lt;s: autocompleter /&gt;</a>等）的标志和非表单的UI标志（如<a href="http://cwiki.apache.org/WW/tree.html">&lt;s: tree /&gt;</a>等），我会在以后的文章中讲述其使用。</p>
<br />
原作者:http://www.blogjava.net/max/archive/2007/05/18/118442.html
<img src ="http://www.blogjava.net/i369/aggbug/183622.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/i369/" target="_blank">芦苇</a> 2008-03-04 10:30 <a href="http://www.blogjava.net/i369/articles/183622.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转换器（Converter）——Struts 2.0中的魔术师(Struts2中数据批量保存)[转别人的]</title><link>http://www.blogjava.net/i369/articles/183607.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Tue, 04 Mar 2008 01:25:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/183607.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/183607.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/183607.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/183607.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/183607.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转换器（Converter）——Struts 2.0中的魔术师 在我已往的Struts 1.x项目经验中，有个问题不时的出现——在创建FormBean时，对于某个属性到底应该用String还是其它类型？开发Web应用程序与开发传统桌面应用程序不同，Web应用程序实际上是分布个不同的主机（当然也可以同一个主机，不过比较少见）上的两个进程之间互交。这种互交建立在HTTP之上，它们互相传递是都是...&nbsp;&nbsp;<a href='http://www.blogjava.net/i369/articles/183607.html'>阅读全文</a><img src ="http://www.blogjava.net/i369/aggbug/183607.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/i369/" target="_blank">芦苇</a> 2008-03-04 09:25 <a href="http://www.blogjava.net/i369/articles/183607.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts 1.x中批量封装对象</title><link>http://www.blogjava.net/i369/articles/183603.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Tue, 04 Mar 2008 01:19:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/183603.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/183603.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/183603.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/183603.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/183603.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Struts 1.x中批量封装对象 在我早前的文章《转换器（Converter）——Struts 2.0中的魔术师》（以下简称为《转》）中，提及在Struts 1.x中实现批量封装对象，并不是一件容易的事，这需要一些技巧。昨天，有一位同事又和我讨论起这个问题，所以鉴于此场景（scenario）较为普遍，我决定写一篇有关的文章。 应用场景本文使用《转》中的最后一个例子作为应用场景，即是批...&nbsp;&nbsp;<a href='http://www.blogjava.net/i369/articles/183603.html'>阅读全文</a><img src ="http://www.blogjava.net/i369/aggbug/183603.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/i369/" target="_blank">芦苇</a> 2008-03-04 09:19 <a href="http://www.blogjava.net/i369/articles/183603.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts2 strus.xml中result类型及含义</title><link>http://www.blogjava.net/i369/articles/169286.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Fri, 21 Dec 2007 05:04:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/169286.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/169286.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/169286.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/169286.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/169286.html</trackback:ping><description><![CDATA[<p style="text-indent: 2em">一个提交到服务器的处理通常可以分为两个阶段，第一个阶段查询服务器状态（查询或者更新数据库），第二个阶段选择一个合适的结果页面其返回给用户（这里要讲的Result的内容）。</p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">Struts2提供了对不同种类返回结果的支持，常见的有JSP，FreeMarker，Velocity等。</p>
<p style="text-indent: 2em">Struts2支持的不同类型的返回结果为：</p>
<p style="text-indent: 2em">
<table cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td valign="top" width="210">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">名字</p>
            </td>
            <td valign="top" width="366">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">说明</p>
            </td>
        </tr>
        <tr>
            <td valign="top" width="210">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">Chain Result</p>
            </td>
            <td valign="top" width="366">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">用来处理Action链</p>
            </td>
        </tr>
        <tr>
            <td valign="top" width="210">
            <p style="text-indent: 2em">Dispatcher Result</p>
            </td>
            <td valign="top" width="366">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">用来转向页面，通常处理JSP</p>
            </td>
        </tr>
        <tr>
            <td valign="top" width="210">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">FreeMarker Result</p>
            </td>
            <td valign="top" width="366">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">处理FreeMarker模板</p>
            </td>
        </tr>
        <tr>
            <td valign="top" width="210">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">HttpHeader Result</p>
            </td>
            <td valign="top" width="366">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">用来控制特殊的Http行为</p>
            </td>
        </tr>
        <tr>
            <td valign="top" width="210">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">Redirect Result</p>
            </td>
            <td valign="top" width="366">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">重定向到一个URL</p>
            </td>
        </tr>
        <tr>
            <td valign="top" width="210">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">Redirect Action Result</p>
            </td>
            <td valign="top" width="366">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">重定向到一个Action</p>
            </td>
        </tr>
        <tr>
            <td valign="top" width="210">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">&nbsp;Stream Result</p>
            </td>
            <td valign="top" width="366">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">向浏览器发送InputSream对象，通常用来处理文件下载</p>
            </td>
        </tr>
        <tr>
            <td valign="top" width="210">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">Velocity Result</p>
            </td>
            <td valign="top" width="366">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">处理Velocity模板</p>
            </td>
        </tr>
        <tr>
            <td valign="top" width="210">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">XLS Result</p>
            </td>
            <td valign="top" width="366">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">处理XML/XLST模板</p>
            </td>
        </tr>
        <tr>
            <td valign="top" width="210">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">PlainText Result</p>
            </td>
            <td valign="top" width="366">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">显示原始文件内容，例如文件源代码</p>
            </td>
        </tr>
        <tr>
            <td valign="top" width="210">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">S2PLUGINS:Tiles Result</p>
            </td>
            <td valign="top" width="366">
            <p>&nbsp;</p>
            <p style="text-indent: 2em">结合Tile使用</p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p style="text-indent: 2em">另外第三方的Result类型还包括JasperReports Plugin，专门用来处理JasperReport类型的报表输出。</p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">在struts-default.xml文件中已经有了对于所有类型Result的定义：</p>
<p style="text-indent: 2em">&lt;result-types&gt;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &lt;result-type name="chain" </p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="com.opensymphony.xwork2.ActionChainResult"/&gt;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &lt;result-type name="dispatcher" </p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.apache.struts2.dispatcher.ServletDispatcherResult" </p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default="true"/&gt;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &lt;result-type name="freemarker" </p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.apache.struts2.views.freemarker.FreemarkerResult"/&gt;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &lt;result-type name="httpheader" </p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.apache.struts2.dispatcher.HttpHeaderResult"/&gt;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &lt;result-type name="redirect" </p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.apache.struts2.dispatcher.ServletRedirectResult"/&gt;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &lt;result-type name="redirectAction" </p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/&gt;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &lt;result-type name="stream" </p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.apache.struts2.dispatcher.StreamResult"/&gt;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &lt;result-type name="velocity" </p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.apache.struts2.dispatcher.VelocityResult"/&gt;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &lt;result-type name="xslt" </p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.apache.struts2.views.xslt.XSLTResult"/&gt;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &lt;result-type name="plainText" </p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.apache.struts2.dispatcher.PlainTextResult" /&gt;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &lt;!-- Deprecated name form scheduled for removal in Struts 2.1.0. </p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The camelCase versions are preferred. See ww-1707 --&gt;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &lt;result-type name="redirect-action" </p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/&gt;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &lt;result-type name="plaintext" </p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.apache.struts2.dispatcher.PlainTextResult" /&gt;</p>
<p style="text-indent: 2em">&lt;/result-types&gt;</p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">从上述代码中可以看出在不指定Result类型的时候使用dispatcher类型。</p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">定义一个Result值，</p>
<p style="text-indent: 2em">&lt;result name="success" type="dispatcher"&gt;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &lt;param name="location"&gt;/ThankYou.jsp&lt;/param&gt;</p>
<p style="text-indent: 2em">&lt;/result&gt;</p>
<p style="text-indent: 2em">由于type默认值是dispatcher，所以这里不需要定义，另外name的默认值为success所以这里也不需要定义。</p>
<p style="text-indent: 2em">上述代码可以简写为：</p>
<p style="text-indent: 2em">&lt;result&gt;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; &lt;param name="location"&gt;/ThankYou.jsp&lt;/param&gt;</p>
<p style="text-indent: 2em">&lt;/result&gt;</p>
<p style="text-indent: 2em">另外location参数也可以直接卸载result标签内部，所以上述代码的最简单的写法为：</p>
<p style="text-indent: 2em">&lt;result&gt;/ThankYou.jsp&lt;/result&gt;</p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">我们也可以定义多个不同的Result</p>
<p style="text-indent: 2em">&lt;action name="Hello"&gt;</p>
<p style="text-indent: 2em">&nbsp;&lt;result&gt;/hello/Result.jsp&lt;/result&gt;</p>
<p style="text-indent: 2em">&nbsp;&lt;result name="error"&gt;/hello/Error.jsp&lt;/result&gt;</p>
<p style="text-indent: 2em">&nbsp;&lt;result name="input"&gt;/hello/Input.jsp&lt;/result&gt;</p>
<p style="text-indent: 2em">&lt;/action&gt;</p>
<p style="text-indent: 2em">上述代码的含义为，名字为Hello的Action有三个返回结果，并且都是dispatcher类型（默认类型），这三个返回值的名字分别为success（默认值），error，input，对应的页面的路径分别为/hello/Result.jsp，/hello/Error.jsp，/hello/Input.jsp。</p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">有些时候我们需要一个定义在全局的Result，这个时候我们可以在package内部定义全局的Result，例如：</p>
<p style="text-indent: 2em">&lt;global-results&gt;</p>
<p style="text-indent: 2em">&nbsp;&lt;result name="error"&gt;/Error.jsp&lt;/result&gt;</p>
<p style="text-indent: 2em">&nbsp;&lt;result name="invalid.token"&gt;/Error.jsp&lt;/result&gt;</p>
<p style="text-indent: 2em">&nbsp;&lt;result name="login" type="redirect-action"&gt;Logon!input&lt;/result&gt;</p>
<p style="text-indent: 2em">&lt;/global-results&gt;</p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">动态返回结果</p>
<p style="text-indent: 2em">有些时候，只有当Action执行完璧的时候我们才知道要返回哪个结果，这个时候我们可以在Action内部定义一个属性，这个属性用来存储Action执行完璧之后的Result值，例如：</p>
<p style="text-indent: 2em">private String nextAction;&nbsp;</p>
<p style="text-indent: 2em">public String getNextAction() {</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp; return nextAction;</p>
<p style="text-indent: 2em">}</p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">在strutx.xml配置文件中，我们可以使用${nextAction}来引用到Action中的属性，通过${nextAction}表示的内容来动态的返回结果，例如：</p>
<p style="text-indent: 2em">&lt;action name="fragment" class="FragmentAction"&gt;</p>
<p style="text-indent: 2em">&nbsp;&lt;result name="next" type="redirect-action"&gt;${nextAction}&lt;/result&gt;</p>
<p style="text-indent: 2em">&lt;/action&gt;</p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">上述Action的execute方法返回next的时候，还需要根据nextAction的属性来判断具体定位到哪个Action。</p>
<p style="text-indent: 2em">&nbsp;</p>
<p style="text-indent: 2em">在strutx.xml配置文件中，我们可以使用method=""来设置调用类的哪个方法，这样就可以在一个JAVA类中使用不同的方法来实现不同的功能,就无需每个功能写一类了,例如：</p>
<p style="text-indent: 2em">&lt;action name="fragment" class="FragmentAction" method="add"&gt;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;result&gt;/success.jsp&lt;/result&gt;</p>
<p style="text-indent: 2em">&lt;/action&gt;</p>
<img src ="http://www.blogjava.net/i369/aggbug/169286.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/i369/" target="_blank">芦苇</a> 2007-12-21 13:04 <a href="http://www.blogjava.net/i369/articles/169286.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts2拦截器的使用 (详解)</title><link>http://www.blogjava.net/i369/articles/162407.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Thu, 22 Nov 2007 08:58:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/162407.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/162407.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/162407.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/162407.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/162407.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 如何使用struts2拦截器，或者自定义拦截器。特别注意，在使用拦截器的时候，在Action里面必须最后一定要引用struts2自带的拦截器缺省堆栈defaultStack,如下(这里我是引用了struts2自带的checkbox拦截器)：&lt;interceptor-ref name="checkbox"&gt;&nbsp; &lt;param name="uncheckedValue...&nbsp;&nbsp;<a href='http://www.blogjava.net/i369/articles/162407.html'>阅读全文</a><img src ="http://www.blogjava.net/i369/aggbug/162407.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/i369/" target="_blank">芦苇</a> 2007-11-22 16:58 <a href="http://www.blogjava.net/i369/articles/162407.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts 2中的OGNL [转]</title><link>http://www.blogjava.net/i369/articles/162409.html</link><dc:creator>芦苇</dc:creator><author>芦苇</author><pubDate>Thu, 22 Nov 2007 08:58:00 GMT</pubDate><guid>http://www.blogjava.net/i369/articles/162409.html</guid><wfw:comment>http://www.blogjava.net/i369/comments/162409.html</wfw:comment><comments>http://www.blogjava.net/i369/articles/162409.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/i369/comments/commentRss/162409.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/i369/services/trackbacks/162409.html</trackback:ping><description><![CDATA[<p>Struts 2中的OGNL <br />
本人是一个EL（Expression Language，以下译为表达式语言）的支持者。因为我对&lt;% %&gt;写法极为反感，忘记了在那本书上看到的一句话——&#8220;使用标志（Tag）的一个目的就是避免在JSP页面中出现过多的&lt;%%&gt;的语句，使页面与后台代码分离。&#8221;</p>
<p>表达式语言主要有以下几大好处：</p>
<p>避免(MyType) request.getAttribute()和myBean.getMyProperty()之类的语句，使页面更简洁； <br />
支持运算符（如+-*/），比普通的标志具有更高的自由度和更强的功能； <br />
简单明了地表达代码逻辑，使用代码更可读与便于维护。 <br />
Struts 2中的表达式语言<br />
Struts 2支持以下几种表达式语言：</p>
<p>OGNL（Object-Graph Navigation Language），可以方便地操作对象属性的开源表达式语言； <br />
JSTL（JSP Standard Tag Library），JSP 2.0集成的标准的表达式语言； <br />
Groovy，基于Java平台的动态语言，它具有时下比较流行的动态语言（如Python、Ruby和Smarttalk等）的一些起特性； <br />
Velocity，严格来说不是表达式语言，它是一种基于Java的模板匹配引擎，具说其性能要比JSP好。 <br />
Struts 2默认的表达式语言是OGNL，原因是它相对其它表达式语言具有下面几大优势：</p>
<p>支持对象方法调用，如xxx.doSomeSpecial()； <br />
支持类静态的方法调用和值访问，表达式的格式为@[类全名（包括包路径）]@[方法名 |&nbsp;&nbsp; 值名]，例如：@java.lang.String@format('foo %s', 'bar')或@tutorial.MyConstant@APP_NAME； <br />
支持赋值操作和表达式串联，如price=100, discount=0.8, calculatePrice()，这个表达式会返回80； <br />
访问OGNL上下文（OGNL context）和ActionContext； <br />
操作集合对象。 <br />
OGNL的用法<br />
OGNL是通常要结合Struts 2的标志一起使用，如&lt;s:property value="xx" /&gt;等。大家经常遇到的问题是#、%和$这三个符号的使用。下面我想通过例子讲述这个问题：</p>
<p>首先新建名为Struts2_OGNL的Web工程，配置开发环境。之前很多朋友在使用Struts 2的过程中都遇到乱码问题。当然乱码问题由来已久，而且涉及多方面的知识，所以并非三言两语可以说明白，而且互联网上也已经有很多这方便的文章，大家可以Google一下。不过，如果你在开发的过程，多注意一下，避免乱码问题也不难。乱码多数是由于编码与解码所使用的方式不同造成的，所以我建议大家将编码方式都设为&#8220;utf-8&#8221;，如&lt;%@&nbsp;&nbsp; page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %&gt;。另外，在配置web.xml时使用ActionContextCleanUp过滤器（Filter），如下面代码所示：</p>
<p>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
&lt;web-app id="WebApp_9" version="2.4"<br />
&nbsp;&nbsp;&nbsp;&nbsp; xmlns="<a href="http://java.sun.com/xml/ns/j2ee">http://java.sun.com/xml/ns/j2ee</a>"<br />
&nbsp;&nbsp;&nbsp;&nbsp; xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"<br />
&nbsp;&nbsp;&nbsp;&nbsp; xsi:schemaLocation="<a href="http://java.sun.com/xml/ns/j2ee">http://java.sun.com/xml/ns/j2ee</a> <a href="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd</a>"&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;display-name&gt;Struts 2 OGNL&lt;/display-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;struts-cleanup&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; org.apache.struts2.dispatcher.ActionContextCleanUp<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/filter-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/filter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;struts-cleanup&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/filter-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;struts2&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; org.apache.struts2.dispatcher.FilterDispatcher<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/filter-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/filter&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;struts2&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/filter-mapping&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;welcome-file-list&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;welcome-file&gt;index.html&lt;/welcome-file&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/welcome-file-list&gt;</p>
<p>&lt;/web-app&gt;清单1 WebContent/WEB-INF/web.xml <br />
&#8220;#&#8221;主要有三种用途：</p>
<p>访问OGNL上下文和Action上下文，#相当于ActionContext.getContext()；下表有几个ActionContext中有用的属性：&nbsp;&nbsp; 名称 作用 例子 <br />
parameters 包含当前HTTP请求参数的Map #parameters.id[0]作用相当于request.getParameter("id") <br />
request 包含当前HttpServletRequest的属性（attribute)的Map #request.userName相当于request.getAttribute("userName") <br />
session 包含当前HttpSession的属性（attribute）的Map #session.userName相当于session.getAttribute("userName") <br />
application 包含当前应用的ServletContext的属性（attribute）的Map #application.userName相当于application.getAttribute("userName") <br />
attr 用于按request &gt; session &gt; application顺序访问其属性（attribute） #attr.userName相当于按顺序在以上三个范围（scope）内读取userName属性，直到找到为止 </p>
<p>用于过滤和投影（projecting)集合，如books.{?#this.price&lt;100}； <br />
构造Map，如#{'foo1':'bar1', 'foo2':'bar2'}。 <br />
下面让我们它们的具体写法，首先是Action类代码：</p>
<p>package tutorial.action;</p>
<p>import java.util.LinkedList;<br />
import java.util.List;<br />
import java.util.Map;</p>
<p>import javax.servlet.ServletContext;<br />
import javax.servlet.http.HttpServletRequest;</p>
<p>import org.apache.struts2.interceptor.ServletRequestAware;<br />
import org.apache.struts2.interceptor.SessionAware;<br />
import org.apache.struts2.util.ServletContextAware;</p>
<p>import tutorial.model.Book;</p>
<p>import com.opensymphony.xwork2.ActionSupport;</p>
<p>public class OgnlAction extends ActionSupport implements ServletRequestAware, SessionAware, ServletContextAware&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp; private static final long serialVersionUID = 1L;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; private HttpServletRequest request;<br />
&nbsp;&nbsp;&nbsp;&nbsp; private Map&lt;String, String&gt; session;<br />
&nbsp;&nbsp;&nbsp;&nbsp; private ServletContext application;<br />
&nbsp;&nbsp;&nbsp;&nbsp; private List&lt;Book&gt; books;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; public void setServletRequest(HttpServletRequest request) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.request = request;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; @SuppressWarnings("unchecked")<br />
&nbsp;&nbsp;&nbsp;&nbsp; public void setSession(Map session) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.session = session;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; public void setServletContext(ServletContext application) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.application = application;<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; public List&lt;Book&gt; getBooks() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return books;<br />
&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; @Override<br />
&nbsp;&nbsp;&nbsp;&nbsp; public String execute() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request.setAttribute("userName", "Max From request");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; session.put("userName", "Max From session");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; application.setAttribute("userName", "Max From application");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; books = new LinkedList&lt;Book&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; books.add(new Book("978-0735619678", "Code Complete, Second Edition", 32.99));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; books.add(new Book("978-0596007867", "The Art of Project Management", 35.96));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; books.add(new Book("978-0201633610", "Design Patterns: Elements of Reusable Object-Oriented Software", 43.19));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; books.add(new Book("978-0596527341", "Information Architecture for the World Wide Web: Designing Large-Scale Web Sites", 25.19));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; books.add(new Book("978-0735605350", "Software Estimation: Demystifying the Black Art", 25.19));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return SUCCESS;<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
}清单2 src/tutorial/action/OgnlAction.java </p>
<p>以上代码分别在request、session和application的范围内添加&#8220;userName&#8221;属性，然后再在JSP页面使用OGNL将其取回。我还创建了Book对象的列表用于演示&#8220;用于过滤和投影（projecting)集合&#8221;的功能，至于Book的代码大家可以在我前一文章《在Struts 2中实现CRUD》看到。</p>
<p>下面是Ognl.jsp的代码，内容如下：</p>
<p>&lt;%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %&gt;<br />
&lt;%@ taglib prefix="s" uri="/struts-tags" %&gt;</p>
<p>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "<a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</a>"&gt;<br />
&lt;html xmlns="<a href="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>"&gt;<br />
&lt;head&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;title&gt;Struts OGNL Demo&lt;/title&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;h3&gt;访问OGNL上下文和Action上下文&lt;/h3&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;p&gt;parameters: &lt;s:property value="#parameters.userName" /&gt;&lt;/p&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;p&gt;request.userName: &lt;s:property value="#request.userName" /&gt;&lt;/p&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;p&gt;session.userName: &lt;s:property value="#session.userName" /&gt;&lt;/p&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;p&gt;application.userName: &lt;s:property value="#application.userName" /&gt;&lt;/p&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;p&gt;attr.userName: &lt;s:property value="#attr.userName" /&gt;&lt;/p&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;hr /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;h3&gt;用于过滤和投影（projecting)集合&