<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
	<channel>
		<title></title>
		<link>http://www.eoss.cn/blog/category//</link>
		<description>一个不安分的程序员对技术和商业的思考...</description>
		<copyright>Powered by SaBlog-X. Copyright (C) 2003-2009.</copyright>
		<generator>SaBlog-X Version Plus 2.0 Build 20090308</generator>
		<lastBuildDate>Fri, 12 Mar 2010 05:06:05 +0000</lastBuildDate>
		<ttl>30</ttl>
		<item>
			<guid>http://www.eoss.cn/blog/hibernate_ten_defect/</guid>
			<title>Hibernate的十大罪状</title>
			<author>shine</author>
			<description><![CDATA[乐在其中 ( http://www.eoss.cn/blog/ ) : <div class="postText">Hibernate确实功能强悍，但在易用性、性能上存在缺陷。如果团队中没有一个精通Hibernate的高手，不适合使用Hibernate。<br />
<br />
1.  复杂的实体状态<br />
3种实体状态的设计是种种复杂性问题的根源。在持久化状态下不需要save就自动同步到数据库既无必要又容易造成烦恼。<br />
2. Lazy  Load 与 Eager Load<br />
Lazy Load的概念听起来不错，用起来就不那么妙了，也直接导致产生了Open Session In  View这种妥协方案。此外，在domain类中定义的FetchType只针对get/load/loadAll有效，对Query是无效的，需要再次定义。<br />
3.  Open Session In View<br />
Lazy Load引发的一个有较多副作用的解决方案。<br />
4.  级联<br />
级联是一个很好很OO的概念，但往往增加了复杂度。<br />
5.  批量更新与缓存不一致<br />
Hibernate引入了一级缓存和二级缓存，提供了性能的同时带来了缓存一致性的问题。批量更新或者其他系统对数据库的更新容易造成缓存不一致。<br />
6.  配置繁琐<br />
Hibernate最初只能使用xml进行配置，后来终于引入了Annotation和CoC(约定优于配置)来简化配置，但这种变革并不彻底。Hibernate默认把userName映射userName，但实际开发中，把userName映射为user_name的情况更多些。<br />
7.  HQL<br />
HQL是一个类SQL对象查询语言，但正是因为HQL与SQL的相似性，往往容易造成混淆，同时HQL难以调试，本质创建了一种语言，增加学习成本。<br />
8.  太多的查询方案<br />
HQL、QBC、SQL，就不能统一点，简洁点？<br />
9. N+1次查询<br />
10.  性能问题<br />
<br />
总之，Hibernate立足于作一个完整的自动化的能够适应各种环境的ORM，因此带来了100%的复杂性。但我们实际需要的只是一个简单的能够以20%时间解决80%问题的框架，具有对象-关系映射，能自动生成SQL，能够让新手尽快工作就足够了，也许ActiveRecord是一个选择。</div>]]></description>
			<link>http://www.eoss.cn/blog/hibernate_ten_defect/</link>
			<category domain="http://www.eoss.cn/blog/category/java/">Java</category>
			<pubDate>2009-01-21 19:49</pubDate>
		</item>
		<item>
			<guid>http://www.eoss.cn/blog/java_server_framework/</guid>
			<title>Note: Java Server Framework</title>
			<author>shine</author>
			<description><![CDATA[乐在其中 ( http://www.eoss.cn/blog/ ) : <p>Apache MINA<br />
<a href="http://www.ibm.com/developerworks/cn/opensource/os-cn-apmina/?S_TACT=105AGX52&amp;S_CMP=techcsdn" target="_blank">http://www.ibm.com/developerworks/cn/opensource/os-cn-apmina/?S_TACT=105AGX52&amp;S_CMP=techcsdn</a><br />
<br />
Grizzly<br />
<a href="http://www.javaeye.com/news/4489-grizzly-1-9-released-new-twitter-demo" target="_blank">http://www.javaeye.com/news/4489-grizzly-1-9-released-new-twitter-demo</a><br />
<br />
Quick Server<br />
<a href="http://www.blogjava.net/calvin/archive/2006/08/12/63260.html" target="_blank">http://www.blogjava.net/calvin/archive/2006/08/12/63260.html</a></p>]]></description>
			<link>http://www.eoss.cn/blog/java_server_framework/</link>
			<category domain="http://www.eoss.cn/blog/category/java/">Java</category>
			<pubDate>2009-01-16 12:32</pubDate>
		</item>
		<item>
			<guid>http://www.eoss.cn/blog/play_case/</guid>
			<title>Play with Play! - 案例</title>
			<author>shine</author>
			<description><![CDATA[乐在其中 ( http://www.eoss.cn/blog/ ) : <p>abikenow <br />
<a href="http://www.abikenow.com/" target="_blank">http://www.abikenow.com</a><br />
分享和搜索自行车的iPhone应用<br />
<img src="http://www.playframework.org/manual/_media/contents/abikenow.png?cache=cache" alt="" /><br />
<br />
Shigeta website<br />
<a href="http://www.shigeta.fr/" target="_blank">http://www.shigeta.fr</a><br />
<img src="http://www.playframework.org/manual/_media/contents/shigeta1.png?cache=cache" alt="" /><br />
<br />
<img src="http://www.playframework.org/manual/_media/contents/shigeta2.png?cache=cache" alt="" /><br />
<br />
zebre<br />
企业内部管理系统，使用了JPA 、AJAX和Google charts API等技术。 <br />
<img src="http://www.playframework.org/manual/_media/contents/zebre1.png?cache=cache" alt="" /><br />
<br />
<img src="http://www.playframework.org/manual/_media/contents/zebre2.png?cache=cache" alt="" /><br />
<br />
<br />
B&amp;B media website<br />
<a href="http://www.bandbmedia.com/">http://www.bandbmedia.com</a><br />
<img src="http://www.playframework.org/manual/_media/contents/bbmedia1.png?cache=cache" alt="" /><br />
<br />
<img src="http://www.playframework.org/manual/_media/contents/bbmedia2.png?cache=cache" alt="" /><br />
zapps<br />
zapps提供了一个完整的协作平台，包括邮件、任务管理、日历、文档管理等功能。<br />
<img src="http://www.playframework.org/manual/_media/contents/zapp1.png?cache=cache" alt="" /><br />
<img src="http://www.playframework.org/manual/_media/contents/zapp2.png?cache=cache" alt="" /></p>]]></description>
			<link>http://www.eoss.cn/blog/play_case/</link>
			<category domain="http://www.eoss.cn/blog/category/java/">Java</category>
			<pubDate>2009-01-05 11:29</pubDate>
		</item>
		<item>
			<guid>http://www.eoss.cn/blog/play_sample/</guid>
			<title>Play with Play! - 应用实例</title>
			<author>shine</author>
			<description><![CDATA[乐在其中 ( http://www.eoss.cn/blog/ ) : <p>论坛<br />
涉及JPA、页面模板、控制器、Session、Flash、自定义404/403页面、安全、Email等<br />
<br />
<img src="http://www.playframework.org/manual/_media/contents/forum.png?cache=cache" alt="" /><br />
<br />
<a href="http://www.playframework.org/download/samples/sample-forum.zip">下载</a><br />
<br />
Blog<br />
涉及JPA、页面模板、控制器、Session、Flash、自定义404/403页面、安全等<br />
<br />
<img src="http://www.playframework.org/manual/_media/contents/blog.png?cache=cache" alt="" /><br />
<br />
<a href="http://www.playframework.org/download/samples/sample-blog.zip">下载</a><br />
<br />
多种模板类型<br />
Play!支持通过调用renderXXX方法输出json、html、xml、二进制等多种回复类型，如果只是调用render()方法，Play!会根据浏览器的需要选择不同的模板。<br />
<br />
<a href="http://www.taldius.net/%7Ejef/play/sample-json-xml.zip">下载</a><br />
<br />
Flex客户端<br />
Play!应用程序粘合Amazon ECS (e-commerce API)和Flex客户端的<br />
<br />
<img src="http://www.playframework.org/manual/_media/contents/demo_flex_play.png?cache=" alt="" /><br />
<br />
<a href="http://devcats3.s3.amazonaws.com/static/AmazonFlex_Play.zip">下载（Play!代码）</a><br />
<a href="http://devcats3.s3.amazonaws.com/static/AmazonFlex_Flex.zip">下载（Flex代码）</a></p>]]></description>
			<link>http://www.eoss.cn/blog/play_sample/</link>
			<category domain="http://www.eoss.cn/blog/category/java/">Java</category>
			<pubDate>2009-01-05 11:25</pubDate>
		</item>
		<item>
			<guid>http://www.eoss.cn/blog/validation_in_play/</guid>
			<title>Play with Play! - Validation</title>
			<author>shine</author>
			<description><![CDATA[乐在其中 ( http://www.eoss.cn/blog/ ) : <p>目前Play!没有集成验证功能，暂时可以使用下面两个验证框架作为替代：<br />
<br />
<a href="http://www.hibernate.org/412.html" target="_blank">Hibernate Validator</a><br />
<a href="http://oval.sourceforge.net/" target="_blank">OVal</a><br />
<br />
Play!开发团队有实现一个类似Hibernate Validator功能的验证框架的打算。</p>]]></description>
			<link>http://www.eoss.cn/blog/validation_in_play/</link>
			<category domain="http://www.eoss.cn/blog/category/java/">Java</category>
			<pubDate>2009-01-05 11:21</pubDate>
		</item>
		<item>
			<guid>http://www.eoss.cn/blog/grials1_1beta2/</guid>
			<title>Grails 1.1 Beta 2发布</title>
			<author>shine</author>
			<description><![CDATA[乐在其中 ( http://www.eoss.cn/blog/ ) : <p>Grails 1.1 Beta 2<span lang="ZH-CN" style="font-family: 宋体;">发布了，</span>Groovy 1.6 final<span lang="ZH-CN" style="font-family: 宋体;">和</span>Grails 1.1 final<span lang="ZH-CN" style="font-family: 宋体;">也越来越近，不过已经不是很感兴趣了。虽然对于</span>Java<span lang="ZH-CN" style="font-family: 宋体;">开发者来说，相比</span>Rails<span lang="ZH-CN" style="font-family: 宋体;">，</span>Grails<span lang="ZH-CN" style="font-family: 宋体;">更容易上手，但它并不成熟的。在论证</span> Grails<span lang="ZH-CN" style="font-family: 宋体;">的成熟度时，</span>Graema<span lang="ZH-CN" style="font-family: 宋体;">说：</span>&ldquo;<span lang="ZH-CN" style="font-family: 宋体;">你会把</span>Spring<span lang="ZH-CN" style="font-family: 宋体;">和</span>Hibernate<span lang="ZH-CN" style="font-family: 宋体;">看作风险吗？</span>&rdquo; Spring<span lang="ZH-CN" style="font-family: 宋体;">和</span>Hibernate<span lang="ZH-CN" style="font-family: 宋体;">确实不是风险，但</span>Grails<span lang="ZH-CN" style="font-family: 宋体;">对</span>Spring<span lang="ZH-CN" style="font-family: 宋体;">和</span>Hibernate<span lang="ZH-CN" style="font-family: 宋体;">的包装却是一个极大风险，</span>&ldquo;<span lang="ZH-CN" style="font-family: 宋体;">在种种危险中，最主要的一</span><span lang="ZH-CN" style="font-family: 宋体;">点是我们已经对底层框架的抽象太成功了，以至于有时会出现问题。</span>&rdquo;<span lang="ZH-CN" style="font-family: 宋体;">具体可以看看这个</span><a target="_blank" href="http://www.eoss.cn/blog/grails_notes_1/"><span lang="ZH-CN" style="font-family: 宋体;">例子</span></a><span lang="ZH-CN" style="font-family: 宋体;">。使用</span>Grails<span lang="ZH-CN" style="font-family: 宋体;">，不如使用</span>JRuby On Rails<span lang="ZH-CN" style="font-family: 宋体;">或者</span>Play!</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">不管怎么样下面介绍一下</span>1.1<span lang="ZH-CN" style="font-family: 宋体;">版本的新特性：</span><br />
<o:p></o:p></p>
<p class="MsoNormal"><b style=""><span style="font-size: 16pt;">GORM <o:p></o:p></span></b></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">更好的</span>GORM</b><b style=""><span lang="ZH-CN" style="font-family: 宋体;">事件</span><o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">之前</span>, GORM <span lang="ZH-CN" style="font-family: 宋体;">只支持</span> beforeInsert, beforeUpdate <span lang="ZH-CN" style="font-family: 宋体;">和</span>beforeDelete <span lang="ZH-CN" style="font-family: 宋体;">事件</span>, <span lang="ZH-CN" style="font-family: 宋体;">现增加了</span>afterInsert, afterUpdate <span lang="ZH-CN" style="font-family: 宋体;">和</span>afterDelete <span lang="ZH-CN" style="font-family: 宋体;">来完成图片操作</span></p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">基本类型集的持久化</span><o:p></o:p></b></p>
<p class="MsoNormal">GORM <span lang="ZH-CN" style="font-family: 宋体;">现在支持基本类型比如</span>String, Integer <span lang="ZH-CN" style="font-family: 宋体;">等使用一个连接表的持久化。</span></p>
<p class="MsoNormal">class &nbsp;Person&nbsp;{&nbsp;&nbsp; &nbsp;</p>
<p class="MsoNormal">static &nbsp;hasMany&nbsp;=&nbsp;[nicknames:String]&nbsp;</p>
<p class="MsoNormal">}&nbsp;&nbsp;</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal">class Person {<o:p><br type="_moz" />
</o:p></p>
<p class="MsoNormal"><span style="">&nbsp;&nbsp; </span>static hasMany = [nicknames:String]<o:p><br type="_moz" />
</o:p></p>
<p class="MsoNormal">}</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">对象的只读访问</span><o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">现在，持久化实例对象可以使用</span>read <span lang="ZH-CN" style="font-family: 宋体;">方法以只读状态被加载</span>:</p>
<p class="MsoNormal">def book = Book.read(1)</p>
<p class="MsoNormal"><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">默认的排列顺序</span><o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">现在，关联可以使用一个类级别声明的默认的排列顺序来排序</span>:</p>
<p class="MsoNormal">class Book {</p>
<p class="MsoNormal">&nbsp; String title</p>
<p class="MsoNormal">&nbsp; static mapping = {</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp; sort &quot;title&quot;</p>
<p class="MsoNormal">&nbsp; }</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">或在关联级别上</span>:</p>
<p class="MsoNormal">class Author {</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp; static hasMany = [books:Book]</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp; static mapping = {</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; books sort:&quot;title&quot;</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp; }</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">批处理</span><o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">现在</span>GORM <span lang="ZH-CN" style="font-family: 宋体;">支持使用</span>ORM DSL <span lang="ZH-CN" style="font-family: 宋体;">在类级别上配置批处理</span><span lang="ZH-CN" style="font-family: 宋体;">（</span>batch fetching <span lang="ZH-CN" style="font-family: 宋体;">）</span>( <span lang="ZH-CN" style="font-family: 宋体;">延迟加载的优化</span>):</p>
<p class="MsoNormal">class Book {</p>
<p class="MsoNormal">&nbsp; String title</p>
<p class="MsoNormal">&nbsp; static mapping = {</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp; batchSize 15</p>
<p class="MsoNormal">&nbsp; }</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">或在关联级别上</span>:</p>
<p class="MsoNormal">class Author {</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp; static hasMany = [books:Book]</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp; static mapping = {</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; books batchSize:15</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp; }</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal"><o:p><br type="_moz" />
</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">动态</span>Finders</b><b style=""><span lang="ZH-CN" style="font-family: 宋体;">的改进</span><o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">动态查询器的新后缀</span>InList <span lang="ZH-CN" style="font-family: 宋体;">可用：</span></p>
<p class="MsoNormal">def groovyBooks = Book.findByAuthorInList(['Dierk Koenig', 'Graeme Rocher'])</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">现在，</span>Dynamic finders <span lang="ZH-CN" style="font-family: 宋体;">也能查询缓存</span>:</p>
<p class="MsoNormal">def books = Book.findByTitle(&quot;Groovy in Action&quot;, [cache:true] )</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">可以使用悲观锁</span>:</p>
<p class="MsoNormal">def books = Book.findByTitle(&quot;Groovy in Action&quot;, [lock:true] )</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">单项的</span>One-to-many</b><b style=""><span lang="ZH-CN" style="font-family: 宋体;">遗留映射</span><o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">单项的</span>One-to-many<span lang="ZH-CN" style="font-family: 宋体;">关联关系可以使用</span>joinTable <span lang="ZH-CN" style="font-family: 宋体;">参数改变它们对底层数据库的映射</span>:</p>
<p class="MsoNormal">class Book {</p>
<p class="MsoNormal">&nbsp; String title</p>
<p class="MsoNormal">&nbsp; static belongsTo = Author</p>
<p class="MsoNormal">&nbsp; static hasMany = [authors:Author]</p>
<p class="MsoNormal">&nbsp; static mapping = {</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp; authors joinTable :[name:&quot;mm_author_books&quot;, key:'mm_book_id' ]</p>
<p class="MsoNormal">&nbsp; }</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal">class Author {</p>
<p class="MsoNormal">&nbsp; String name</p>
<p class="MsoNormal">&nbsp; static hasMany = [books:Book]</p>
<p class="MsoNormal">&nbsp; static mapping = {</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp; books joinTable:[name:&quot;mm_author_books&quot;, key:'mm_author_id']</p>
<p class="MsoNormal">&nbsp; }</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">增强枚举类型的支持</span><o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">现在，枚举类型使用</span>GORM <span lang="ZH-CN" style="font-family: 宋体;">调用的</span>getId <span lang="ZH-CN" style="font-family: 宋体;">（）方法来持久化枚举状态。</span></p>
<p class="MsoNormal">enum Country {</p>
<p class="MsoNormal">&nbsp;&nbsp; <st1:country-region w:st="on"><st1:place w:st="on">AUSTRIA</st1:place></st1:country-region>('at'),</p>
<p class="MsoNormal">&nbsp;&nbsp; UNITED_STATES('us'),</p>
<p class="MsoNormal">&nbsp;&nbsp; <st1:country-region w:st="on"><st1:place w:st="on">GERMANY</st1:place></st1:country-region>('de');</p>
<p class="MsoNormal">&nbsp;&nbsp; final String id</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp; Country(String id) { this.id = id }</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-size: 16pt; font-family: 宋体;">插件</span></b><b style=""><span style="font-size: 16pt;"><o:p></o:p></span></b></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">全局插件</span><o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">现在，安装插件可以给所有的应用程序共享</span>:</p>
<p class="MsoNormal">grails install-plugin webtest -global</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">多插件仓库</span><o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">现在，</span>Grails <span lang="ZH-CN" style="font-family: 宋体;">支持通过提供多插件仓库配置的能力</span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">使用</span>USER_HOME/.grails/settings.groovy <span lang="ZH-CN" style="font-family: 宋体;">文件或包含配置好的仓库详情的</span>grails-app/conf/BuildConfig.groovy <span lang="ZH-CN" style="font-family: 宋体;">文件。</span></p>
<p class="MsoNormal">grails.plugin.repos.discovery.myRepository=&quot;http://svn.codehaus.org/grails/trunk/grails-test-plugin-repo&quot;</p>
<p class="MsoNormal">grails.plugin.repos.distribution.myRepository=&quot;https://svn.codehaus.org/grails/trunk/grails-test-plugin-repo&quot;</p>
<p class="MsoNormal">Grails<span lang="ZH-CN" style="font-family: 宋体;">的插件命令如</span>list-plugin<span lang="ZH-CN" style="font-family: 宋体;">和</span>install-plugin<span lang="ZH-CN" style="font-family: 宋体;">会自动使用所有设置的插件仓库，发布一个插件到一个插件仓库可以是用下面的命令：</span></p>
<p class="MsoNormal">grails release-plugin -repository=myRepository</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">自动安装插件方案</span><o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">插件不再需要到</span>SVN <span lang="ZH-CN" style="font-family: 宋体;">检出，当应用程序第一次加载时，通过插件元数据会自动安装。</span><span lang="ZH-CN" style="font-family: 宋体;">另外</span>,<span lang="ZH-CN" style="font-family: 宋体;">插件的依赖关系问题已经解决了。</span></p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">插件的作用范围和环境</span><o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">现在，插件可以作用于环境或预置的构建范围内：</span></p>
<p class="MsoNormal">def environments = ['dev', 'test']</p>
<p class="MsoNormal">def scopes = [excludes:'war']</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">仅在那些环境中加载使用，而不打包到</span>WAR <span lang="ZH-CN" style="font-family: 宋体;">文件中。这使得产品使用时</span> &quot;development-only&quot; <span lang="ZH-CN" style="font-family: 宋体;">的插件不会被打包</span><span lang="ZH-CN" style="font-family: 宋体;">。</span></p>
<p class="MsoNormal"><br />
<o:p></o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-size: 16pt; font-family: 宋体;">测试</span></b><b style=""><span style="font-size: 16pt;"><o:p></o:p></span></b></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">测试框架</span><o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">现在，作为</span>1.0.x <span lang="ZH-CN" style="font-family: 宋体;">系列可用插件的新</span><a href="http://www.grails.org/Testing+Plugin"><span lang="ZH-CN" style="font-family: 宋体;">测试框架</span></a><span lang="ZH-CN" style="font-family: 宋体;">已集成到</span> Grails 1.1.</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">该测试框架增加了模拟所以普通类型包扩控制器，领域类，标签库和</span>url <span lang="ZH-CN" style="font-family: 宋体;">映射简写的行为，快速运行单元测试。</span></p>
<p class="MsoNormal">class SongTests extends grails.test.GrailsUnitTestCase {</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp; void testMinimumDuration() {</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mockDomain(Song)</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def song = new Song(duration: 0)</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assertFalse 'validation should have failed', song.validate()</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assertEquals &quot;min&quot;, song.errors.duration</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp; }</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-size: 16pt; font-family: 宋体;">数据绑定</span></b><b style=""><span style="font-size: 16pt;"><o:p></o:p></span></b></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">属性子集的数据绑定</span><o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">现在更容易对属性的自己和进行数据绑定。在之前的版本中你也许会使用</span>:</p>
<p class="MsoNormal">person.properties&nbsp;=&nbsp;params&nbsp;&nbsp;</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">这将会将</span>request<span lang="ZH-CN" style="font-family: 宋体;">中的所有变量绑定到</span>person<span lang="ZH-CN" style="font-family: 宋体;">中。如果你不想绑定所有的数据的话，你可以使用</span> bindData <span lang="ZH-CN" style="font-family: 宋体;">方法。现在你可以通过使用</span>subscript operator<span lang="ZH-CN" style="font-family: 宋体;">来绑定部分的变量</span>:</p>
<p class="MsoNormal">person.properties[&quot;firstName&quot;,&quot;lastName&quot;]&nbsp;=&nbsp;params&nbsp;&nbsp;</p>
<p class="MsoNormal">person.properties[&quot;firstName&quot;,&quot;lastName&quot;] = params</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">要取得</span>domain<span lang="ZH-CN" style="font-family: 宋体;">中的所有属性的一个子集也可以通过这样的方式：</span></p>
<p class="MsoNormal">person.properties[&quot;firstName&quot;,&quot;lastName&quot;].each&nbsp;{&nbsp;println&nbsp;it&nbsp;}&nbsp;</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">集合类型的数据绑定</span><o:p></o:p></b></p>
<p class="MsoNormal">Grails<span lang="ZH-CN" style="font-family: 宋体;">已经支持集合类型的数据绑定</span>,<span lang="ZH-CN" style="font-family: 宋体;">例如</span>list<span lang="ZH-CN" style="font-family: 宋体;">、</span>set<span lang="ZH-CN" style="font-family: 宋体;">和</span>map<span lang="ZH-CN" style="font-family: 宋体;">。</span></p>
<p class="MsoNormal">&lt;g:textField name=&quot;books[0].title&quot; value=&quot;the Stand&quot; /&gt;</p>
<p class="MsoNormal">&lt;g:textField name=&quot;books[1].title&quot; value=&quot;the Shining&quot; /&gt;</p>
<p class="MsoNormal">&lt;g:textField name=&quot;books[2].title&quot; value=&quot;Red Madder&quot; /&gt;</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-size: 16pt; font-family: 宋体;">脚手架</span></b><b style=""><span style="font-size: 16pt;"><o:p></o:p></span></b></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">模板和动态脚手架</span><o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">现在，动态脚手架使用通过</span>install-templates <span lang="ZH-CN" style="font-family: 宋体;">命令安装的模板。</span></p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">支持更多关联类型</span><o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">现在，</span>Scaffolding <span lang="ZH-CN" style="font-family: 宋体;">支持</span> many-to-many <span lang="ZH-CN" style="font-family: 宋体;">和单项的</span> one-to-many <span lang="ZH-CN" style="font-family: 宋体;">关联。</span></p>
<p class="MsoNormal"><img src="http://www.grails.org/images/1.1-beta2+Release+Notes/m2m_scaffolding.png" alt="" /><br />
<!--[if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600"
o:spt="75" o:preferrelative="t" path="m&#64;4&#64;5l&#64;4&#64;11&#64;9&#64;11&#64;9&#64;5xe" filled="f"
stroked="f">
<v:stroke joinstyle="miter" />
<v:formulas>
<v:f eqn="if lineDrawn pixelLineWidth 0" />
<v:f eqn="sum &#64;0 1 0" />
<v:f eqn="sum 0 0 &#64;1" />
<v:f eqn="prod &#64;2 1 2" />
<v:f eqn="prod &#64;3 21600 pixelWidth" />
<v:f eqn="prod &#64;3 21600 pixelHeight" />
<v:f eqn="sum &#64;0 0 1" />
<v:f eqn="prod &#64;6 1 2" />
<v:f eqn="prod &#64;7 21600 pixelWidth" />
<v:f eqn="sum &#64;8 21600 0" />
<v:f eqn="prod &#64;7 21600 pixelHeight" />
<v:f eqn="sum &#64;10 21600 0" />
</v:formulas>
<v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect" />
<o:lock v:ext="edit" aspectratio="t" />
</v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" alt="" style='width:287.25pt;
height:201pt'>
<v:imagedata src="file:///C:\TEMP\msohtml1\01\clip_image001.png" o:href="http://www.grails.org/images/1.1-beta2+Release+Notes/m2m_scaffolding.png" />
</v:shape><![endif]--><!--[if !vml]--></p>
<p class="MsoNormal"><br />
<!--[endif]--></p>
<p class="MsoNormal"><b style=""><span style="font-size: 16pt;">Groovy Server Pages <o:p></o:p></span></b></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">在</span>JSP</b><b style=""><span lang="ZH-CN" style="font-family: 宋体;">中支持</span>JSP</b><b style=""><span lang="ZH-CN" style="font-family: 宋体;">标签库</span><o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">现在，</span>GSP <span lang="ZH-CN" style="font-family: 宋体;">已经支持</span>JSP <span lang="ZH-CN" style="font-family: 宋体;">标签库复用的能力</span>:</p>
<p class="MsoNormal">&lt;%@ taglib prefix=&quot;fmt&quot; uri=&quot;http://java.sun.com/jsp/jstl/fmt&quot; %&gt;</p>
<p class="MsoNormal">&lt;fmt:formatNumber value=&quot;${10}&quot; pattern=&quot;.00&quot;/&gt;</p>
<p class="MsoNormal">JSP <span lang="ZH-CN" style="font-family: 宋体;">标签也可以像正常的</span>GSP <span lang="ZH-CN" style="font-family: 宋体;">标签一样调用</span>:</p>
<p class="MsoNormal">&lt;%@ taglib prefix=&quot;fmt&quot; uri=&quot;http://java.sun.com/jsp/jstl/fmt&quot; %&gt;</p>
<p class="MsoNormal">${fmt.formatNumber(value:10, pattern:&quot;.00&quot;)}</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-size: 16pt; font-family: 宋体;">工程基本结构</span></b><b style=""><span style="font-size: 16pt;"><o:p></o:p></span></b></p>
<p class="MsoNormal"><b style="">Maven </b><b style=""><span lang="ZH-CN" style="font-family: 宋体;">集成</span>&nbsp; <o:p></o:p></b></p>
<p class="MsoNormal">Grails 1.1 <span lang="ZH-CN" style="font-family: 宋体;">缘自和</span> Maven plugin <span lang="ZH-CN" style="font-family: 宋体;">和</span>archetype <span lang="ZH-CN" style="font-family: 宋体;">的关联，允许你使用</span>Maven <span lang="ZH-CN" style="font-family: 宋体;">更容易的构建</span>Grails <span lang="ZH-CN" style="font-family: 宋体;">工程。根据操作指南</span><a href="http://www.grails.org/Maven+Integration">here</a><span lang="ZH-CN" style="font-family: 宋体;">或使用原型来创建一个新的</span>Grails <span lang="ZH-CN" style="font-family: 宋体;">工程</span>, <span lang="ZH-CN" style="font-family: 宋体;">或运行</span>:</p>
<p class="MsoNormal">mvn grails:create-pom</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">来为已有工程创建一个</span>Maven POM.</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">环境及元数据</span>API&nbsp;&nbsp; <o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">使用新</span> API <span lang="ZH-CN" style="font-family: 宋体;">来访问当前环境</span>:</p>
<p class="MsoNormal">import grails.util.Environment</p>
<p class="MsoNormal">...</p>
<p class="MsoNormal">switch(Environment.current) {</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Environment.DEVELOPMENT:</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; configureForDevelopment()</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case Environment.PRODUCTION:</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; configureForProduction()</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">当然也有一个易于访问应用程序元数据的新类：</span></p>
<p class="MsoNormal">def metadata = grails.util.Metadata.current</p>
<p class="MsoNormal">println metadata.applicationName</p>
<p class="MsoNormal">println metadata.applicationVersion</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style="">Log4j DSL&nbsp;&nbsp; <o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">新的</span> Log4j DSL <span lang="ZH-CN" style="font-family: 宋体;">用于替换以前</span>Log4j <span lang="ZH-CN" style="font-family: 宋体;">配置的方式</span>:</p>
<p class="MsoNormal">log4j = {</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp; error&nbsp; 'org.codehaus.groovy.grails.web.servlet',&nbsp; //&nbsp; controllers</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'org.codehaus.groovy.grails.web.pages' //&nbsp; GSP</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp; warn&nbsp;&nbsp; 'org.mortbay.log'</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">详见</span>user guide <span lang="ZH-CN" style="font-family: 宋体;">中</span>Log4j DSL <span lang="ZH-CN" style="font-family: 宋体;">全部文档。</span></p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">灵活的构建配置</span><o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">新的</span> grails-app/conf/BuildConfig.groovy <span lang="ZH-CN" style="font-family: 宋体;">文件可用，它允许你配置不同层面的</span>Grails <span lang="ZH-CN" style="font-family: 宋体;">构建输出路径和服务器使用插件的解决方案：</span></p>
<p class="MsoNormal">grails.work.dir=&quot;/tmp/work&quot;</p>
<p class="MsoNormal">grails.plugins.dir=&quot;/usr/local/grails/plugins&quot;</p>
<p class="MsoNormal">grails.project.test.reports.dir=&quot;/usr/local/grails/test-reports&quot;</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">非交互模式</span>&nbsp; <o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">现在，</span>Grails <span lang="ZH-CN" style="font-family: 宋体;">支持一种</span>--non-interactive flag <span lang="ZH-CN" style="font-family: 宋体;">，须键入到命令行，目的是关闭用户提示</span>:</p>
<p class="MsoNormal">grails run-app --non-interactive</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">这对服务器持续集成是有帮助的。</span></p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-family: 宋体;">加密数据源</span>&nbsp; <o:p></o:p></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">现在，数据源密码可以使用已提供的编码类来加密</span>:</p>
<p class="MsoNormal">dataSource {</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; username = &quot;foo&quot;</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; password = &quot;438uodf9s872398783r&quot;</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; passwordEncryptionCodec=&quot;my.company.encryption.BlowfishCodec&quot;</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">支持的编码使用</span> Grails' <span lang="ZH-CN" style="font-family: 宋体;">现存的编码机制。</span></p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b style=""><span lang="ZH-CN" style="font-size: 16pt; font-family: 宋体;">升级备注</span></b><b style=""><span style="font-size: 16pt;"><o:p></o:p></span></b></p>
<p class="MsoNormal">Grails 1.1 <span lang="ZH-CN" style="font-family: 宋体;">有很多改变，但大多是向后兼容</span>1.0.x <span lang="ZH-CN" style="font-family: 宋体;">系列的。如果有问题请报告。升级时，以下是已知需要注意的问题列表：</span></p>
<p class="MsoNormal">Plugins <span lang="ZH-CN" style="font-family: 宋体;">不保存在你的</span> USER_HOME <span lang="ZH-CN" style="font-family: 宋体;">路径下</span>. <span lang="ZH-CN" style="font-family: 宋体;">你需要重写安装插件或运行</span>:</p>
<p class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; grails -Dgrails.plugins.dir=./plugins run-app</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">现在枚举类型已经被映射到数据库，使用字符串值而不是原始默认的。</span></p>
<p class="MsoNormal">jsession id <span lang="ZH-CN" style="font-family: 宋体;">默认已无效</span>. <span lang="ZH-CN" style="font-family: 宋体;">详见</span><a href="http://jira.codehaus.org/browse/GRAILS-3364">GRAILS-3364</a></p>
<p class="MsoNormal">GSP <span lang="ZH-CN" style="font-family: 宋体;">空白符处理已经变好很多了，比以前有更多空白符</span>. <span lang="ZH-CN" style="font-family: 宋体;">详见</span><a href="http://jira.codehaus.org/browse/GRAILS-3277">GRAILS-3277</a></p>
<p class="MsoNormal">grails.testing.reports.destDir <span lang="ZH-CN" style="font-family: 宋体;">配置选项已被替代为</span>grails.project.test.reports.dir</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">现在，</span>PreInit.groovy <span lang="ZH-CN" style="font-family: 宋体;">改为</span>BuildConfig.groovy</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">控制器中的</span>allowedMethod <span lang="ZH-CN" style="font-family: 宋体;">属性被标识为</span>static <span lang="ZH-CN" style="font-family: 宋体;">。非</span> static <span lang="ZH-CN" style="font-family: 宋体;">版本不推荐使用，尽管它仍然起作用并在控制台产生信息。</span><o:p><br type="_moz" />
</o:p></p>
<p class="MsoNormal">Grails1.0<span lang="ZH-CN" style="font-family: 宋体;">的</span><a target="_blank" href="http://www.infoq.com/cn/news/2008/02/grails-1.0-released"><span lang="ZH-CN" style="font-family: 宋体;">这篇文章</span></a><span lang="ZH-CN" style="font-family: 宋体;">也可以作为参考。</span></p>]]></description>
			<link>http://www.eoss.cn/blog/grials1_1beta2/</link>
			<category domain="http://www.eoss.cn/blog/category/java/">Java</category>
			<pubDate>2008-12-26 11:03</pubDate>
		</item>
		<item>
			<guid>http://www.eoss.cn/blog/five_cool_functions_in_play/</guid>
			<title>Play with Play! - Play!最酷的5个功能</title>
			<author>shine</author>
			<description><![CDATA[乐在其中 ( http://www.eoss.cn/blog/ ) : <p><span lang="ZH-CN" style="font-family: 宋体;">本文通过</span>5<span lang="ZH-CN" style="font-family: 宋体;">个例子展示了</span>Play!<span lang="ZH-CN" style="font-family: 宋体;">框架背后的哲学。</span><o:p> </o:p></p>
<p class="MsoNormal"><b><span style=""><span lang="ZH-CN" style="font-family: 宋体;">1.绑定</span>HTTP</span><span style=""><span lang="ZH-CN" style="font-family: 宋体;">参数到</span>Java</span><span style=""><span lang="ZH-CN" style="font-family: 宋体;">方法</span></span></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">通过在</span>Java<span lang="ZH-CN" style="font-family: 宋体;">方法中定义和</span>HTTP<span lang="ZH-CN" style="font-family: 宋体;">参数同名的参数就可以方便的取得</span>HTTP<span lang="ZH-CN" style="font-family: 宋体;">中的参数值。</span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">例如：</span></p>
<p class="MsoNormal">/articles/archive?date=08/01/08&amp;page=2</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">你可以通过定义方法参数来获取</span>date<span lang="ZH-CN" style="font-family: 宋体;">和</span>page<span lang="ZH-CN" style="font-family: 宋体;">的值：</span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br>
<br>
Code highlighting produced by Actipro CodeHighlighter (freeware)<br>
http://www.CodeHighlighter.com/<br>
<br>
--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;archive(Date&nbsp;date,&nbsp;Integer&nbsp;page)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;List</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">Article</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;articles&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;Articles.fromArchive(date,&nbsp;page);<br />
&nbsp;&nbsp;&nbsp;&nbsp;render(articles);<br />
}</span></div>
<br />
</span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">也可以直接绑定到类：</span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br>
<br>
Code highlighting produced by Actipro CodeHighlighter (freeware)<br>
http://www.CodeHighlighter.com/<br>
<br>
--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;Person&nbsp;{<br />
&nbsp;&nbsp;String&nbsp;name;<br />
&nbsp;&nbsp;Integer&nbsp;age;<br />
}<br />
<br />
</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;add(Person&nbsp;p)&nbsp;{<br />
&nbsp;&nbsp;p.save();<br />
}<br />
</span></div>
</span></p>
<div class="postText">
<link rel="File-List" href="file:///C:%5CTEMP%5Cmsohtml1%5C01%5Cclip_filelist.xml" /><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:PunctuationKerning />
<w:ValidateAgainstSchemas />
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:BreakWrappedTables />
<w:SnapToGridInCell />
<w:WrapTextWithPunct />
<w:UseAsianBreakRules />
<w:DontGrowAutofit />
<w:UseFELayout />
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" LatentStyleCount="156">
</w:LatentStyles>
</xml><![endif]--><style type="text/css"><!--
 /* Font Definitions */
 &#64;font-face
	{font-family:宋体;
	panose-1:2 1 6 0 3 1 1 1 1 1;
	mso-font-alt:SimSun;
	mso-font-charset:134;
	mso-generic-font-family:auto;
	mso-font-pitch:variable;
	mso-font-signature:3 135135232 16 0 262145 0;}
&#64;font-face
	{font-family:"\&#64;宋体";
	panose-1:2 1 6 0 3 1 1 1 1 1;
	mso-font-charset:134;
	mso-generic-font-family:auto;
	mso-font-pitch:variable;
	mso-font-signature:3 135135232 16 0 262145 0;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
	{mso-style-parent:"";
	margin:0in;
	margin-bottom:.0001pt;
	mso-pagination:widow-orphan;
	font-size:12.0pt;
	font-family:"Times New Roman";
	mso-fareast-font-family:宋体;}
&#64;page Section1
	{size:8.5in 11.0in;
	margin:1.0in 1.25in 1.0in 1.25in;
	mso-header-margin:.5in;
	mso-footer-margin:.5in;
	mso-paper-source:0;}
div.Section1
	{page:Section1;}
--></style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin:0in;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
</style>
<![endif]-->
<p class="MsoNormal">HTML<span lang="ZH-CN" style="font-family: 宋体;">中如下定义：</span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br>
<br>
Code highlighting produced by Actipro CodeHighlighter (freeware)<br>
http://www.CodeHighlighter.com/<br>
<br>
--><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">form&nbsp;</span><span style="color: rgb(255, 0, 0);">action</span><span style="color: rgb(0, 0, 255);">=&quot;/Directory/add&quot;</span><span style="color: rgb(255, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;Name:&nbsp;</span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">input&nbsp;</span><span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;text&quot;</span><span style="color: rgb(255, 0, 0);">&nbsp;name</span><span style="color: rgb(0, 0, 255);">=&quot;p.name&quot;</span><span style="color: rgb(255, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">/&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;Age:&nbsp;</span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">input&nbsp;</span><span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;text&quot;</span><span style="color: rgb(255, 0, 0);">&nbsp;name</span><span style="color: rgb(0, 0, 255);">=&quot;p.age&quot;</span><span style="color: rgb(255, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">/&gt;</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">form</span><span style="color: rgb(0, 0, 255);">&gt;</span></div>
<br />
</span></p>
<link rel="File-List" href="file:///C:%5CTEMP%5Cmsohtml1%5C01%5Cclip_filelist.xml" /><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:PunctuationKerning />
<w:ValidateAgainstSchemas />
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:BreakWrappedTables />
<w:SnapToGridInCell />
<w:WrapTextWithPunct />
<w:UseAsianBreakRules />
<w:DontGrowAutofit />
<w:UseFELayout />
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" LatentStyleCount="156">
</w:LatentStyles>
</xml><![endif]--><style type="text/css"><!--
 /* Font Definitions */
 &#64;font-face
	{font-family:宋体;
	panose-1:2 1 6 0 3 1 1 1 1 1;
	mso-font-alt:SimSun;
	mso-font-charset:134;
	mso-generic-font-family:auto;
	mso-font-pitch:variable;
	mso-font-signature:3 135135232 16 0 262145 0;}
&#64;font-face
	{font-family:"\&#64;宋体";
	panose-1:2 1 6 0 3 1 1 1 1 1;
	mso-font-charset:134;
	mso-generic-font-family:auto;
	mso-font-pitch:variable;
	mso-font-signature:3 135135232 16 0 262145 0;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
	{mso-style-parent:"";
	margin:0in;
	margin-bottom:.0001pt;
	mso-pagination:widow-orphan;
	font-size:12.0pt;
	font-family:"Times New Roman";
	mso-fareast-font-family:宋体;}
&#64;page Section1
	{size:8.5in 11.0in;
	margin:1.0in 1.25in 1.0in 1.25in;
	mso-header-margin:.5in;
	mso-footer-margin:.5in;
	mso-paper-source:0;}
div.Section1
	{page:Section1;}
--></style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin:0in;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
</style>
<![endif]-->
<p class="MsoNormal"><b>2.<span style=""><span lang="ZH-CN" style="font-family: 宋体;">通过调用</span>Java</span><span style=""><span lang="ZH-CN" style="font-family: 宋体;">方法重定向到相应的</span>action</span></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">只需要调用相应的</span>Java<span lang="ZH-CN" style="font-family: 宋体;">方法就能方便地重定向到另一个</span>action<span lang="ZH-CN" style="font-family: 宋体;">，</span>Play!<span lang="ZH-CN" style="font-family: 宋体;">会生成正确的</span>redirect response<span lang="ZH-CN" style="font-family: 宋体;">，而不是</span>forward<span lang="ZH-CN" style="font-family: 宋体;">。</span></p>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br>
<br>
Code highlighting produced by Actipro CodeHighlighter (freeware)<br>
http://www.CodeHighlighter.com/<br>
<br>
--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;show(Long&nbsp;id)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;Article&nbsp;article&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;Article.findById(id);<br />
&nbsp;&nbsp;&nbsp;&nbsp;render(article);<br />
}<br />
<br />
</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;edit(Long&nbsp;id,&nbsp;String&nbsp;title)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;Article&nbsp;article&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;Article.findById(id);<br />
&nbsp;&nbsp;&nbsp;&nbsp;article.title&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;title;<br />
&nbsp;&nbsp;&nbsp;&nbsp;article.save();<br />
&nbsp;&nbsp;&nbsp;&nbsp;show(id);<br />
}<br />
</span></div>
<br />
<link rel="File-List" href="file:///C:%5CTEMP%5Cmsohtml1%5C01%5Cclip_filelist.xml" /><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:PunctuationKerning />
<w:ValidateAgainstSchemas />
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:BreakWrappedTables />
<w:SnapToGridInCell />
<w:WrapTextWithPunct />
<w:UseAsianBreakRules />
<w:DontGrowAutofit />
<w:UseFELayout />
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" LatentStyleCount="156">
</w:LatentStyles>
</xml><![endif]--><style type="text/css"><!--
 /* Font Definitions */
 &#64;font-face
	{font-family:宋体;
	panose-1:2 1 6 0 3 1 1 1 1 1;
	mso-font-alt:SimSun;
	mso-font-charset:134;
	mso-generic-font-family:auto;
	mso-font-pitch:variable;
	mso-font-signature:3 135135232 16 0 262145 0;}
&#64;font-face
	{font-family:"\&#64;宋体";
	panose-1:2 1 6 0 3 1 1 1 1 1;
	mso-font-charset:134;
	mso-generic-font-family:auto;
	mso-font-pitch:variable;
	mso-font-signature:3 135135232 16 0 262145 0;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
	{mso-style-parent:"";
	margin:0in;
	margin-bottom:.0001pt;
	mso-pagination:widow-orphan;
	font-size:12.0pt;
	font-family:"Times New Roman";
	mso-fareast-font-family:宋体;}
&#64;page Section1
	{size:8.5in 11.0in;
	margin:1.0in 1.25in 1.0in 1.25in;
	mso-header-margin:.5in;
	mso-footer-margin:.5in;
	mso-paper-source:0;}
div.Section1
	{page:Section1;}
--></style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin:0in;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
</style>
<![endif]-->
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">注意：在</span>edit action<span lang="ZH-CN" style="font-family: 宋体;">的最后重定向到了</span>show action<span lang="ZH-CN" style="font-family: 宋体;">。</span></p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">在模板中你可以使用类似的符号来生成链接：</span></p>
<p class="MsoNormal">&lt;a href=&quot;@{Article.show(article.id)}&quot;&gt;${article.title}&lt;/a&gt;</p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">最终生成的</span>HTML<span lang="ZH-CN" style="font-family: 宋体;">：</span></p>
<p class="MsoNormal">&lt;a href=&quot;/articles/15&quot;&gt;My new article&lt;/a&gt;</p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal"><b>3.<span style=""><span lang="ZH-CN" style="font-family: 宋体;">直接把</span>Java</span><span style=""><span lang="ZH-CN" style="font-family: 宋体;">对象</span></span><span lang="ZH-CN" style="font-family: 宋体;">传递到页面模板</span></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">在大多数</span>Java<span lang="ZH-CN" style="font-family: 宋体;">框架中，你需要写类似下面代码来把</span>Java<span lang="ZH-CN" style="font-family: 宋体;">对象传递给页面模板：</span></p>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br>
<br>
Code highlighting produced by Actipro CodeHighlighter (freeware)<br>
http://www.CodeHighlighter.com/<br>
<br>
--><span style="color: rgb(0, 0, 0);">Article&nbsp;article&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;Article.findById(id);<br />
User&nbsp;user&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;User.getConnected();<br />
Map</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">String,&nbsp;Object</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;model&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;HashMap</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">String,Object</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">();<br />
model.put(</span><span style="color: rgb(0, 0, 0);">&quot;</span><span style="color: rgb(0, 0, 0);">article</span><span style="color: rgb(0, 0, 0);">&quot;</span><span style="color: rgb(0, 0, 0);">,&nbsp;article);<br />
model.put(</span><span style="color: rgb(0, 0, 0);">&quot;</span><span style="color: rgb(0, 0, 0);">user</span><span style="color: rgb(0, 0, 0);">&quot;</span><span style="color: rgb(0, 0, 0);">,&nbsp;user);<br />
render(model);<br />
</span></div>
<link rel="File-List" href="file:///C:%5CTEMP%5Cmsohtml1%5C01%5Cclip_filelist.xml" /><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:PunctuationKerning />
<w:ValidateAgainstSchemas />
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:BreakWrappedTables />
<w:SnapToGridInCell />
<w:WrapTextWithPunct />
<w:UseAsianBreakRules />
<w:DontGrowAutofit />
<w:UseFELayout />
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" LatentStyleCount="156">
</w:LatentStyles>
</xml><![endif]--><style type="text/css"><!--
 /* Font Definitions */
 &#64;font-face
	{font-family:宋体;
	panose-1:2 1 6 0 3 1 1 1 1 1;
	mso-font-alt:SimSun;
	mso-font-charset:134;
	mso-generic-font-family:auto;
	mso-font-pitch:variable;
	mso-font-signature:3 135135232 16 0 262145 0;}
&#64;font-face
	{font-family:"\&#64;宋体";
	panose-1:2 1 6 0 3 1 1 1 1 1;
	mso-font-charset:134;
	mso-generic-font-family:auto;
	mso-font-pitch:variable;
	mso-font-signature:3 135135232 16 0 262145 0;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
	{mso-style-parent:"";
	margin:0in;
	margin-bottom:.0001pt;
	mso-pagination:widow-orphan;
	font-size:12.0pt;
	font-family:"Times New Roman";
	mso-fareast-font-family:宋体;}
&#64;page Section1
	{size:8.5in 11.0in;
	margin:1.0in 1.25in 1.0in 1.25in;
	mso-header-margin:.5in;
	mso-footer-margin:.5in;
	mso-paper-source:0;}
div.Section1
	{page:Section1;}
--></style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin:0in;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
</style>
<![endif]-->
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">在</span>Play!<span lang="ZH-CN" style="font-family: 宋体;">中你只需要这么做：</span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br>
<br>
Code highlighting produced by Actipro CodeHighlighter (freeware)<br>
http://www.CodeHighlighter.com/<br>
<br>
--><span style="color: rgb(0, 0, 0);">Article&nbsp;article&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;Article.findById(id);<br />
User&nbsp;user&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;User.getConnected();<br />
render(article,&nbsp;user);&nbsp;</span></div>
<br />
</span></p>
<link rel="File-List" href="file:///C:%5CTEMP%5Cmsohtml1%5C01%5Cclip_filelist.xml" /><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:PunctuationKerning />
<w:ValidateAgainstSchemas />
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:BreakWrappedTables />
<w:SnapToGridInCell />
<w:WrapTextWithPunct />
<w:UseAsianBreakRules />
<w:DontGrowAutofit />
<w:UseFELayout />
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" LatentStyleCount="156">
</w:LatentStyles>
</xml><![endif]--><style type="text/css"><!--
 /* Font Definitions */
 &#64;font-face
	{font-family:宋体;
	panose-1:2 1 6 0 3 1 1 1 1 1;
	mso-font-alt:SimSun;
	mso-font-charset:134;
	mso-generic-font-family:auto;
	mso-font-pitch:variable;
	mso-font-signature:3 135135232 16 0 262145 0;}
&#64;font-face
	{font-family:"\&#64;宋体";
	panose-1:2 1 6 0 3 1 1 1 1 1;
	mso-font-charset:134;
	mso-generic-font-family:auto;
	mso-font-pitch:variable;
	mso-font-signature:3 135135232 16 0 262145 0;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
	{mso-style-parent:"";
	margin:0in;
	margin-bottom:.0001pt;
	mso-pagination:widow-orphan;
	font-size:12.0pt;
	font-family:"Times New Roman";
	mso-fareast-font-family:宋体;}
&#64;page Section1
	{size:8.5in 11.0in;
	margin:1.0in 1.25in 1.0in 1.25in;
	mso-header-margin:.5in;
	mso-footer-margin:.5in;
	mso-paper-source:0;}
div.Section1
	{page:Section1;}
--></style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin:0in;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
</style>
<![endif]--><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
<p class="MsoNormal"><b>4.<span lang="ZH-CN" style="font-family: 宋体;">方便的文件上传</span></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">在</span>Play!<span lang="ZH-CN" style="font-family: 宋体;">框架中实现文件上传很方便：</span></p>
<p class="MsoNormal">HTML form <span lang="ZH-CN" style="font-family: 宋体;">：</span></p>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br>
<br>
Code highlighting produced by Actipro CodeHighlighter (freeware)<br>
http://www.CodeHighlighter.com/<br>
<br>
--><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">form&nbsp;</span><span style="color: rgb(255, 0, 0);">action</span><span style="color: rgb(0, 0, 255);">=&quot;@{Article.uploadPhoto}&quot;</span><span style="color: rgb(255, 0, 0);">&nbsp;method</span><span style="color: rgb(0, 0, 255);">=&quot;POST&quot;</span><span style="color: rgb(255, 0, 0);">&nbsp;enctype</span><span style="color: rgb(0, 0, 255);">=&quot;multipart/form-data&quot;</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">input&nbsp;</span><span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;text&quot;</span><span style="color: rgb(255, 0, 0);">&nbsp;name</span><span style="color: rgb(0, 0, 255);">=&quot;title&quot;</span><span style="color: rgb(255, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">/&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">input&nbsp;</span><span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;file&quot;</span><span style="color: rgb(255, 0, 0);">&nbsp;id</span><span style="color: rgb(0, 0, 255);">=&quot;photo&quot;</span><span style="color: rgb(255, 0, 0);">&nbsp;name</span><span style="color: rgb(0, 0, 255);">=&quot;photo&quot;</span><span style="color: rgb(255, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">/&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">input&nbsp;</span><span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">=&quot;submit&quot;</span><span style="color: rgb(255, 0, 0);">&nbsp;value</span><span style="color: rgb(0, 0, 255);">=&quot;Send&nbsp;it&nbsp;<img alt="" src="http://www.blogjava.net/Images/dot.gif" />&quot;</span><span style="color: rgb(255, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">/&gt;</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">form</span><span style="color: rgb(0, 0, 255);">&gt;</span></div>
<link rel="File-List" href="file:///C:%5CTEMP%5Cmsohtml1%5C01%5Cclip_filelist.xml" /><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:PunctuationKerning />
<w:ValidateAgainstSchemas />
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:BreakWrappedTables />
<w:SnapToGridInCell />
<w:WrapTextWithPunct />
<w:UseAsianBreakRules />
<w:DontGrowAutofit />
<w:UseFELayout />
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" LatentStyleCount="156">
</w:LatentStyles>
</xml><![endif]--><style type="text/css"><!--
 /* Font Definitions */
 &#64;font-face
	{font-family:宋体;
	panose-1:2 1 6 0 3 1 1 1 1 1;
	mso-font-alt:SimSun;
	mso-font-charset:134;
	mso-generic-font-family:auto;
	mso-font-pitch:variable;
	mso-font-signature:3 135135232 16 0 262145 0;}
&#64;font-face
	{font-family:"\&#64;宋体";
	panose-1:2 1 6 0 3 1 1 1 1 1;
	mso-font-charset:134;
	mso-generic-font-family:auto;
	mso-font-pitch:variable;
	mso-font-signature:3 135135232 16 0 262145 0;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
	{mso-style-parent:"";
	margin:0in;
	margin-bottom:.0001pt;
	mso-pagination:widow-orphan;
	font-size:12.0pt;
	font-family:"Times New Roman";
	mso-fareast-font-family:宋体;}
&#64;page Section1
	{size:8.5in 11.0in;
	margin:1.0in 1.25in 1.0in 1.25in;
	mso-header-margin:.5in;
	mso-footer-margin:.5in;
	mso-paper-source:0;}
div.Section1
	{page:Section1;}
--></style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin:0in;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
</style>
<![endif]-->
<p class="MsoNormal">Java<span lang="ZH-CN" style="font-family: 宋体;">代码：</span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br>
<br>
Code highlighting produced by Actipro CodeHighlighter (freeware)<br>
http://www.CodeHighlighter.com/<br>
<br>
--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;uploadPhoto(String&nbsp;title,&nbsp;File&nbsp;photo)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;<img alt="" src="http://www.blogjava.net/Images/dot.gif" /><br />
}</span></div>
<br />
</span></p>
<link rel="File-List" href="file:///C:%5CTEMP%5Cmsohtml1%5C01%5Cclip_filelist.xml" /><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:PunctuationKerning />
<w:ValidateAgainstSchemas />
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:BreakWrappedTables />
<w:SnapToGridInCell />
<w:WrapTextWithPunct />
<w:UseAsianBreakRules />
<w:DontGrowAutofit />
<w:UseFELayout />
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" LatentStyleCount="156">
</w:LatentStyles>
</xml><![endif]--><style type="text/css"><!--
 /* Font Definitions */
 &#64;font-face
	{font-family:宋体;
	panose-1:2 1 6 0 3 1 1 1 1 1;
	mso-font-alt:SimSun;
	mso-font-charset:134;
	mso-generic-font-family:auto;
	mso-font-pitch:variable;
	mso-font-signature:3 135135232 16 0 262145 0;}
&#64;font-face
	{font-family:"\&#64;宋体";
	panose-1:2 1 6 0 3 1 1 1 1 1;
	mso-font-charset:134;
	mso-generic-font-family:auto;
	mso-font-pitch:variable;
	mso-font-signature:3 135135232 16 0 262145 0;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
	{mso-style-parent:"";
	margin:0in;
	margin-bottom:.0001pt;
	mso-pagination:widow-orphan;
	font-size:12.0pt;
	font-family:"Times New Roman";
	mso-fareast-font-family:宋体;}
&#64;page Section1
	{size:8.5in 11.0in;
	margin:1.0in 1.25in 1.0in 1.25in;
	mso-header-margin:.5in;
	mso-footer-margin:.5in;
	mso-paper-source:0;}
div.Section1
	{page:Section1;}
--></style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin:0in;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
</style>
<![endif]-->
<p class="MsoNormal"><b>5.<span style=""><span lang="ZH-CN" style="font-family: 宋体;">不用任何配置就可以把应用分布到多个</span>JVM</span></b></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">由于应用程序被设计成无状态的，所以你可以简单地在多台服务器上启动同一个应用，然后通过</span>HTTP<span lang="ZH-CN" style="font-family: 宋体;">层面的负载均衡来实现分布式应用。不需要设置一个负债的服务器集群。</span></p>
</div>]]></description>
			<link>http://www.eoss.cn/blog/five_cool_functions_in_play/</link>
			<category domain="http://www.eoss.cn/blog/category/java/">Java</category>
			<pubDate>2008-12-25 10:47</pubDate>
		</item>
		<item>
			<guid>http://www.eoss.cn/blog/play_framework_overview/</guid>
			<title>Play with Play! - 框架概要</title>
			<author>shine</author>
			<description><![CDATA[乐在其中 ( http://www.eoss.cn/blog/ ) : <p><b>纯Java框架</b> 		</p>
<p>Play!<span lang="ZH-CN" style="font-family: 宋体;">是一个纯</span>Java<span lang="ZH-CN" style="font-family: 宋体;">实现的</span>Web<span lang="ZH-CN" style="font-family: 宋体;">敏捷开发框架，工程的默认目录结构如下：</span></p>
<p><img src="http://www.playframework.org/manual/_media/structure.png?cache=cache" alt="" /> 				<br />
<span lang="ZH-CN" style="font-family: 宋体;"> 				</span> 				<span lang="ZH-CN"> 				</span> 				<span style="text-decoration: none;"> 						<v:shapetype path=" m@4@5 l@4@11@9@11@9@5 xe" stroked="f" filled="f" o:spt="75" o:preferrelative="t" coordsize="21600,21600" id="_x0000_t75"> 								<v:stroke joinstyle="miter"> 								</v:stroke> 								<v:formulas> 										<v:f eqn="if lineDrawn pixelLineWidth 0 "> 										</v:f> 										<v:f eqn="sum @0 1 0 "> 										</v:f> 										<v:f eqn="sum 0 0 @1 "> 										</v:f> 										<v:f eqn="prod @2 1 2 "> 										</v:f> 										<v:f eqn="prod @3 21600 pixelWidth "> 										</v:f> 										<v:f eqn="prod @3 21600 pixelHeight "> 										</v:f> 										<v:f eqn="sum @0 0 1 "> 										</v:f> 										<v:f eqn="prod @6 1 2 "> 										</v:f> 										<v:f eqn="prod @7 21600 pixelWidth "> 										</v:f> 										<v:f eqn="sum @8 21600 0 "> 										</v:f> 										<v:f eqn="prod @7 21600 pixelHeight "> 										</v:f> 										<v:f eqn="sum @10 21600 0 "> 										</v:f> 								</v:formulas> 								<v:path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"> 								</v:path> 								<o:lock v:ext="edit" aspectratio="t"> 								</o:lock> 						</v:shapetype> 						<v:shape o:button="t" href="http://www.playframework.org/manual/_detail/structure.png?id=contents%3Aoverview&amp;cache=cache" alt="" coordsize="21600,21600" type="#_x0000_t75" style="width: 519.75pt; height: 349.5pt;" title="&quot;structure.png&quot;" id="_x0000_i1025"> 								<v:imagedata o:href="http://www.playframework.org/manual/_media/structure.png?w=&amp;h=&amp;cache=cache" src="file:///C:%5CTEMP%5Cmsohtml1%5C01%5Cclip_image001.png"> 								</v:imagedata> 						</v:shape> 				</span></p>
<p><b>构建在HTTP上</b></p>
<p>Servlet<span lang="ZH-CN" style="font-family: 宋体;">或者</span>Struts<span lang="ZH-CN" style="font-family: 宋体;">之类的</span>Java Web<span lang="ZH-CN" style="font-family: 宋体;">框架对</span>HTTP API<span lang="ZH-CN" style="font-family: 宋体;">进行了抽象和封装，</span>Play!<span lang="ZH-CN" style="font-family: 宋体;">和这些框架的根本上的不同之处就在于</span>Play!<span lang="ZH-CN" style="font-family: 宋体;">提供了对</span>HTTP<span lang="ZH-CN" style="font-family: 宋体;">完全的访问能力。</span><o:p></o:p></p>
<p><span lang="ZH-CN" style="font-family: 宋体;">通过</span>Router<span lang="ZH-CN" style="font-family: 宋体;">绑定</span>URI<span lang="ZH-CN" style="font-family: 宋体;">到</span>Java<span lang="ZH-CN" style="font-family: 宋体;">的方法：</span><o:p></o:p></p>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><!--<br>
<br>
Code highlighting produced by Actipro CodeHighlighter (freeware)<br>
http://www.CodeHighlighter.com/<br>
<br>
--> 				<span style="color: rgb(0, 0, 0);">GET&nbsp;&nbsp;&nbsp;</span> 				<span style="color: rgb(0, 0, 0);">/</span> 				<span style="color: rgb(0, 0, 0);">clients</span> 				<span style="color: rgb(0, 0, 0);">/</span> 				<span style="color: rgb(0, 0, 0);">{id}&nbsp;&nbsp;&nbsp;Clients.show</span><o:p></o:p><br />
<span lang="ZH-CN" style="font-family: 宋体;"> 				</span></div>
<h2>&nbsp;</h2>
<p><span lang="ZH-CN" style="font-family: 宋体;"> 						<b>高效的模板引擎</b> 						<br />
</span></p>
<p><span lang="ZH-CN" style="font-family: 宋体;">我们喜欢</span>JSP<span lang="ZH-CN" style="font-family: 宋体;">和表达式语言背后的思想，但为什么创建一个</span>taglib<span lang="ZH-CN" style="font-family: 宋体;">需要配置这么多的文件，为什么不能提供对</span>model<span lang="ZH-CN" style="font-family: 宋体;">的完全的访问？</span>JSP<span lang="ZH-CN" style="font-family: 宋体;">有太多的局限性，使用起来很麻烦，那么让我们创建一个更好的模板引擎吧。</span></p>
<p><span lang="ZH-CN" style="font-family: 宋体;">如果你想实现下面的</span>JSP<span lang="ZH-CN" style="font-family: 宋体;">代码的功能：</span><o:p></o:p></p>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><!--<br>
<br>
Code highlighting produced by Actipro CodeHighlighter (freeware)<br>
http://www.CodeHighlighter.com/<br>
<br>
--> 				<span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 0);">&lt;%</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">@&nbsp;taglib&nbsp;uri</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">=</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">&quot;</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">http://java.sun.com/jsp/jstl/core</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">&quot;</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">&nbsp;prefix</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">=</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">&quot;</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">c</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">&quot;</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">&nbsp;</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 0);">%&gt;</span> 				<span style="color: rgb(0, 0, 0);"> 						<br />
</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 0);">&lt;%</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">@&nbsp;taglib&nbsp;uri</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">=</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">&quot;</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">http://java.sun.com/jsp/jstl/functions</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">&quot;</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">&nbsp;prefix</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">=</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">&quot;</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">fn</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">&quot;</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">&nbsp;</span> 				<span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 0);">%&gt;</span> 				<span style="color: rgb(0, 0, 0);"> 						<br />
<br />
</span> 				<span style="color: rgb(0, 0, 255);">&lt;</span> 				<span style="color: rgb(128, 0, 0);">c:choose</span> 				<span style="color: rgb(0, 0, 255);">&gt;</span> 				<span style="color: rgb(0, 0, 0);"> 						<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span> 				<span style="color: rgb(0, 0, 255);">&lt;</span> 				<span style="color: rgb(128, 0, 0);">c:when&nbsp;</span> 				<span style="color: rgb(255, 0, 0);">test</span> 				<span style="color: rgb(0, 0, 255);">=&quot;${emails.unread&nbsp;!=&nbsp;null&nbsp;&amp;&amp;&nbsp;fn:size(emails.unread)}&quot;</span> 				<span style="color: rgb(0, 0, 255);">&gt;</span> 				<span style="color: rgb(0, 0, 0);"> 						<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;You've&nbsp;${fn:size(emails.unread)}&nbsp;unread&nbsp;emails&nbsp;!<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span> 				<span style="color: rgb(0, 0, 255);">&lt;/</span> 				<span style="color: rgb(128, 0, 0);">c:when</span> 				<span style="color: rgb(0, 0, 255);">&gt;</span> 				<span style="color: rgb(0, 0, 0);"> 						<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span> 				<span style="color: rgb(0, 0, 255);">&lt;</span> 				<span style="color: rgb(128, 0, 0);">c:otherwise</span> 				<span style="color: rgb(0, 0, 255);">&gt;</span> 				<span style="color: rgb(0, 0, 0);"> 						<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;You've&nbsp;none&nbsp;unread&nbsp;emails&nbsp;!<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span> 				<span style="color: rgb(0, 0, 255);">&lt;/</span> 				<span style="color: rgb(128, 0, 0);">c:otherwise</span> 				<span style="color: rgb(0, 0, 255);">&gt;</span> 				<span style="color: rgb(0, 0, 0);"> 						<br />
</span> 				<span style="color: rgb(0, 0, 255);">&lt;/</span> 				<span style="color: rgb(128, 0, 0);">c:choose</span> 				<span style="color: rgb(0, 0, 255);">&gt;</span> 				</div>
<p><span lang="ZH-CN" style="font-family: 宋体;">你会喜欢上下面这种写法：</span></p>
<p><span lang="ZH-CN" style="font-family: 宋体;"> 				</span></p>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><!--<br>
<br>
Code highlighting produced by Actipro CodeHighlighter (freeware)<br>
http://www.CodeHighlighter.com/<br>
<br>
--> 				<span style="color: rgb(0, 0, 0);">You</span> 				<span style="color: rgb(128, 0, 0);">'</span> 				<span style="color: rgb(128, 0, 0);">ve&nbsp;${email.unread?.size()&nbsp;?:&nbsp;</span> 				<span style="color: rgb(128, 0, 0);">'</span> 				<span style="color: rgb(0, 0, 0);">none</span> 				<span style="color: rgb(128, 0, 0);">'</span> 				<span style="color: rgb(128, 0, 0);">}&nbsp;unread&nbsp;emails&nbsp;!</span></div>
<o:p> 		</o:p>
<p>&nbsp;</p>
<p>Play!<span lang="ZH-CN" style="font-family: 宋体;">使用</span>Groovy<span lang="ZH-CN" style="font-family: 宋体;">作为模板语言，这是一种和</span>Java<span lang="ZH-CN" style="font-family: 宋体;">语法极为相似的语言，并且可以无缝的使用</span>Java<span lang="ZH-CN" style="font-family: 宋体;">类库，可以将其看作是动态的</span>Java<span lang="ZH-CN" style="font-family: 宋体;">语言。</span><o:p></o:p><br />
<span lang="ZH-CN" style="font-family: 宋体;"> 				</span></p>
<p>&nbsp;</p>
<p><span lang="ZH-CN" style="font-family: 宋体;"> 						<b>具有生产效率的Java</b> 						<br />
</span></p>
<p><span lang="ZH-CN" style="font-family: 宋体;">众所周知，由于需要编译、部署，</span>Java<span lang="ZH-CN" style="font-family: 宋体;">平台的生产效率比</span>ROR<span lang="ZH-CN" style="font-family: 宋体;">这类动态语言平台低很多。</span>Play!<span lang="ZH-CN" style="font-family: 宋体;">的目标是尽可能的提高</span>Java<span lang="ZH-CN" style="font-family: 宋体;">开发的生产效率。在开发环境下，</span>Play!<span lang="ZH-CN" style="font-family: 宋体;">框架可自动编译和重新装载已改变的源文件。也就是说在保存源代码的改变后，就能立刻通过刷新浏览器看到结果，不需要重新编译、部署、重启服务器。</span></p>
<p>Play! <span lang="ZH-CN" style="font-family: 宋体;">具有优秀的错误报告功能。发生异常时，该框架会直接显示出错误的源代码，甚至是模板代码。</span></p>
<p><img src="http://www.playframework.org/manual/_media/error.png?cache=cache" alt="" /> </p>
<p><strong>Full-stack应用框架</strong></p>
<p>Play!<span lang="ZH-CN" style="font-family: 宋体;">是一个</span>full-stack Java Web<span lang="ZH-CN" style="font-family: 宋体;">应用框架，具有建立一个现代化网络应用所需的一切：</span><o:p></o:p></p>
<ul type="disc">
    <li class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">通过</span>JBDC<span lang="ZH-CN" style="font-family: 宋体;">支持关系型数据库</span><o:p></o:p></li>
    <li class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">使用</span>Hibernate<span lang="ZH-CN" style="font-family: 宋体;">作为</span>ORM<o:p></o:p></li>
    <li class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">支持</span>Memcache<o:p></o:p></li>
    <li class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">支持</span>JSON<span lang="ZH-CN" style="font-family: 宋体;">或者</span><acronym>XML</acronym><span lang="ZH-CN" style="font-family: 宋体;">格式的</span>Web<span lang="ZH-CN" style="font-family: 宋体;">服务</span><o:p></o:p></li>
    <li class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">支持</span>OpenID<o:p></o:p></li>
    <li class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">图片处理</span> 						<acronym>API</acronym> 						<o:p> 						</o:p></li>
    <li class="MsoNormal">&hellip;<o:p></o:p></li>
</ul>
<p>Play!<span lang="ZH-CN" style="font-family: 宋体;">的插件系统可以让你重用其他系统的</span>Java<span lang="ZH-CN" style="font-family: 宋体;">代码、模板甚至</span>JavaScript<span lang="ZH-CN" style="font-family: 宋体;">和</span>CSS<span lang="ZH-CN" style="font-family: 宋体;">。</span></p>]]></description>
			<link>http://www.eoss.cn/blog/play_framework_overview/</link>
			<category domain="http://www.eoss.cn/blog/category/java/">Java</category>
			<pubDate>2008-12-25 10:22</pubDate>
		</item>
		<item>
			<guid>http://www.eoss.cn/blog/java_error_language_coding/</guid>
			<title>Note:Java开发的中文乱码问题</title>
			<author>shine</author>
			<description><![CDATA[乐在其中 ( http://www.eoss.cn/blog/ ) : <p>JSP输出乱码<br />
获取表单乱码<br />
URL乱码<br />
数据库乱码<br />
<br />
这里仅做标记，解决方案网上很多。</p>]]></description>
			<link>http://www.eoss.cn/blog/java_error_language_coding/</link>
			<category domain="http://www.eoss.cn/blog/category/java/">Java</category>
			<pubDate>2008-12-20 10:02</pubDate>
		</item>
		<item>
			<guid>http://www.eoss.cn/blog/java_server_performance/</guid>
			<title>Java服务器性能测试</title>
			<author>shine</author>
			<description><![CDATA[乐在其中 ( http://www.eoss.cn/blog/ ) : <p>摘录：</p>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br>
<br>
Code highlighting produced by Actipro CodeHighlighter (freeware)<br>
http://www.CodeHighlighter.com/<br>
<br>
--><span style="color: rgb(0, 0, 0);">tomcat6.</span><span style="color: rgb(0, 0, 0);">0.14</span><span style="color: rgb(0, 0, 0);">、resin3.</span><span style="color: rgb(0, 0, 0);">2.1</span><span style="color: rgb(0, 0, 0);">、glassfish&nbsp;v2对同一个loginaction使用JMeter进行压力测试，具体流程：JMeter发送http请求</span><span style="color: rgb(0, 0, 0);">--&gt;</span><span style="color: rgb(0, 0, 0);">login.jsp</span><span style="color: rgb(0, 0, 0);">--&gt;</span><span style="color: rgb(0, 0, 0);">login.</span><span style="color: rgb(0, 0, 255);">do</span><span style="color: rgb(0, 0, 0);">--&gt;</span><span style="color: rgb(0, 0, 0);">控制台打印一条信息表示收到request请求。每种服务器测试两次，每次10个thread，每个thread以每秒10次的速度发请求，循环10次，每组共发100个请求，两次共200个。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;glassfish平均延迟：</span><span style="color: rgb(0, 0, 0);">6041</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resin平均延迟：</span><span style="color: rgb(0, 0, 0);">3394</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tomcat平均延迟：</span><span style="color: rgb(0, 0, 0);">1215</span><span style="color: rgb(0, 0, 0);">！！<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;附件内是测试结果截图。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;后记：以上测试都是在直接下载服务器软件不进行任何调整和优化的情况下进行的，resin和glassfish都必须进行针对项目的优化才能获得满意的性能，而tomcat默认优化已经不错。<br />
<br />
另据我个人经验，同样做深度优化后resin比tomcat还是要快一些，但绝达不到网上流传的3倍之多，glassfish目前还没有使用经验</span></div>
<p>一直想比较一下几种常见的Java服务器的性能，除了上面提到的几种服务器外，还可以加上Jetty和JBossWeb，先做个记号，有时间自己测一下。</p>
<p>Tomcat就不多说了。</p>
<p>Glassfish是一个免费，开源的Java EE5应用服务器。</p>
<p>Resin的免费版好像性能比较低。</p>
<p>Jetty 主要是作为企业级产品的嵌入式组件来设计的，可以非常方便地嵌入到其它产品中。而且 Jetty 是作为单独的 Http Server 来设计的，据 Jetty 开发人员的测试，Jetty 的性能几乎与 Apache 相当，生产环境，尤其是高负载的环境中还是使用 Jetty 更好。Jetty适合快速部署测试开发，Grails就内置了Jetty。据说，jetty的优势是集群，很适合云计算的环境。</p>
<p>另外，JBossWeb好像性能也不错。</p>]]></description>
			<link>http://www.eoss.cn/blog/java_server_performance/</link>
			<category domain="http://www.eoss.cn/blog/category/java/">Java</category>
			<pubDate>2008-12-16 11:11</pubDate>
		</item>
		<item>
			<guid>http://www.eoss.cn/blog/beyond_java/</guid>
			<title>谁能成为Java的接班者</title>
			<author>shine</author>
			<description><![CDATA[乐在其中 ( http://www.eoss.cn/blog/ ) : <p>这篇文章主要是《Beyond Java》几个要点的摘录，算是读书笔记，目前还没有哪个语言有取代Java的趋势，虽然比例略有下降，Java依然稳稳的占据编程语言排行榜 （TIOBE）的第一位，但编程语言变革的暗潮已经在涌动了，我觉得这几点可以作为我们把握开发语言发展趋势的参考：</p>
<ul>
    <li>动态类型或者自动类型转换</li>
    <li>快速反馈，改变代码后马上可以看到运行效果</li>
    <li>基于虚拟机</li>
    <li>开放源代码</li>
    <li>支持分布式、多核计算</li>
</ul>]]></description>
			<link>http://www.eoss.cn/blog/beyond_java/</link>
			<category domain="http://www.eoss.cn/blog/category/java/">Java</category>
			<pubDate>2008-12-16 09:58</pubDate>
		</item>
		<item>
			<guid>http://www.eoss.cn/blog/jdbc_optimize/</guid>
			<title>优化JDBC访问数据库性能</title>
			<author>shine</author>
			<description><![CDATA[乐在其中 ( http://www.eoss.cn/blog/ ) : <p>1.使用连接地<br />
2.关闭自动提交功能<br />
conn.setAutoCommit(false)<br />
关闭后需要手工调用commit()和rollback()<br />
3.使用PreparedStatement预编译<br />
4.建立索引</p>]]></description>
			<link>http://www.eoss.cn/blog/jdbc_optimize/</link>
			<category domain="http://www.eoss.cn/blog/category/java/">Java</category>
			<pubDate>2008-12-15 11:10</pubDate>
		</item>
		<item>
			<guid>http://www.eoss.cn/blog/grails_notes_3/</guid>
			<title>Grails开发笔记 - 如何输出SQL Log</title>
			<author>shine</author>
			<description><![CDATA[乐在其中 ( http://www.eoss.cn/blog/ ) : <p>Hibernate是一个流行的Java对象关系映射框架，Grails的数据访问层GORM就是建立在Hibernate的基础上。Hibernate 能够根据配置自动生成SQL语句，使得程序员可以随心所欲的使用对象编程思维来操纵数据库。然而如果使用不当，往往容易造成性能问题，例如N+1次查询问 题。在开发过程中，常常需要通过查看Hibernate生成的SQL来对数据访问层进行调优。Grails使用了Log4j作为日志组件，因此可以像传统 的基于Hibernate的Java项目那样，通过配置Log4j来达到输出Hibernate SQL Log的功能，这里就不再详述。Grails提供了两种更加简单的方法：<br />
<br />
1.修改config.groovy文件中的log4j configuration，把hibernate=&quot;off&quot;改成hibernate=&quot;on&quot;，这样就可以输出Hibernate运行的详细日志，包括SQL Log。<br />
<br />
2. 一般情况下，我们不需要方法1输出的详细的日志，仅仅需要输出SQL Log，可以DataSource.groovy中的数据库环境配置(environment specific settings)，例如在development的dataSource中添加logSql = true即可。</p>
<pre><ol class="dp-rb"><li class="alt"><span><span>//&nbsp;environment&nbsp;specific&nbsp;settings&nbsp;</span></span></li><li><span>environments&nbsp;{&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;development&nbsp;{&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;dataSource&nbsp;{&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dbCreate&nbsp;=&nbsp;<span class="string">&quot;update&quot;</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url&nbsp;=&nbsp;<span class="string">&quot;jdbc:hsqldb:mem:devDB&quot;</span><span>&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logSql&nbsp;=&nbsp;<span class="keyword">true</span><span>&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;}&nbsp;</span></li><li><span>}&nbsp;</span></li></ol></pre>
<p>&nbsp;</p>]]></description>
			<link>http://www.eoss.cn/blog/grails_notes_3/</link>
			<category domain="http://www.eoss.cn/blog/category/java/">Java</category>
			<pubDate>2008-12-03 16:54</pubDate>
		</item>
		<item>
			<guid>http://www.eoss.cn/blog/grails_notes_2/</guid>
			<title>Grails开发笔记 - 如何改变默认主页</title>
			<author>shine</author>
			<description><![CDATA[乐在其中 ( http://www.eoss.cn/blog/ ) : <p>Grails为开发者提供了一个controller列表的默认主页，在开发时用起来确实很方便，但总不能把它用到产品环境下吧。可是在grails- app/views下面怎么找不到这个文件，也没有哪个controller和主页相关？实际上这个默认的主页独立放在web-app下，文件名是 index.gsp。把它修改为：</p>
<pre><ol class="dp-xml"><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">html</span><span class="tag">&gt;</span><span>&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">head</span><span class="tag">&gt;</span><span>&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>Welcome&nbsp;to&nbsp;Grails</span><span class="tag">&lt;/</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">meta</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;layout&quot;</span><span>&nbsp;</span><span class="attribute">content</span><span>=</span><span class="attribute-value">&quot;main&quot;</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">head</span><span class="tag">&gt;</span><span>&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">body</span><span class="tag">&gt;</span><span>&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;Hello&nbsp;World!&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">body</span><span class="tag">&gt;</span><span>&nbsp;</span></span></li><li class="alt"><span><span class="tag">&lt;/</span><span class="tag-name">html</span><span class="tag">&gt;</span><span>&nbsp;</span></span></li></ol></pre>
<p>刷新后主页变成了Hello World!</p>
<p>好了，本文结束，接下来的工作就是你的了。慢着，如果不想重新编写一个主页，而是想把它重定向到一个controller怎么办？</p>
<p>Grails 是建立在Java的基础之上的，在Grails项目中我们可以很方便的使用Java的各种技术，包括JSP。现在把index.gsp重新命名为 index.jsp，内容改为&lt;% response.sendRedirect(&quot;yourController/yourAction&quot;); %&gt;，刷新后主页就重定向到了你定义的路径。</p>
<p>事实上GSP是JSP的扩展，这意味着你同样可以在GSP中使用session、 servletContext,、request和response对象。把index.jsp重新改回index.gsp，内容改 为${response.sendRedirect(&quot;yourController/yourAction&quot;)}同样可以达到重定向效果。</p>
<p>还可以自定义一个Tag来实现重定向：</p>
<pre><ol class="dp-rb"><li class="alt"><span><span class="keyword">def</span><span>&nbsp;redirectPage={attrs-&gt;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;<span class="keyword">def</span><span>&nbsp;url=attrs.get(</span><span class="string">'url'</span><span>)&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;response.sendRedirect(<span class="string">&quot;${request.contextPath}&quot;</span><span>+url)&nbsp;</span></span></li><li><span>}&nbsp;</span></li></ol></pre>
<p>最后介绍最简单的解决方法：<br />
打开grails-app/conf/UrlMappings.groovy，这是Grails中URL映射的配置文件，相当于Rails中的routes.rb，把它作如下修改即可：</p>
<pre><ol class="dp-rb"><li class="alt"><span><span class="keyword">class</span><span>&nbsp;UrlMappings&nbsp;{&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;mappings&nbsp;=&nbsp;{&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">&quot;/&quot;</span><span>(controller:</span><span class="string">&quot;yourController&quot;</span><span>,action:</span><span class="string">&quot;yourAction&quot;</span><span>)&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">&quot;/$controller/$action?/$id?&quot;</span><span>{&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;constraints&nbsp;{&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;apply&nbsp;constraints&nbsp;here&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span></li><li><span>}&nbsp;</span></li></ol>
</pre>]]></description>
			<link>http://www.eoss.cn/blog/grails_notes_2/</link>
			<category domain="http://www.eoss.cn/blog/category/java/">Java</category>
			<pubDate>2008-11-27 16:40</pubDate>
		</item>
		<item>
			<guid>http://www.eoss.cn/blog/grails_notes_1/</guid>
			<title>Grails开发笔记 - 立即加载和延迟加载</title>
			<author>shine</author>
			<description><![CDATA[乐在其中 ( http://www.eoss.cn/blog/ ) : <p>使用ORM时，常常碰到N+1次查询的问题。Hibernate采用立即加载(eager load)和延迟加载(lazy load)来解决这一问题，GROM建立在Hibernate的基础之上，理论上同样适用。但事实如何？</p>
<p>Grails的官方文档中提到：默认情况下，GORM 集合使用延迟加载的并且可以通过fetchMode来配置或者是使用mapping来配置 。并给出了一段在domain中配置的样例代码。</p>
<p>但从我的使用经验来看，不推荐在domain类中配置延迟加载。原因如下：<br />
1、在domain类中配置延迟加载是全局性的，有可能造成不需要开销。<br />
2、目前在domain类中配置延迟加载存在Bug，只对one-to-many的关系才有效。</p>
<p>例如论坛的列表页面，需要显示topic的分页列表，其中每条topic需要显示作者的名字，topic最后回复帖子的作者。</p>
<p>按照官方文档，可以在Topic类中如下配置，查询结果为1条topic，理论上结果应该执行一条SQL语句：</p>
<pre><ol class="dp-j"><li class="alt"><span><span class="keyword">class</span><span>&nbsp;&nbsp;&nbsp;Topic&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;title&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;body&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;createTime&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;<span class="keyword">new</span><span>&nbsp;&nbsp;Date()&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;author&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;Integer&nbsp;viewNum&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;<span class="number">0</span><span>&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;Integer&nbsp;postNum&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;<span class="number">0</span><span>&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;lastUpdateTime&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;lastUpdateBy&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">static</span><span>&nbsp;&nbsp;hasMany&nbsp;&nbsp;=&nbsp;&nbsp;[&nbsp;posts&nbsp;:&nbsp;Post&nbsp;]&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">static</span><span>&nbsp;&nbsp;fetchMode&nbsp;&nbsp;=&nbsp;&nbsp;[author:&nbsp;</span><span class="string">'&nbsp;eager&nbsp;'</span><span>&nbsp;,&nbsp;lastUpdateBy:&nbsp;</span><span class="string">'&nbsp;eager&nbsp;'</span><span>&nbsp;]&nbsp;</span></span></li><li><span>}&nbsp;</span></li></ol></pre>
<p>但从SQL Log来看，Grails还是执行了3条SQL：</p>
<pre><ol class="dp-sql"><li class="alt"><span><span class="keyword">select</span><span>&nbsp;...&nbsp;</span><span class="keyword">from</span><span>&nbsp;topic&nbsp;</span><span class="keyword">where</span><span>&nbsp;id&nbsp;&nbsp;=&nbsp;?&nbsp;</span></span></li><li><span><span class="keyword">select</span><span>&nbsp;...&nbsp;</span><span class="keyword">from</span><span>&nbsp;</span><span class="func">user</span><span>&nbsp;</span><span class="keyword">where</span><span>&nbsp;id&nbsp;&nbsp;=&nbsp;?&nbsp;</span></span></li><li class="alt"><span><span class="keyword">select</span><span>&nbsp;...&nbsp;</span><span class="keyword">from</span><span>&nbsp;</span><span class="func">user</span><span>&nbsp;</span><span class="keyword">where</span><span>&nbsp;id&nbsp;&nbsp;=&nbsp;?&nbsp;</span></span></li></ol></pre>
<p>也就是说在domain类中配置延迟加载存在对one-to-one, many-to-one是无效的。</p>
<p>如果这样配置：</p>
<pre><ol class="dp-j"><li class="alt"><span><span class="keyword">class</span><span>&nbsp;&nbsp;&nbsp;Topic&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;title&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;body&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;createTime&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;<span class="keyword">new</span><span>&nbsp;&nbsp;Date()&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;author&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;Integer&nbsp;viewNum&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;<span class="number">0</span><span>&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;Integer&nbsp;postNum&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;<span class="number">0</span><span>&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;lastUpdateTime&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;lastUpdateBy&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">static</span><span>&nbsp;&nbsp;hasMany&nbsp;&nbsp;=&nbsp;&nbsp;[&nbsp;posts&nbsp;:&nbsp;Post&nbsp;]&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">static</span><span>&nbsp;&nbsp;fetchMode&nbsp;&nbsp;=&nbsp;&nbsp;[posts:&nbsp;</span><span class="string">'&nbsp;eager&nbsp;'</span><span>&nbsp;]&nbsp;</span></span></li><li><span>}&nbsp;&nbsp;</span></li></ol></pre>
<p>执行Topic.get(id)来加载1条Topic，执行结果为1条SQL：</p>
<pre><ol class="dp-sql"><li class="alt"><span><span class="keyword">select</span><span>&nbsp;...&nbsp;</span><span class="keyword">from</span><span>&nbsp;topic&nbsp;</span><span class="func">left</span><span>&nbsp;</span><span class="op">outer</span><span>&nbsp;</span><span class="op">join</span><span>&nbsp;post&nbsp;</span><span class="keyword">on</span><span>&nbsp;topic.id&nbsp;=&nbsp;posttopic_id&nbsp;</span><span class="keyword">where</span><span>&nbsp;topic.id&nbsp;=&nbsp;?&nbsp;&nbsp;</span></span></li></ol></pre>
<p>也就是说在domain类中配置延迟加载存在对one-to-many是有效的。以上结论对使用mapping来配置也是一样的。</p>
<p>这无疑是一个尴尬的结论，适用全局立即加载的author和lastUpdateBy不能在domain类中通过配置事先，不适用全局立即加载的posts却可以。看来GROM对Hibernate的包装还存在问题。</p>
<p>目前的解决方法是不要在domain类中配置立即加载，而是在取数据的方法中按需要配置，例如Topic.list(fetch:[author:'eager', lastUpdateBy:'eager'])</p>
<p>另外，可以参考一下<a target="_blank" href="http://robbin.javaeye.com/blog/77338">这里</a>关于立即加载和N+1次查询性能的争论。</p>]]></description>
			<link>http://www.eoss.cn/blog/grails_notes_1/</link>
			<category domain="http://www.eoss.cn/blog/category/java/">Java</category>
			<pubDate>2008-11-26 16:29</pubDate>
		</item>
		<item>
			<guid>http://www.eoss.cn/blog/play_with_play_1/</guid>
			<title>Play with Play! - 一个Rails-like的Java框架</title>
			<author>shine</author>
			<description><![CDATA[乐在其中 ( http://www.eoss.cn/blog/ ) : <p>由于Java语言的局限性，实现一个Rails-like的Java开发框架一直是一个难题。在Java上想体验Rails-like的开发模式，只能选 择Grails或者JRuby on Rails。然而这两种框架都是动态语言实现的框架，只是基于JVM而不是基于Java语言本身。动态语言确实有很多优点，但往往难以调试。是否有一个 Java语言实现的Rails-like框架？答案是<a target="_blank" href="http://www.playframework.org">Play!</a><br />
<br />
Play!是一个full-stack Java Web应用框架，包括一个简单无状态的MVC模型，Hibernate的持久性对象，基于Groovy的模板引擎，以及建立一个现代化网络应用所需的一 切。注意，这里虽然使用了Groovy，但只是是作为页面模板语言，这和freemaker、velocity使用自己定义的语言是同样的道 理，Groovy的成熟以及它和Java的相似性决定了采用Groovy远远好于自己定义一个语言。<br />
<br />
Play!的主要特性：</p>
<ul>
    <li>简单的开发周期。该框架可自动编译和重新装载已改变的源文件。也就是说在保存源代码的改变后，就能立刻从浏览器中看到结果，不需要重新编译、部署、重启服务器。</li>
    <li>约定优于配置。</li>
    <li>智能绑定HTTP参数到Java方法参数。</li>
    <li>无状态的模型，无共享架构（Share-Nothing Architecture），为REST做好了准备（未来的目标是RESTful架构），具有很好的伸缩性。</li>
    <li>一个基于Groovy的强大的模板引擎，可实现多层继承，定制用户标签等功能。</li>
    <li>包含了很多开发Web应用需要的功能整合，如Memcached、OpenID、插件系统等。</li>
    <li>优秀的错误报告功能：发生异常时，该框架会直接显示出错误的源代码，甚至是模板代码。</li>
    <li>纯Java，能够使用任何Java类库，能够很好的生成eclipse和netbeans项目文件。</li>
    <li>速度很快。</li>
</ul>
<p>初步看了下文档，应该是目前最接近Rails的Java framework，整个框架和我最近设想的一个框架差不多，很多简化 Java Web开发会遇到的问题，play!都给出了一个尽可能的解决方法，比如HTTP参数绑定、属性get/set等等，局限于java语言本身，目前也只能 这样了。play!目前还没有集成验证功能，也没有一些诸如HTML encode的工具库，和spring的集成也好像还在开发中，不过这些都应该很容易解决。</p>
<p>该项目是开源的，您可以在<a href="http://www.playframework.org" target="_blank">http://www.playframework.org</a>上查看更多！</p>]]></description>
			<link>http://www.eoss.cn/blog/play_with_play_1/</link>
			<category domain="http://www.eoss.cn/blog/category/java/">Java</category>
			<pubDate>2008-11-19 16:22</pubDate>
		</item>
		<item>
			<guid>http://www.eoss.cn/blog/displaytag_number_sort/</guid>
			<title>DisplayTag数字排序问题的解决方法</title>
			<author>shine</author>
			<description><![CDATA[乐在其中 ( http://www.eoss.cn/blog/ ) : <div class="postText">
<p dir="ltr" style="margin-right: 0px;">在使用displaytag显示数字时，如果对数字进行了HTML包装，那么就有可能造成排序结果的不正确。<br />
<br />
displaytag排序的方法是：compare(Object object1, Object object2)<br />
1.如果object1,object2都是String，则按String排序；<br />
2.如果object1,object2实现了Comparable接口，则compareTo方法比较，这样纯数字排序因为能够转换成实现Comparable接口的数字类型所以排序结果正确；<br />
3.其他情况转换成String比较。</p>
<p>因此，组装成HTML的列就默认按String来比较，造成排序结果与预期不符。<br />
例如需要排序displaytag中带超级链接的数字列：<br />
s1: &lt;a href=&quot;www.example.com?id=53&quot;&gt;53&lt;/a&gt;<br />
s2: &lt;a href=&quot;www.example.com?id=9&quot;&gt;9&lt;/a&gt;<br />
则比较结果s1 &lt; s2，显然和我们预期的相反。</p>
<p>解决的方法:<br />
1.自定义一个Comparator类，实现你自己的比较规则，在页面需要的列中配置&lt;display:column title=&quot;...&quot; property=&quot;...&quot; comparator=&quot;你实现的Comparator类名&quot;&gt;<br />
2.外排序<br />
3.如果只是需要把数字排正确，更简单的方法是写一个数字的format类，在decorator组装HTML时在数字前补0对齐：<br />
s1: &lt;a href=&quot;www.example.com?id=00053&quot;&gt;53&lt;/a&gt;<br />
s2: &lt;a href=&quot;www.example.com?id=00009&quot;&gt;9&lt;/a&gt;</p>
<p>另外，如果每列需要比较数字前的HTML不是相同的，可以添加隐藏域来解决。例如：<br />
s1: &lt;a href=&quot;www.example.com?id=100&quot;&gt;53&lt;/a&gt;<br />
s2: &lt;a href=&quot;www.example.com?id=200&quot;&gt;9&lt;/a&gt;<br />
修改为：<br />
s1: &lt;input type=&quot;hidden&quot; name=&quot;sortValue&quot; value=&quot;00053&quot;&gt;&lt;a href=&quot;www.example.com?id=100&quot;&gt;53&lt;/a&gt;<br />
s2: &lt;input type=&quot;hidden&quot; name=&quot;sortValue&quot; value=&quot;00009&quot;&gt;&lt;a href=&quot;www.example.com?id=200&quot;&gt;9&lt;/a&gt;</p>
</div>]]></description>
			<link>http://www.eoss.cn/blog/displaytag_number_sort/</link>
			<category domain="http://www.eoss.cn/blog/category/java/">Java</category>
			<pubDate>2008-11-05 16:28</pubDate>
		</item>
	</channel>
</rss>
