<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>Simplify your life</title>
    <description>一个J2EE Developer，熟悉Java及一堆杂七杂八的框架，喜欢的领域是Web开发、全文检索、Python。
喜欢上网，鼓捣稀奇古怪的软件，离开计算机和互联网无法生活
对VIM的使用比较熟悉，非常愿意与各位学习、讨论。
常在浩方上玩星际，ID不定（太菜）。</description>
    <link>http://fyting.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>dojo1.1的主要更新</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/183578" style="color:red;">http://fyting.javaeye.com/blog/183578</a>&nbsp;
          发表时间: 2008年04月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          dojo1.1发布也有些时日了，今天静下来看了看到底有哪些更新以及对项目的影响，顺便把<a href="http://dojotoolkit.org/book/dojo-1-1-release-notes" target="_blank">release notes</a>大体翻译了过来。<br /><br /><span style="font-size: x-large">Core</span><br /><br />    <span style="font-size: large">dojo.fromJson解析失败时，会抛出error，需要程序员手动try、catch</span><br />    <pre name="code" class="javascript">
        var result = text;
        try{
         result = dojo.fromJson(text);
        }catch(e){
         // squelch exception, use input as result
        }
    </pre><br /><br />    <span style="font-size: large">多版本支持</span><br />		dojo1.1可以与其他版本的dojo共存，甚至可以修改dojo的库名称，详细见:<a href="http://dojotoolkit.org/book/book-dojo/part-3-javascript-programming-dojo-and-dijit/multiple-versions-dojo-page" target="_blank">Dojo Book Page on multiversion support</a><br />    <span style="font-size: large">在DOM载入后再加载dojo</span><br />        设置djConfig.afterOnLoad = true，这是<a href="http://archive.dojotoolkit.org/nightly/dojotoolkit/dojo/tests/_base/_loader/afterOnLoad.html" target="_blank">测试页面</a> 没感觉到这个功能的用处，并且在DOM载入后如果移动鼠标有可能引起javascript，整个dojo都无法载入。<br />	<br />    <span style="font-size: large">XMLHttpRequest的变化</span><br />		以前那一堆dojo.xhrGet(), dojo.xhrPost(), dojo.xhrRawPost(), dojo.xhrPut(), dojo.xhrRawPut() 还有 dojo.xhrDelete()，现在终于有了一个通用的函数：dojo.xhr()。<br />		<br />		使用dojo.xhr*将发送名为“X-Requested-With”的http header，值为“XMLHttpRequest”<br /><br />    <span style="font-size: large">cacheBust</span><br />        如果设置djConfig.cacheBust = (new Date()).getTime()，载入模块和模板时，将把这个cacheBust的值将添加到URL中，防止浏览器缓存。在1.0里面其实已经存在，也是个不知所云的功能。<br /><br />    <span style="font-size: large">dojo.attr()</span><br />		新增加dojo.attr()，dojo.hasAttr()，还有dojo.removeAttr()函数，用于获取DOM节点的attribute<br /><pre name="code" class="javascript">
    var d1 = dojo.byId('div1');
    console.debug(dojo.attr(d1,"id"));
    console.debug("div1 has age?" + dojo.hasAttr(d1,"age"));
    dojo.attr(d1,"age",18);
    console.debug("div1 has age?" + dojo.hasAttr(d1,"age"));
    console.debug(dojo.attr(d1,"age"));
</pre><br />		<br />    <span style="font-size: large">dojo.style()</span><br />		dojo.style现在可以一次性设置多个css属性，以前是这样的：<br /><pre name="code" class="javascript">
    dojo.style(dojo.byId('div2'),"width","700px;");
    dojo.style(dojo.byId('div2'),"height","600px;");
</pre><br />        现在可以这样了：<br /><pre name="code" class="javascript">
    dojo.style(dojo.byId('div2'),{
        width:"700px",
        height:"600px",
        background:"#ccf"
    });
</pre><br /><br />	<br />    <span style="font-size: large">dojo.query/NodeList</span><br />		dojo.query()结果可以使用attr()、instantiate()，还有之前就可以使用的style()也可以使用上面的那种dojo.style()的用法了。<br /><pre name="code" class="javascript">
    dojo.style("thinger", {
        "opacity": 0.5,
        "border": "3px solid black",
        "height": 300
    });
</pre><br />        <br />		<br />    <span style="font-size: large">动画/animation</span><br />		修正了动画效果的性能问题，增加了一个新的dojo.anim()方法，默认的duration从1秒变成了350ms，简化了指定动画属性的语法。另外重写了dojo.fx.combine()和dojo.fx.chain()的集成，现在集成不同的动画效果更加简单。<br />        dojo.anim("id", { opacity: 0 }, 1000);<br />		<br />    <span style="font-size: large">Adobe AIR的支持</span><br />    1.1里面dojo提供了更好的AIR支持。<a href="http://www.dojotoolkit.org/air" target="_blank">http://www.dojotoolkit.org/air</a><br />		<br /><br /><span style="font-size: x-large">Dijit</span><br /><br />    <span style="font-size: large">widget模板的变化</span><br />		input类型的widget（包括ValidationTextBox, ComboBox等）的模板从&lt;table>转变成&lt;div>，因此自定义的样式也需要跟着修改了:(<br />		dijitTabInnerDiv的css class名字变成为了dijitTabContent<br />		Dialog,TooltipDialog的模板发生变化（触发关闭事件的名称从hide变成了onCancel，这说明把事件定义在模板里不是一个好的实践？）<br /><br />	<br />    <span style="font-size: large">themes/主题</span><br />		新的主题 nihilo<br />		soria终于完成了，貌似算dojo里比较好看的了……<br />		更新了原有的tundra主题（还是很难看）<br />		<br />    <span style="font-size: large">新的widget</span><br />    <ul><br />        <li>SimpleTextArea	不会自动改变大小的TextArea……</li>        <li>MultiSelect组件	就是个多选的列表框，不要报太大希望，功能上很简陋。</li>    </ul><br /><br />    <span style="font-size: large">Layout widgets</span><br />    新的<a href="http://dojotoolkit.org/book/book-dojo/part-2-dijit-dojo-widget-library/layout/border-container" target="_blank">BorderContainer</a>提供了更小巧的js文件、更平滑的缩放效果。SplitContainer和LayoutContainer已经是deprecated，请使用新的BorderContainer。<br /><br />    <span style="font-size: large">Tree</span><br />    做了大量BUG修复和改进工作，一些API已经被标注为deprecated。1.1里主要修复了1.0里面tree关于拖动的bug，改进了数据更新的问题，使用了新的dojo.data.ItemFileWriteStore。详细请点击<a href="http://www.dojotoolkit.org/2008/02/24/dijit-tree-and-dojo-data-dojo-1-1-model" target="_blank">这里</a><br /><br />    <span style="font-size: large">Dialog, TooltipDialog</span><br />		现在可以在其中放入TabContainer了，如果放入了Layout widgts，请千万不要在初始化方法里把整个dialog设置为style="display:none"，而是使用style="visibility:hidden"来代替。<br />		在dialog的DateTextBox里按ESC不会关闭dialog了。<br />		open dialog时，将把焦点放到第一个input组件里<br />		<br />    <span style="font-size: large">Features/Bug fixes</span><br />    <ul><br />        <li>highlighting/focus invalid fields on attempted form submit</li>		<li>separate edit and display mode for input widgets like NumberTextBox and CurrencyTextBox. For example, when editing US$ on an en-us locale machine, the $ sign and commas disappear</li>		<li>input widget formatting bugs fixed (use of table abandoned)</li>		<li>reset of forms now supported (must use dijit.Form widget)</li>    </ul><br />	<br />    <span style="font-size: large">Form widgets API更新与变化</span><br />	<br />        引入了新的setAttribute()，旧的方法被标注为deprecated：<br />		setDisabled(Boolean)	==>		setAttribute("disabled", Boolean)<br />		setChecked(Boolean)		==>		setAttribute("checked", Boolean)<br /><br />		原有的setValue()/getValue()更加贴近语义：<br />        获取value时使用getValue()，根据组件的不同而不同，尤其是CheckBox组件。<br />        由用户输入的值使用setValue，程序设置的值使用setAttribute("value", ...);<br /><br />		CheckBox.getValue()会根据checkbox的状态进行序列化。<br />			当CheckBox未选中时	==>		getValue()返回“false”<br />			其他时候返回CheckBox的“value”<br />		同样，CheckBox.setValue(Boolean)只会使CheckBox变为选中 or 未选中状态<br />		如果要改变CheckBox的值，请使用setAttribute("value",...)，同理对于Button也是如此<br />        <br /><br />		所有的form widget使用onFocus()/onBlur()，以前那一堆onblur,_onBlur等鬼东西现在走上正轨了。<br /><br />		自定义的Form widget需要从dijit.form._FormValueWidget继承，以前是使用的dijit.form._FormWidget。如果是CheckBox一类，不需要用户直接输入value的widget，可以从dijit.form._FormWidget继承。<br /><br />        dijit.Form widget fixes <a href="http://trac.dojotoolkit.org/ticket/5775" target="_blank" target="_blank">#5775</a><br /><br />	<br />    <span style="font-size: large">其他</span><br />		FireFox3兼容(屁话)<br />		允许指定tooltip的位置（above/below/before/after）<br />		Bidi: All widgets should now be BiDi-compliant and mirror properly when dir=rtl is set on the document <br />		A11y - basically everything except Grid accessible <br />	<br />    <span style="font-size: large">CSS class名称变化(自定义组件可能会受影响)</span><br />    See <a href="http://trac.dojotoolkit.org/ticket/6104" target="_blank">#6104</a><br />		IEFixedToolbar → dijitIEFixedToolbar <br />		dijitProgressBarVertical → dijitProgressBarV <br />		dijitProgressBarHorizontal → dijitProgressBarH <br />		RuleContainer → dijitRuleContainer <br />		HorizontalRuleContainer → dijitRuleContainerH <br />		VerticalRuleContainer → dijitRuleContainerV <br />		RuleLabel → dijitRuleLabel <br />		RuleLabelContainer → dijitRuleLabelContainer <br />		HorizontalRuleLabelContainer → dijitRuleLabelContainerH <br />		VerticalRuleLabelContainer → dijitRuleLabelContainerV <br />		HorizontalRuleLabel → dijitRuleLabelH <br />		VerticalRuleLabel → dijitRuleLabelV <br />		RuleMark → dijitRuleMark <br />		HorizontalRuleMark → dijitRuleMarkH <br />		VerticalRuleMark → dijitRuleMarkV <br />		dijitHorizontalSliderBar → dijitSliderBarH <br />		dijitVerticalSliderBar → dijitSliderBarV <br />		dijitVerticalSliderBottomBumper → dijitSliderBottomBumper <br />		dijitHorizontalSliderBumper → dijitSliderBumperH <br />		dijitVerticalSliderBumper → dijitSliderBumperV <br />		dijitVerticalSliderButtonContainer → dijitSliderButtonContainerV <br />		dijitHorizontalSliderButtonContainer → dijitSliderButtonContainerH <br />		dijitHorizontalSliderDecoration → dijitSliderDecorationH <br />		dijitVerticalSliderDecoration → dijitSliderDecorationV <br />		dijitHorizontalSliderImageHandle → dijitSliderImageHandleH <br />		dijitVerticalSliderImageHandle → dijitSliderImageHandleV <br />		dijitHorizontalSliderLeftBumper → dijitSliderLeftBumper <br />		dijitHorizontalSliderMoveable → dijitSliderMoveableH <br />		dijitVerticalSliderMoveable → dijitSliderMoveableV <br />		dijitHorizontalSliderProgressBar → dijitSliderProgressBarH <br />		dijitVerticalSliderProgressBar → dijitSliderProgressBarV <br />		dijitHorizontalSliderRemainingBar → dijitSliderRemainingBarH <br />		dijitVerticalSliderRemainingBar → dijitSliderRemainingBarV <br />		dijitHorizontalSliderRightBumper → dijitSliderRightBumper <br />		dijitVerticalSliderTopBumper → dijitSliderTopBumper <br />		dijitSplitterHorizontal → dijitSplitterH <br />		dijitSplitterVertical → dijitSplitterV <br />		dijitHorizontalSliderDecrementIcon → dijitSliderDecrementIconH <br />		dijitHorizontalSliderIncrementIcon → dijitSliderIncrementIconH <br />		dijitVerticalSliderIncrementIcon → dijitSliderIncrementIconV <br />		dijitVerticalSliderDecrementIcon → dijitSliderDecrementIconV<br /><br /><br /><span style="font-size: x-large">Dojox</span><br />	一些杂七杂八的东西，有些早已存在又拿出来说，没有翻译……<br />	DTL<br />	Many improvements to the detail library. The upshot is that you can now declare widgets where the templates have for loops, if statements, etc. For example: <br /><pre name="code" class="javascript">

	templateString: '&lt;div>&lt;input dojoAttachEvent="onkeyup: keyUp">&lt;ul>{% for item in items %}&lt;li>${oldRepl} {{ item }}&lt;/li>{% endfor %}&lt;/ul>&lt;/div>'
	See the demos for examples.
</pre><br /><br />	GFX<br />	animations for GFX, so you can animate strokes, fills, etc. See the career test example.<br />	- sketch: a drawing program on the web<br /><br />	DojoX Charting<br />	Soften your line charts by adding a "tension" property to the object used to add a plot (.addPlot); the lower the tension, the looser the curves. For best results, try a tension around 3; see the main chart test for examples.<br /><br />	dojox.lang.functional<br />	new package for functional idioms like lambda, reduce, etc.<br /><br />	Crypto merged with encoding<br />	The original dojox.crypto package has been merged with the newer DojoX encoding project; dojox.crypto will be entirely removed by release 1.2.<br /><br />	DojoX FX Easing functions<br />	Robert Penner donated his easing functions to dojo, see the dojo-moj-oe post.<br /><br />	dojox.highlight<br />    客户端代码高亮组件，语法是&lt;code>xxxx&lt;/code>，可以用在dojo1.0及以上版本（dojo > 0.9?)	<br /><br />	dojox.data<br />	new dojox.data stores<br /><br />	Storage<br />	Flash storage ported from 0.4<br /><br />	Jaxer<br />	???<br /><br />	- more NodeList animations<br />	<br />	DojoX Widgets<br />		New widgets:<br /><br />		FisheyeLight: 类似于Mac Dock的东西，比之前的版本更小巧，速度更快。<br />		Wizard - 向导组件（上一步、下一步），从0.4来的。<br />		ScrollPane - 根据鼠标位置自动移动的面板<br />		DragPane - 能拖动内容的面板，就像PDF Reader<br />		Magnifier 放大镜<br />		CheckedMultiSelect - like a select with multiple=true but displays checkboxes for each item <br />	Updated:<br /><br />		Lightbox<br /><br /><br /><span style="font-size: x-large">Util (buildscripts)</span><br /><br />	新的构建选项<br />    <ul><br />    <li>cssOptimize：设置cssOptimize=comments将去除CSS里所有空白，并根据@import规则，把所有CSS文件压缩为一行</li>	<li>cssImportIgnore：设置cssOptimize里需要忽略掉的css文件。使用逗号分开，路径与@import的url一致</li>	<li>buildLayers：只重新构建某些layer，用法是buildLayers=[comma separated list of layer names]</li>	<li>symbol：symbol=short 和 symbol=long将为所有匿名函数添加一个名称，主要方便调试</li>	<li>dojo多版本并存有一些相关选项，请参考http://dojotoolkit.org/book/book-dojo/part-3-javascript-programming-dojo-and-dijit/multiple-versions-dojo-page</li>	<li>Rhino builds：指定Rhino为host environment，代替普通的浏览器环境。</li>    </ul><br />	<br /><br /><br />    下载地址 <a href="http://www.dojotoolkit.org/downloads" target="_blank">http://www.dojotoolkit.org/downloads</a><br />		<br />整个dojo1.1，总体是在1.0的基础上进行了大量BUG FIX工作，据说修复了<a href="http://trac.dojotoolkit.org/milestone/1.1" target="_blank">800个BUG</a>。变动稍大的部分是widget的表单组件，由于一些方法名称、模板的变更(table->div)以及CSS的变化，对于自定义组件的影响还是挺大的，有很多自定义的CSS需要重新写，有些可能需要修改代码。<br />开始对过度设计进行弥补，比如SimpleTextArea这东西就是个普通的TextArea，以前的TextArea会自动改变大小，导致Grid里一行撑很高，纯粹没事找抽。Grid里移动鼠标时老是自动晃的功能也去了，谢天谢地。<br />在可用性方面有所提升，很多Form组件增加了布局相关的代码，比如resize方法。soria主题看起来也比原来的tundra稍微好看，不过要打到ext的那种漂亮程度和像素级精度还很远。<br /><br /><div class="quote_title">引用</div><div class="quote_div">原作者 Kenny，转载请注明出自 <a href="http://www.fyting.com" target="_blank">http://www.fyting.com</a>，非常感谢。</div>
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/183578#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 17 Apr 2008 04:25:07 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/183578</link>
        <guid>http://fyting.javaeye.com/blog/183578</guid>
      </item>
      <item>
        <title>早晨上班时累了个半死</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/170183" style="color:red;">http://fyting.javaeye.com/blog/170183</a>&nbsp;
          发表时间: 2008年03月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          昨晚又看到凌晨3点才睡，早晨起床冲了个澡上班。还没到公交站，发现车来了，于是一路奔过去。上车后，很累，觉得全身无力，靠在扶手边站着。前面座位上的同事发现了我，和我打招呼，我却喘不过气来。以前长跑都不至于这样呀，现在却一阵恶心，而且这感觉越来越厉害。同事把座位让给了我，本以为坐着就会好些，可恶心的感觉越来越厉害，头也很晕，似乎快窒息了。我趴在前面靠背上，大口大口地呼吸，身上一直出冷汗，越来越难受，只想往地上躺。我跟同事说，送我去医院，他还以为我开玩笑。没力气再说话了，我突然想起了华为累死的那哥们儿，突然很后悔那么迟睡觉。我祈祷着，希望可以没事，我以后一定会早点休息的，再也不跑了。后来车窗打开了，呼吸着新鲜空气，直到有人叫我把头伸进来。现在想起来，那个情景竟然很模糊，只记得车窗开了，我趴在上面。可能是车外冷空气的原因，慢慢感觉好了，我迷迷糊糊地睡着了。谢天谢地，躲过了一劫……<br />想起来还心有余悸，以后一定要在平常好好爱惜自己，别在快失去时，才后悔当初……<br /><br />搞这一行的很多人都睡很迟，发到论坛里，也是想提醒大家，记得早点休息。<img src="/images/smiles/icon_smile.gif"/>
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/170183#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 11 Mar 2008 14:13:24 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/170183</link>
        <guid>http://fyting.javaeye.com/blog/170183</guid>
      </item>
      <item>
        <title>SQLServer2005获取大数据集时内存不足的解决办法</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/166988" style="color:red;">http://fyting.javaeye.com/blog/166988</a>&nbsp;
          发表时间: 2008年03月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="font-size: small">原作者: <a href="http://fyting.javaeye.com" target="_blank">fyting</a>，转载请注明原文地址: <a href="http://fyting.javaeye.com/blog/166988" target="_blank">http://fyting.javaeye.com/blog/166988</a> </span><br /><br />使用jdbc读取SQLServer2005的一个表全部记录，该表具有10W记录，结果发生以下错误：<br /><pre name="code" class="java">
com.microsoft.sqlserver.jdbc.SQLServerException: 系统内存不足。请对大型 ResultSet 使用服务器端游标: Java heap space。ResultSet 大小:236,535,956。JVM 总内存大小:312,213,504。
	at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(Unknown Source)
	at com.microsoft.sqlserver.jdbc.DBComms.receive(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerStatement.doExecuteStatement(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerStatement$StatementExecutionRequest.executeStatement(Unknown Source)
	at com.microsoft.sqlserver.jdbc.CancelableRequest.execute(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeRequest(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeQuery(Unknown Source)
</pre><br />使用以下代码无效<br /><pre name="code" class="java">
Statement stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(100);
</pre><br />查文档得知与sqlserver jdbc驱动的select Method有关。selectMethod分为direct和cursor。当使用direct时，驱动会一次性载入所有结果集到jvm内存中，因此造成了out of memory；而使用cursor时，会在服务器端创建一个cursor，因此不会占据客户端的大量内存，办法有两种：<br /><ol><li>修改SQLServer2005 jdbc的URL: jdbc.url=jdbc:sqlserver://127.0.0.1;instanceName=ProductDB;databaseName=product_index;<span style="color: red">selectMethod=cursor</span></li><br />这种方式会影响整个应用程序，可能引起其他普通情况的读取性能下降。<li>使用如下代码</li><pre name="code" class="java">Statement stmt = con.createStatement(SQLServerResultSet.TYPE_SS_SERVER_CURSOR_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);</pre><br />这种方式会造成SQLServer的API侵入，但不失为一种更好的办法。<br /></ol><br />参考文档：<br /><a href="http://msdn2.microsoft.com/en-us/library/ms378405.aspx" target="_blank">http://msdn2.microsoft.com/en-us/library/ms378405.aspx</a><br /><a href="http://msdn2.microsoft.com/en-us/library/ms378988.aspx" target="_blank">http://msdn2.microsoft.com/en-us/library/ms378988.aspx</a>
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/166988#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 03 Mar 2008 16:27:22 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/166988</link>
        <guid>http://fyting.javaeye.com/blog/166988</guid>
      </item>
      <item>
        <title>dojo Quick Start</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/152117" style="color:red;">http://fyting.javaeye.com/blog/152117</a>&nbsp;
          发表时间: 2008年01月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          转载请注明出处 <a href="http://www.fyting.com" target="_blank">http://www.fyting.com</a>,谢谢<br />2006年初，dojo还是0.22的时候就很关注它的发展，可一直没有在实际项目中使用。一来是由于文档的缺少，而来是dojo的相关介绍总是让人望而生畏。到现在都如此，第一个hello world就搞了一大堆东西，比如widget组件，自定义的script标签等，加上要引入什么css文件，djConfig、dojo.require等等，让人很迷惑，这么复杂，到底dojo该怎么使用呢？我只是想把dojo当作一个普通的js类库，就像prototype那样？OK，闲话少说，来看看如何使用dojo。<br /><br /><strong><span style="font-size: 18pt">第一步，引入dojo.js</span></strong><br />dojo的发行包里有4个子目录，要引入的文件是名叫"dojo"的子目录里的dojo.js。<br />假设你是这样的目录结构:<br /><div class="quote_title">引用</div><div class="quote_div"><br />project<br />|<br />+--dojo-lib<br />|     |<br />|     +--dijit<br />|     +--dojo<br />|     +--dojox<br />|     +--util<br />|<br />+--dojo_hello_world.html<br /></div><br /><br /><pre name="code" class="java">&lt;script type="text/javascript" src="./dojo-lib/dojo/dojo.js">&lt;/script></pre><br /><br /><br /><br /><strong><span style="font-size: 18pt">开始使用dojo</span></strong><br />现在开始使用dojo的第一个函数:dojo.byId<br />dojo.byId就等同于常用的document.getElement<br />&lt;input type="text" name="username" id="username" value="Mark" /><br />&lt;script type="text/javascript"><br />var username = dojo.byId('username').value<br />alert(username);<br />&lt;/script><br />OK，是不是和普通的js库一样，没有任何玄机？<br /><br /><br /><br /><strong><span style="font-size: 18pt">dojo.addOnLoad</span></strong><br />现在我们想在window.onload里面处理一点东西，就像Ext.onReady，这个东西在dojo里叫做dojo.addOnLoad<br /><pre name="code" class="java">dojo.addOnLoad(function(){
	var username = dojo.byId('username').value
	alert(username);
});</pre><br /><br /><br /><br /><strong><span style="font-size: 18pt">dojo.connect</span></strong><br />OK，window.onload搞定了，那么如何监听普通的dom事件呢？没问题，强大的dojo.connect出场<br /><pre name="code" class="java">
&lt;script type="text/javascript">
function sayHello(event)
{
	alert("Hello");
}
dojo.addOnLoad(function(){
	var btn = dojo.byId('hello');
	dojo.connect(btn,"onclick",sayHello);
});
&lt;/script>
&lt;input type="button" id="hello" value="Hello" />
</pre><br /><br />是不是和prototype的Event.observe($('btnAdd'), "load", doAdd)差不多?<br />用prototype时最烦的就是那个长长的bindAsListener了，使用dojo.conncect，可以在第三个参数中指定当前的scope：<br /><pre name="code" class="java">
var name = "Mark"
function sayHello()
{
	alert("Hello " + this.name);
}
var obj = {
	name: "Karl"
}
dojo.addOnLoad(function(){
	var btn = dojo.byId('hello');
	dojo.connect(btn,"onclick",obj,sayHello);//注意这行的第三个和第四个参数
});
</pre><br />OK，点击按钮，将输出：Hello Karl<br />这里dojo.connect的第三个参数变成了scope，而handler函数是第四个，实际上<br />dojo.connect(btn,"onclick",sayHello);<br />与<br />dojo.connect(btn,"onclick",null,sayHello);<br />相同。<br />更加复杂的用法这里不作介绍，写太多就越搞越复杂了，后面再写文章详细介绍dojo.connect，这里只简单介绍如何绑定DOM事件。<br /><br /><br /><br /><strong><span style="font-size: 18pt">xmlhttp dojo.xhrGet</span></strong><br />OK，介绍了简单的DOM操作方法，接下来该到Ajax的传统项目-XmlHttp了<br />在使用xmlhttp时，需要注意到编码的问题，要让dojo默认绑定为utf-8怎么办呢？很简单，只需要修改一下引入dojo.js时的标签：<br /><br /><pre name="code" class="java">&lt;script type="text/javascript" src="./dojo-lib/dojo/dojo.js" djConfig="isDebug:true,bindEncoding:'UTF-8'">&lt;/script></pre><br />多了一个djConfig属性，很简单，第一个isDebug是说是否打开FireBug的Console，第二个是xmlhttp使用的编码。第二个才是重点，设置了就一劳永逸了。<br /><br />这次我们要点击了hello按钮后发出一个xmlhttp请求:<br /><pre name="code" class="java">function sayHello() {
    dojo.xhrGet({
        url: "http://localhost/hello/sayHello.jsp",
        handleAs: "text",
        load: function(responseText)
        {
          alert(responseText);
          dojo.byId("divHello").innerHTML = responseText;
        },
        error: function(response)
        {
          alert("Error");
        }
    });
}
dojo.connect(btn,"onclick",sayHello);</pre><br /><br />看看，够不够一目了然？<br /><br />url             就是url……<br />handleAs        把获取的内容作为text/html<br />load            成功时的回调函数<br />error           失败时的回调函数<br /><br /><br /><em><span style="font-size: 18pt">那如果要传入参数怎么办</span>?</em><br /><pre name="code" class="java">
var params = {
    username:'Mark',
    id:'105'
}
dojo.xhrGet({
    url: "http://localhost/hello/sayHello.jsp",
    content:params,
    //...
});
</pre><br />注意那个content参数，你要传入的参数是个关联数组/object，dojo会自动把参数解析出来，要使用post方法？<br />dojo.xhrGet  --->   dojo.xhrPost<br />其他的还有<br />dojo.xhrPut<br />dojo.xhrDelete<br /><br /><br /><em><span style="font-size: 18pt">json</span></em><br />那要是我想更换获取到的数据类型，比如json？xml？<br />修改handleAs即可，如：<br />handleAs: "json"<br /><pre name="code" class="java">
dojo.xhrGet({
    url: "http://localhost/hello/sayHello.jsp",
    handleAs: "json",
    load: function(json)
    {
        alert(json.name)
    }
    //...
});
</pre><br /><div class="quote_title">引用</div><div class="quote_div"><br />handleAs: "json-comment-filtered"                       使用注释符号/**/把json数据包含起来,推荐使用<br />handleAs: "json-comment-optional"                       首先尝试使用json-comment-filtered,如果执行错误,再使用普通的json格式解析<br />handleAs: "javascript"                                  dojo尝试把服务器返回的数据当作javascript执行,并把结果作为参数传递给load函数<br />handleAs: "xml"                                         xml对象。注意在Mozilla和IE中的xml是不同的，推荐使用<a href="http://sarissa.sourceforge.net/" target="_blank">sarissa</a><br /></div><br /><br />至于json和object的转换等，在http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/other-miscellaneous-function/converting-json有一个表格，应该能找到你需要的。<br /><br /><br /><em><span style="font-size: 18pt">想要直接提交一个表单</span></em>,就这样:<br /><pre name="code" class="java">
dojo.xhrGet({
    url: "http://localhost/hello/sayHello.jsp",
    form: dojo.byId("form1")
    //...
});
</pre><br />要解决IE下那个臭名昭著的<em>缓存问题</em>，就这样,preventCache会帮你自动生成一个timestamp<br /><pre name="code" class="java">
dojo.xhrGet({
    url: "http://localhost/hello/sayHello.jsp",
    preventCache: true
    //...
});
</pre><br /><br /><br /><br /><strong><span style="font-size: 18pt">dojo.hitch scope/context</span></strong><br />既然用到了xmlhttp，一个常见的问题就是回调函数的scope/context。在prototype、mootools里我们常用Function.bind，在dojo中，做相同事情的东西叫做dojo.hitch<br /><pre name="code" class="java">
var handler = {
    name:'Mark',
    execute1: function(){
        dojo.xhrGet({
            url: "http://localhost/hello/sayHello.jsp",
            handleAs: "text",
            error: function(text)
            {
                console.dir(this);
                alert(this.name);//输出undefined,这里的this表示当前io参数
            }
            //...
        });
    },
    load: function(text){
        alert(this.name);
    },
    execute2: function(){
        dojo.xhrGet({
            url: "http://localhost/hello/sayHello.jsp",
            handleAs: "text",
            error: dojo.hitch(this,"load") //输出Mark 
            //error: dojo.hitch(this,this.load); //与上一句相同,知道为什么要用方法名字而不是引用了吧?省去了长长的一串this.xxx
            //...
        });
    }
}
</pre><br /><br />OK，基本的东西解决了，还有很多常用的函数没有介绍，比如：dojo.query，dojo.forEach，dojo.marginBox，dojo.contentBox等等<br />这个就没事翻翻dojo.js.uncompressed.js源代码，dojo的文档是没啥好指望的了。<br /><br /><br /><br /><strong><span style="font-size: 18pt">面向对象,定义Class</span></strong><br />下一步我们看看dojo里如何定义Class：<br /><pre name="code" class="java">
dojo.declare("Customer",null,{
    constructor:function(name){
        this.name = name;
    },
    say:function(){
        alert("Hello " + this.name);
    },
    getDiscount:function(){
        alert("Discount is 1.0");
    }
});

var customer1 = new Customer("Mark");
customer1.say();
</pre><br />declare有三个参数:<br />第一个                    class名字<br />第二个                    父类的引用<br />第三个                    ...<br /><br /><em><span style="font-size: 18pt">构造函数</span></em>的名字就叫做"construnctor"<br /><br /><br /><em><span style="font-size: 18pt">再来看看如何继承</span></em>:<br /><br /><pre name="code" class="java">dojo.declare("VIP",Customer,{
    getDiscount:function(){
        alert("Discount is 0.8");
    }
});
var vip = new VIP("Mark");
vip.say();
vip.getDiscount();</pre><br /><br /><br />那么，如何<em><span style="font-size: 18pt">调用父类的方法</span></em>呢。使用this.inherited方法<br /><br /><pre name="code" class="java">
dojo.declare("VIP",Customer,{
    getDiscount:function(){
        this.inherited(arguments);
        //this.inherited("getDiscount",arguments);
    }
});
</pre><br /><br /><br /><em><span style="font-size: 18pt">关于构造函数</span></em>:<br />父类构造函数总是被自动调用的，所以看下面的例子:<br /><br /><pre name="code" class="java">dojo.declare("Customer",null,{
    constructor:function(name){
        this.name = name;
        alert("base class");
    },
    say:function(){
        alert(this.name);
    }
});

dojo.declare("VIP",Customer,{
    constructor:function(age){
        this.age = age;
        alert("child class");
    },
    say:function(){
        alert("name:" + this.name);
        alert("age:" + this.age);
    }
});

var vip = new VIP("123");//1
vip.say();//2
</pre><br />1将打印出两条alert语句，先是父类的构造函数，再是子类的。<br />2将输出"name: 123"  "age: 123"<br />个人认为，这个特性并不好，因为javascript这种弱类型的语言中，根本无法确定构造函数中的参数是传递给谁的，就比如上面的语句执行后，name="123",age="123"，那哪个才是正确的？这个问题在使用dojo Grid的model里就很麻烦，定义一个model得这样:new dojox.grid._data.Table(null,null,data);我要是想扩展这个Model，更麻烦，所有子类的构造函数都被父类给搞乱了。所以推荐的做法是使用关联数组作为构造函数的参数，就像Python里的关键字参数。<br /><br /><pre name="code" class="java">constructor:function(args){
    var args = args || {};
    this.name = args.name;
    this.age = args.age;
}
</pre><br /><br /><br /><em><span style="font-size: 18pt">多继承,mixin</span></em><br />说到继承，多继承的问题又来了。dojo支持多继承，准确地说，是mixin。还记得dojo.declare的第二个参数吗，就是表示父类的那个参数，这个参数可以是一个数组，数组的第一个元素作为声明的类的父类，其他的作为mixin。子类自动获得父类和mixin的所有方法，后面的mixin的同名方法覆盖前面的方法<br /><pre name="code" class="java">
dojo.declare("Customer",null,{
    say:function(){
        alert("Hello Customer");
    },
    getDiscount:function(){
        alert("Discount in Customer");
    }
});

dojo.declare("MixinClass",null,{
    say:function(){
        alert("Hello mixin");
    },
    foo:function(){
        alert("foo in MixinClass");
    }
});
dojo.declare("VIP",[Customer,MixinClass],{
});
var vip = new VIP();
vip.getDiscount();
vip.foo();
vip.say();//输出"Hello MixinClass"
</pre><br /><br />其他的比较有用的函数就是dojo.mixin和dojo.extend了，顾名思义，一个是作用于对象实例，一个是用于扩展class，翻文档和源码吧。<br /><br /><br /><br /><strong><span style="font-size: 18pt">package机制</span></strong><br />说完了dojo里的类继承机制，不得不说说package机制。<br />主要用到的有<br />dojo.require<br />dojo.provide<br />dojo.registerModulePath<br /><br /><br /><em><span style="font-size: 18pt">dojo.require</span></em><br />dojo.require就是引入相应路径文件下的js文件，现在已经有很多library这样做了。现在我们假设要用<br />project/dojo-lib/dojo/string.js<br /><br />dojo中的顶层目录就是dojo.js所在目录的上一层,即"project/dojo-lib/"，而dojo.js放在<br />project/dojo-lib/dojo/dojo.js<br />所以我们就这样:<br />dojo.require("dojo.string");<br />比如要引用其他目录下的:<br />project/dojo-lib/dojox/dtl/_base.js，则这样：dojo.require("dojox.dtl._base");<br /><br />project/dojo-lib/dojox/grid/Grid.js         dojo.require("dojox.grid.Grid");<br /><br />说白了，就和ruby之类的require很相似。<br /><br /><em><span style="font-size: 18pt">dojo.provide</span></em><br />要自己编写一个package怎么办，那就利用dojo.provide。比如要写在：<br />project/dojo-lib/com/javaeye/fyting/Package1.js<br />那么在对应的Package1.js中第一行需要这样写:<br />dojo.provide("com.javaeye.fyting.Package1");<br /><br />类似java里的package声明，是吧？<br /><br /><em><span style="font-size: 18pt">dojo.registerModulePath</span></em><br />那要是我写的js文件不想和dojo放在一起怎么办呢，那就用registerModulePath。假设要放在：<br />project/js/com/javaeye/fyting/Package2.js<br /><br />Package2.js和上面的Package1.js一样的写法，不需要作特殊变化，就这样就行：<br />dojo.provide("com.javaeye.fyting.Package2");<br /><br />在使用时，需要指名这个Package2.js所在的位置，<br />dojo.registerModulePath("com","../../js/com");<br />只需要注意这里的相对路径是相对dojo.js来的。<br /><br />我们假设所有以com.javaeye开头的js都放在一起，而com.microsoft的放在另外的地方，为了防止冲突，可以这样:<br />dojo.registerModulePath("com.javaeye","../../js/com/javaeye");<br />dojo.registerModulePath("com.microsoft","../../javascript/com/microsoft");<br /><br />总得来说，package机制是开发大型项目必须的，但是造成了调试困难，使用dojo.require引入js出错时，根本不知道是什么原因，所以调试时最好手动引入js，dojo的test也是这么搞的。还有js框架中的各种实现类继承的手法，也造成调试困难，dojo还随地抛出个Error，又缺少java那样的error statck，根本不知道错误根源在哪儿。所以，期待js原生地支持这些^^<br />完整的代码文件在附件里，一个是含有dojo-1.0.2的，一个是没有dojo的
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/152117#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 01 Jan 2008 04:42:09 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/152117</link>
        <guid>http://fyting.javaeye.com/blog/152117</guid>
      </item>
      <item>
        <title>SOA的疑惑，SOA的定义是什么</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/133002" style="color:red;">http://fyting.javaeye.com/blog/133002</a>&nbsp;
          发表时间: 2007年10月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          打算等先把理论方面的书和文章看完再去找人请教这个问题。但有些人或者某些书作者的理解是什么？就==WebService？那我实现一个系统，对外使用平常的servlet发布普通的xml、json数据或者使用hessian，其它客户端接收这些数据，或再作一些转换处理，算不算一个SOA架构？也就是说WebService或者说很多言论中指代的WSDL只不过是一个相对比较完善的框架而已？只是比自制的xml完善一些？比如拥有完整的远程事务处理，同步异步接收机制（不清楚是否有这个）？或者说就是RMI的xml版？也即是问，WebService到底在SOA架构中扮演什么作用？也许需要有一套SOA理论基础，切实理解了SOA才能搞清楚这些问题。当前的理解就是，SOA是一种思想或一种架构体系，正如其名，面向服务的，只是突然觉得SOA如此简单，在很久之前的项目过程中已经产生或者尝试实践了这样的架构，难道我已经实现了伟大的SOA而不知道？最不能理解的就是很多人把SOA和WebService混为一谈，特别是只要采用了WebService就谈到实现了SOA是我所不能理解，反正很多人开口闭口就是SOA、WebService，为什么要使用，使用前后的对比，使用后的好处在哪里，又说不上来。到底如何，等看了书来说吧。闷得慌，写出来，权作一记录，一空想家的记录。
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/133002#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 18 Oct 2007 00:17:58 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/133002</link>
        <guid>http://fyting.javaeye.com/blog/133002</guid>
      </item>
      <item>
        <title>找工作的搞笑二三事</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/124482" style="color:red;">http://fyting.javaeye.com/blog/124482</a>&nbsp;
          发表时间: 2007年09月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          前日看到国内某大公司招人，招聘信息里直接注明了具体薪酬待遇，特牛。遂精心组织了一份简历发过去，半个小时后便得到回复，消息显示：对不起，您发送的邮件无法到达，原因是对方邮箱已满…… <br /><br />之前还遇到过更牛的公司:<br />上上周没投过简历，但一家公司打电话叫去面试，时间是在周二下午6:30，奇怪，大家都下班了才面试，这公司的人都加班？ <br />还是去了，在一商住两用楼里，进去一股方便面味道，几个人拿着饭盒走来走去。心想糟了，加班不少。 <br />仔细一看，有个乒乓球台，几个美女在嚷着争一个球，让我不得不对这里有那么一点点动心了。 <br />开始做笔试题，嗯，除了老掉牙的接口，面向对象，还有简单的算法题、数据库、XML，居然还有Web标准。遂产生好感，这公司虽小，环境还不错，而且还挺重视技术的。 <br />做完题后，竟真要打分，得了71，三个面试的人里面最低，心想高手真多啊，即使还很疑惑，不知道哪儿被扣了分。 <br />聊到公司时，人事主管说公司知名度不高，是没做国内项目的缘故，现在公司有100多人，在西南地区排前三没问题。这也吹得太离谱了，ft。 <br />人事说公司在国外有很多工程师，现在搞技术还是国外牛，把面试的人都狠狠踩了一顿，说是来这里可以好好学习，向国外工程师学习，随后不断提起“学习”二字。 <br />项目主要用perl开发，所以每个人面试过了还不行，得每人发一本perl入门教材回去学习，两周后再次考试，考试通过就进入带薪学习。带薪学习后，通过国外的在线perl认证考试，就算公司正式员工了。并且这在线认证每人收费50美元，由公司出。 <br />问：perl不是开源的吗，什么机构搞的认证。回答：现在不能透露。一旁的技术主管补充：搞开源的人也要吃饭，不然他发明perl搞啥。我：%$#%%&^&，ft。 <br />问：这带薪学习是不是试用期。回答：没有试用期，只有带薪学习和考试通过后的正式入职。并且安抚我们不要担心，肯定能过的，就连招来的应届生都能过。可为什么偏要出50美元冤枉钱去考试呢，没搞懂。 <br />再次提到进入公司后少不了学习和考试，必要时还可以叫国外的工程师来讲课，开始神化某些我们看不到的人、事物，并把面试的人贬一番。 <br />薪酬是计时，类似工厂里的计件。搞这样的活估计没啥技术含量，去了就当编码工人吧。 <br />具体的薪酬不便透露，看个人做的多少，范围是4K-2W，这钱也真好拿。 <br />今天考试大家勉强符合要求了，可还不行，考试成绩不是很好，得回去好好学习。末了，一人一本翻印的perl教材，不知道什么内容。 <br />临走前我提出把笔试题拿出来看看。 <br />有道求阶乘和的题，用一个标准的尾递归搞定，却扣了5分，技术主管的解释是：他也不知道这代码能不能运行，所以扣了分，看答了点，所以给了点分，ft。 <br />一个数据库连表的简单查询，题目注明要优化性能，思考了半天，没发现可以优化的，用一个主键连接，查询所有记录，优化个啥啊。直接一个INNER JOIN搞定，结果这题15分一分没得。上次就被人说我数据库不行，可这次不对啊，哪儿错了。解释是：你这写的啥啊，INNER JOIN是什么东西，你的WHERE语句跑哪儿去了。我ft，这SQL92是个啥…… <br />回家后，翻开那本perl书，上网查了查，乐了，大名鼎鼎的Learning Perl，赚到了。只可惜了那些搞翻译的PLMMs无缘再见，遗憾……
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/124482#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 16 Sep 2007 04:46:06 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/124482</link>
        <guid>http://fyting.javaeye.com/blog/124482</guid>
      </item>
      <item>
        <title>java泛型中的上界下界(上限下限)</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/122732" style="color:red;">http://fyting.javaeye.com/blog/122732</a>&nbsp;
          发表时间: 2007年09月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          java泛型中的super关键字不太常用，也不太好理解，今天又从头看了看java的泛型机制，作一记录。<br />上界:<br />上界用extends关键字声明，表示参数化的类型可能是所指定的类型，或者是此类型的子类。如下面的代码：<br /><pre name="code" class="java">
public void upperBound(List&lt;? extends Date> list, Date date)
{
	Date now = list.get(0);
	System.out.println("now==>" + now);
	//list.add(date); //这句话无法编译
	list.add(null);//这句可以编译，因为null没有类型信息
}
</pre><br />为什么会无法编译呢，实际调用时传入的list可能是java.util.Date的某个子类的参数化类型，如:<br /><pre name="code" class="java">
public void testUpperBound()
{
	List&lt;Timestamp> list = new ArrayList&lt;Timestamp>();
	Date date = new Date();
	upperBound(list,date);
}
</pre><br />也就是说，现在upperBound方法中实际的list是List&lt;Timestamp>，向它添加一个Date类型，肯定是不行的。相反，读取数据时，不管实际的list是什么类型，但可以知道它至少会返回一个Date类型，所以用foreach，get等没有问题。<br /><br />那么如何解决呢，可以使用泛型方法<br /><pre name="code" class="java">
public &lt;T extends Date> void upperBound2(List&lt;T> list, T date)
{
	list.add(date);
}
</pre><br />这里方法声明中的T作为一种参数化信息，会存储在java字节码中，T的实际类型由调用时的参数决定的。比如：<br /><pre name="code" class="java">
public void testUpperBound2()
{
	List&lt;Timestamp> list = new ArrayList&lt;Timestamp>();
	Date date = new Date();
	Timestamp time = new Timestamp(date.getTime());
	upperBound2(list,time);
	//upperBound2(list,date);//这句同样无法编译
}
</pre><br />上面代码中的list的类型参数决定了方法中T的类型，所以会看到注释掉的内容不能编译。而换成这样：<br />	List&lt;Date> list2 = new ArrayList&lt;Date>();<br />	upperBound2(list2,date);<br />编译就没有任何问题了。<br /><br /><br />下界<br />下界用super进行声明，表示参数化的类型可能是所指定的类型，或者是此类型的父类型，直至Object。如下面的代码：<br /><pre name="code" class="java">
public void lowerBound(List&lt;? super Timestamp> list)
{
	Timestamp now = new Timestamp(System.currentTimeMillis());
	list.add(now);
	//Timestamp time = list.get(0); //不能编译
}
</pre><br />这又为什么不能通过编译呢，看看调用代码:<br /><pre name="code" class="java">
public void testLowerBound()
{
	List&lt;Date> list = new ArrayList&lt;Date>();
	list.add(new Date());
	lowerBound(list);
}
</pre><br />lowerBound方法中的List&lt;? super Timestamp>表示这个list的参数类型可能是Timestamp或Timestamp的父类，如后面测试代码里，实际传入的是一个List&lt;Date>类型。向List&lt;Date>中add一个Timestamp肯定是没有问题的，但list.get()方法返回的对象类型可能是Date甚至是Object，你不能说list.get(0)返回的就是一个Timestamp，这里是向下类型转换了，编译器无法处理，所以这里不能编译。用java泛型实现的擦拭法解释，编译后会是如下的伪代码：<br /><pre name="code" class="java">
public void lowerBound(List list)
{
	Timestamp now = new Timestamp(System.currentTimeMillis());
	list.add(now);
	Timestamp time = (Timestamp)list.get(0); //①
}
public void testLowerBound()
{
	List list = new ArrayList();
	list.add(new Date());
	lowerBound(list);
}
</pre><br />代码①进行了强制类型转换，但实际添加进去的是一个Date类型，肯定会报ClassCastException，编译器无法保证向下类型转换的安全，所以这一句自然就无法编译了。
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/122732#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 11 Sep 2007 00:46:00 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/122732</link>
        <guid>http://fyting.javaeye.com/blog/122732</guid>
      </item>
      <item>
        <title>选择了离开</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/121807" style="color:red;">http://fyting.javaeye.com/blog/121807</a>&nbsp;
          发表时间: 2007年09月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          最近忙着找工作，好久没写过东西了。前两次面试情况都很不好，可能是缺少经验吧，描述个项目不知所云，给人的感觉就是这两年白过了，混天度日那种，第二家公司甚至明确地说这种情况只能给到2.5-3K。特别是第一次，很好的机会，被我浪费掉了，还麻烦朋友内部推荐了一场，很可惜。出来才深知自己的不足，那位技术主管给的评价是：java还行，数据库一般，C和Linux下编程没什么接触，与他们所期望的两年有差距。想想也是，买了那么多书，居然没有一本和数据库相关。虽然知道对数据库不是一窍不通，可熟练肯定是算不上的。我就算说精通java，又怎样，还会其他的么。可我连精通二字都不敢说，随便考个JAI的图像处理，就会愣在那里。能说出口的，也就是java熟练，javascript熟练？还有所谓的OOP、设计模式这些杂七杂八的东西？也好，知道了自己弱项在什么地方。换个新的环境，也许对成长更有利。每天做内部项目，都是闭门造车，估计压力越小、做得越久，就越不想走，也走不出去了。现在SOA、ESB等技术架构大势所趋，还守着陈旧的东西不放，可能喜新厌旧的我做得也不会开心。前几天一直犹豫着想告诉公司我要离开了，可又一直没说出口。后来老大转达公司的意思，问我是否继续留下，心里都还稍稍犹豫了那么几秒钟。他说公司的意愿是希望我留下，一个月2.6。我郁闷了，既然有意向留下一个人，这钱多钱少也不说了，可还偏偏就要少那么一百块钱以示区别，如果是明年，再少50块钱？偏要把学历作为一种条件，让人好笑，又无奈。老大和我聊了很长一会，见我去意已决，也深知公司情况，很遗憾，告诉我说既然要换，就找个好的，我心里好一阵感动。在他手下做事一直很愉快，有时候很多繁琐的事情都是他自己就做了；所有的工作分配都清晰有序，甚至不需要知道太多东西就把一个项目做完了；因为我的原因让项目延期也从来没说过什么；各种绩效考核啊，加班的补休啊也尽量给我们争取。嗯，真的对我们很好，只是我不得不离开了…… <br />在这里，也应该感谢公司，让对java一窍不通的我入了门，也给了一个应届毕业生工作机会，谢谢，只是种种机制、待遇和技术氛围我无法再待下去。反正我在公司也没起多大作用(这也和自己的行为有关)，走了对公司也没什么损失。以前在10楼就坐一起的几个人，都在公司坚持了两年，今年大家也各奔东西了。再见了，一起做fgw的同学们、做yyw的同学们、玩CS的同学们、玩星际的同学们、臭熊、程姐、张哥、杨老师，还有所有共事的同事们。谢谢你们给我的帮助、关心、快乐，祝你们和家人身体健康，工作顺利，万事如意。
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/121807#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 08 Sep 2007 01:42:12 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/121807</link>
        <guid>http://fyting.javaeye.com/blog/121807</guid>
      </item>
      <item>
        <title>我的常用软件列表</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/116265" style="color:red;">http://fyting.javaeye.com/blog/116265</a>&nbsp;
          发表时间: 2007年08月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一直以来都打算正式写一篇文章介绍下自己觉得好用的软件，但懒于动手，直到看到ddandyy发了一个这样的帖子，才来了兴趣，回复了这么长。贴在这里可能对别人有点用，见(<a href="http://www.javaeye.com/post/310698" target="_blank">http://www.javaeye.com/post/310698</a>)<br />--------------------------------------------------------------------<br /><a href="http://locate32.webhop.org/" target="_blank"><span style="color: blue">Locate32</span></a>，其貌不扬的搜索程序，曾试验过AvaFind，GoogleDesktopSearch，MS的WindowsDesktopSearch，发现大多数情况下只需要按文件名搜索，而不需要对本机全文搜索。Locate32建立索引的速度非常快，不耗费一点机器资源。贴一个用TC打开Locate32搜索结果的配置：<div class="quote_title">引用</div><div class="quote_div">Options->Settings->Advance->Use other program to open folders->设置为<strong> "path\to\totalcmd\TOTALCMD.EXE" /O /T /R="%d" </strong>需要引号</div><img src="http://www.javaeye.com/topics/download/95ab75ea-0aa3-44a8-b133-e165fa9ed212" /><br /><br /><br /><br />浏览器使用的<span style="color: blue">傲游1</span>，虽然偶尔卡死在那里，主要是有两个插件<span style="color: blue">Web Document Packager</span>(快速在后台保存网页为MHT)，还有一个插件叫<span style="color: blue">EasyFinder</span>，可以增量查找，闪烁当前查找结果，很方便。主要是用习惯了，其他浏览器暂时没发现更顺手的，FF太慢，傲游2好看，但也太慢，插件也不支持，连傲游1的基本功能都没完全实现，越做越回去了，不用。<br /><br /><br /><a href="http://www.vim.org" target="_blank"><span style="color: blue">vim</span></a>文本编辑器，在.vimrc里加一行<br /><pre name="code" class="java">set fileencodings=ucs-bom,utf-8,chinese,taiwan，euc-jp,euc-kr,latin1</pre><br />一般的编码问题都解决了吧，不过EmEditor也很舒服，但不能用来写文件，用惯了VIM就感觉其他编辑器太痛苦了……<br /><br /><br /><a href="http://dm2.sourceforge.net/" target="_blank"><span style="color: blue">DM2</span></a>，可以在windows公共文件对话框加一个快速导航功能，另外有一堆插件，比如把当前窗口变成图标，或者固顶，或者用热键调节音量，etc…<img src="http://www.javaeye.com/topics/download/0171346e-492f-4571-ad60-52944649fe10" /><br /><br /><br /><a href="http://www.microsoft.com/technet/sysinternals/SystemInformation/Autoruns.mspx" target="_blank"><span style="color: blue">AutoRuns</span></a>，方便查看系统的自启动程序，并且可以验证数字水印，隐藏微软的文件，保留可疑文件<br /><br /><br /><a href="http://www.microsoft.com/technet/sysinternals/utilities/zoomit.mspx" target="_blank"><span style="color: blue">ZoomIt</span></a>，屏幕放大镜，荧光笔，演讲和会议时很有用<br /><br /><br /><a href="http://ccollomb.free.fr/unlocker" target="_blank"><span style="color: blue">Unlocker</span></a>，经常删除不了文件，提示正在使用吗，用这个就对了。<br /><br /><br /><a href="http://www.wizissoft.com" target="_blank"><span style="color: blue">CyberArticle</span></a>，收藏文章专用，也是我第一个注册的软件。软件说不上完美，收藏后一般很少看，保存为MHT的查看得稍微多些，再是浏览器里保留的网址又要看得多些…现在都改用书签？360doc？或者根本不收藏直接google？知识管理类软件，还很不完善啊…<br /><br /><br /><a href="http://www.codeproject.com/tools/ToDoList2.asp" target="_blank"><span style="color: blue">TodoList</span></a>，任务管理软件,很方便,就是公司和家里拷贝文件麻烦，经常忘记，在线服务的就好了，但现存的在线服务都不太好……<br /><br /><br /><a href="http://picasa.google.com" target="_blank"><span style="color: blue">picasa</span></a>，看图用。打开单个图片嘛，用TC的SGViewer和Imagine就足够了。picasa看图太爽了，还可以直接上传到网上<br /><br /><br /><a href="http://www.totalcmd.net/plugring/xlsview.html" target="_blank"><span style="color: blue">excellence</span></a>，TC里快速查看xls的wlx插件
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/116265#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 24 Aug 2007 22:31:44 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/116265</link>
        <guid>http://fyting.javaeye.com/blog/116265</guid>
      </item>
      <item>
        <title>Re: 一个公司如何才能留住员工呢？</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/116261" style="color:red;">http://fyting.javaeye.com/blog/116261</a>&nbsp;
          发表时间: 2007年08月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          相信每个人对自己所在的公司都有一些自己的看法，本来有很多东西，但写出来似乎就成怨妇帖了，公开发布这些也不大好。但几个熟悉的人私下三三两两讨论下、批判下，好像又不太过瘾……也许慢慢就看开了，管他呢，关我什么事<br />这是很久之前对一个帖子的回复(<a href="http://www.javaeye.com/post/331131" target="_blank">http://www.javaeye.com/post/331131</a>)，用RSS总是导不过来，原文copy来先贴在这里吧，也许以后更新成在一篇真正的文章，也许不会再动。<br /><div class="quote_title">引用</div><div class="quote_div"><br />今天老总告诉我，最近公司确实走了很多人，但公司缺的不是工作一两年的，这种人很好找，就算找不到，每年毕业那么多，培训两个月也能干活。所以意思是：公司需要的是中高层，需要能把握整个项目的人，应届毕业生跳槽就由他去吧。我认为这只是上头的一厢情愿，事实上，项目里充斥了大批低质量代码，维护困难，而且缺少必要的codereview机制，常常造成各种问题，一个长达几百上千行的方法，还是让超人来读吧。本来1个人能做完的事情，现在用3个人都搞不定，相互扯皮，都怨别人。更有甚者，CVS冲突了，他把本地CVS更新到最新版，然后把自己之前修改的文件直接传上去。用人海战术，真不知道是减小了人员流动的风险，还是让沟通成本高了。<br />对于工作时间不长的人：待遇和学习新知识的机会，都很重要。我所看到的是这两项都没有满足，造成大量人员纷纷离职，然后再招新人，周而复始，恶性循环。<br /></div>
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/116261#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 24 Aug 2007 22:23:03 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/116261</link>
        <guid>http://fyting.javaeye.com/blog/116261</guid>
      </item>
      <item>
        <title>简洁的python，简洁的urllib</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/109886" style="color:red;">http://fyting.javaeye.com/blog/109886</a>&nbsp;
          发表时间: 2007年08月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">
实现图片下载
import urllib
url = r"http://www.javaeye.com/images/logo.gif"
path = r"h:\downloads\1.jpg"
data = urllib.urlopen(url).read()
f = file(path,"wb")
f.write(data)
f.close()
</pre><br />当然还有更简洁的<br /><pre name="code" class="java">
import urllib
url = r"http://www.javaeye.com/images/logo.gif"
path = r"h:\downloads\1.jpg"
data = urllib.urlretrieve(url,path)
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/109886#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 08 Aug 2007 00:31:24 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/109886</link>
        <guid>http://fyting.javaeye.com/blog/109886</guid>
      </item>
      <item>
        <title>SpringAOP嵌套调用的解决办法</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/109236" style="color:red;">http://fyting.javaeye.com/blog/109236</a>&nbsp;
          发表时间: 2007年08月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Spring AOP在同一个类里自身方法相互调用时无法拦截。比如下面的代码:<br /><pre name="code" class="java">
public class SomeServiceImpl implements SomeService
{

    public void someMethod()
    {
        someInnerMethod();
        //foo...
    }

    public void someInnerMethod()
    {
        //bar...
    }
}
</pre><br />两个方法经过AOP代理,执行时都实现系统日志记录。单独使用someInnerMethod时，没有任何问题。但someMethod就有问题了。someMethod里调用的someInnerMethod方法是原始的，未经过AOP增强的。我们期望调用一次someMethod会记录下两条系统日志，分别是someInnerMethod和someMethod的，但实际上只能记录下someMethod的日志，也就是只有一条。在配置事务时也可能会出现问题，比如someMethod方法是REQUIRED，someInnerMethod方法是REQUIRES_NEW，someInnerMethod的配置将不起作用，与someMethod方法会使用同一个事务，不会按照所配置的打开新事务。 <br />由于java这个静态类型语言限制，最后想到个曲线救国的办法，出现这种特殊情况时，不要直接调用自身方法，而通过AOP代理后的对象。在实现里保留一个AOP代理对象的引用，调用时通过这个代理即可。比如：<br /><pre name="code" class="java">
//从beanFactory取得AOP代理后的对象
SomeService someServiceProxy = (SomeService)beanFactory.getBean("someService"); 

//把AOP代理后的对象设置进去
someServiceProxy.setSelf(someServiceProxy); 

//在someMethod里面调用self的someInnerMethod，这样就正确了
someServiceProxy.someMethod();
</pre><br />但这个代理对象还要我们手动set进来，幸好SpringBeanFactory有BeanPostProcessor扩展，在bean初始化前后会统一传递给BeanPostProcess处理，繁琐的事情就可以交给程序了，代码如下，首先定义一个BeanSelfAware接口，实现了此接口的程序表明需要注入代理后的对象到自身。<br /><pre name="code" class="java">
public class SomeServiceImpl implements SomeService,BeanSelfAware

{

    private SomeService self;//AOP增强后的代理对象

 

    //实现BeanSelfAware接口

    public void setSelf(Object proxyBean)

    {

        this.self = (SomeService)proxyBean

    }

 

    public void someMethod()

    {

        someInnerMethod();//注意这句，通过self这个对象，而不是直接调用的

        //foo...

    }

    public void someInnerMethod()

    {

        //bar...

    }

}
</pre><br />再定义一个BeanPostProcessor，beanFactory中的每个Bean初始化完毕后，调用所有BeanSelfAware的setSelf方法，把自身的代理对象注入自身…… <br /><pre name="code" class="java">
public class InjectBeanSelfProcessor implements BeanPostProcessor
{
 
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException
    {
        if(bean instanceof BeanSelfAware)
        {
            System.out.println("inject proxy：" + bean.getClass());
            BeanSelfAware myBean = (BeanSelfAware)bean;
            myBean.setSelf(bean);
            return myBean;
        }
        return bean;
    }
 
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException
    {
        return bean;
    }
}
</pre><br />最后，在BeanFactory配置中组合起来，只需要把BeanPostProcesser加进去就可以了，比平常多一行配置而已。<br /><pre name="code" class="java">
    &lt;!-- 注入代理后的bean到bean自身的BeanPostProcessor... -->
    &lt;bean class=" org.mypackage.InjectBeanSelfProcessor">&lt;/bean>

    &lt;bean id="someServiceTarget" class="org.mypackage.SomeServiceImpl" /> 

    &lt;bean id="someService" class="org.springframework.aop.framework.ProxyFactoryBean">
        &lt;property name="target">
            &lt;ref local="someServiceTarget" />
        &lt;/property>
        &lt;property name="interceptorNames">
            &lt;list>
                &lt;value>someAdvisor&lt;/value>
            &lt;/list>
        &lt;/property>
    &lt;/bean>

    &lt;!-- 调用spring的DebugInterceptor记录日志,以确定方法是否被AOP增强 -->
    &lt;bean id="debugInterceptor" class="org.springframework.aop.interceptor.DebugInterceptor" />

    &lt;bean id="someAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        &lt;property name="advice">
            &lt;ref local="debugInterceptor" />
        &lt;/property>
        &lt;property name="patterns">
            &lt;list>
                &lt;value>.*someMethod&lt;/value>
                &lt;value>.*someInnerMethod&lt;/value>
            &lt;/list>
        &lt;/property>
    &lt;/bean>
</pre><br />这里的someService#someInnerMethod就表现出预期的行为了，无论怎样，它都是经过AOP代理的，执行时都会输出日志信息。<br />用XmlBeanFactory进行测试需要注意，所有的BeanPostProcessor并不会自动生效，需要执行以下代码：<br /><pre name="code" class="java">
XmlBeanFactory factory = new XmlBeanFactory(...);
InjectBeanSelfProcessor postProcessor = new InjectBeanSelfProcessor();
factory.addBeanPostProcessor(postProcessor);
</pre><br />ft:发完帖再看论坛里之前的帖子，发现居然更新了，而且取名都叫做self……<br />http://www.javaeye.com/post/347986
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/109236#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 06 Aug 2007 02:14:09 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/109236</link>
        <guid>http://fyting.javaeye.com/blog/109236</guid>
      </item>
      <item>
        <title>开源框架VS土制框架</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/105514" style="color:red;">http://fyting.javaeye.com/blog/105514</a>&nbsp;
          发表时间: 2007年07月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          真的没想到，现在还会出现是否应该使用开源框架的争论。说说我很久以来的看法，权作一笑：<br /><br /><div class="quote_title">引用</div><div class="quote_div">版权问题</div><br />很多Java开源项目都使用ApacheLicence2.0或者LGPL，商业软件中使用完全没有问题。<br /><br /><div class="quote_title">引用</div><div class="quote_div">开发人员积极性问题</div><br />普通的开发人员，都更愿意学习流行的框架，也就是说积极性更高。说实话，对员工的发展也更好（找工作更容易）。有的时候，就会有人抱怨为什么不用Spring啊这些，然后有的人要么会偷偷使用，要么会搞一个稀奇古怪的自己的东西，很影响项目开发，维护。<br /><br /><div class="quote_title">引用</div><div class="quote_div">维护问题</div><br />维护自制的框架需要工作量，由谁去维护成为一个问题。修改过程中，避免BUG出现，保证不影响以前的客户端代码也是一个问题。<br /><br /><div class="quote_title">引用</div><div class="quote_div">可移植性问题</div><br />自制的东西很少遵守标准开发，如果再加上满地的静态方法和丑陋的设计，想要进行单元测试都是空话，想修改后不出BUG是不可能的，当然，想要移植就更加困难。尤其是满地的DBConnectionManager、ConnectionPool、DBUtils，再加上遇到同名不同包的情况（几个相同名字的连接管理类，存放在不同的包，但连接不同的数据库），想不改出问题很难。一个标准的javax.sql.DataSource接口就那么难实现？<br />说到移植性，又顺便说下普通的IOC原则，看看下面这个简单的代码就知道了：<br /><pre name="code" class="java">
public class UserDao{
    public void createUser(User user){
        Connection conn = DBConnectionManager.getConnection();
    }
}
</pre><br />移植的时候，除了DAO，是不是还需要把DBConnectionManager这个东西给带过去？再看看下面这样的：<br /><pre name="code" class="java">
public class UserDao{
    private DataSource dataSource;
    public void setDataSource(DataSource dataSource){
        this.dataSource = dataSource;
    }

    public void createUser(User user){
        Connection conn = this.dataSource.getConnection();
    }
}
</pre><br />现在UserDao的实现只依赖DataSource这个接口，移植的时候，直接修改DataSource配置，传入不同DataSource就是了。单元测试就更加简单，手动setDataSource就行。<br />而前面那个代码怎么单元测试？DBConnectionManager容易替换吗？是不是还需要修改DBConnectionManager的源代码？那要是在jar包里面呢，又怎么修改？移植就更麻烦了，要是移植到的系统已经有个相同名字的DBConnectionManager，但需要取连接的却是另外一个叫做DBUtils的类（一个项目中连接多个数据库很常见吧？），又怎么办？很多时候，用静态方法都不得不手动修改代码，就祈祷全文替换不要出错误吧。<br />第二种实现看似代码长度增加了，多了个setDataSource方法，可想想，如果还有其他的editUser,deleteUser，代码长度谁更有优势，是不是还需要每次都去调用这个恶心的长长的DBConnectionManager？<br />这个是DAO，当然不需要单元测试，其他service代码里的什么静态工厂引用就会遇到单元测试问题了。<br /><br /><br /><div class="quote_title">引用</div><div class="quote_div">性能和稳定性问题</div><br />开源框架的开发人员基本都是高手，一般是每个公司最好的程序员。像Rod Johnson、Gavin King等人，比起一般公司里的开发人员，根本不在一个档次，甚至根本没必要拿来比。当然，SourceForge上粗制劣造的开源项目也不少，但这种东西注定了不会流行，流行的都是开源项目中的佼佼者。甚至可以说，开源项目强烈影响和冲击了各种标准，Spring和Hibernate，彻底颠覆了旧的EJB2，然后才有了更加先进的EJB3(JSR-220)，而其中的JPA（Java Persistence API），更是Hibernate的一个子集。实在不能把开源框架的性能和稳定性作为质疑的条件，难道自己制造的框架就一定比开源的更稳定？难道自制的框架都有很完备的测试？在质疑的同时，是否对这些开源项目有过较深入的了解，或者说是否使用过？是否真正知道使用后的好处与坏处？如果根本不了解，又如何能质疑它们？<br />自己不去了解就永远也不知道是否有性能问题，也许根本不存在呢？稳定性？说实话，我更怀疑根本没有经过单元测试就制造出来了的代码。<br /><br /><div class="quote_title">引用</div><div class="quote_div">嗯，看上去不错，用熟练了可能也很好，但这些框架都需要一个熟悉的过程，需要代价。</div><br />这是一个伪命题，为什么呢。说这些话的人都是搞了一套自己的框架，对于他们来说，使用其他框架当然需要学习。但对于公司其他人来说，使用这些自制的框架也需要学习，遇到稀奇古怪的问题也很郁闷，如果开发这个框架的人不在公司，只能自己从代码中慢慢找错误。这个是有切身体会的，很郁闷，不客气地说，很多自制的代码基本上比开源的差了不止一个档次，不容易跟踪到错误根源。<br /><br /><div class="quote_title">引用</div><div class="quote_div">那好，从别的框架取出好的部分，消化后转换为自己的代码。</div><br />FT。首先需要自己维护，麻烦。文档要重新写，麻烦。转换过程中不一定像开源框架那样有完整的测试（单元测试，集成测试），容易出错。最重要的问题，看似自己消化掉了，转换为了自己所理解的。但是没有参与“消化”的程序员，面对被“消化”掉重新构造出来的代码，难道就不需要消化了吗？像StringUtils这种东西，jakarta-commons-lang有一大堆方法了，再自己去写相同功能的就实在没有必要。自己写的web框架，就更容易漏洞百出了，自己写的就是比WebWork好？我相信，每个人都比Richard Oberg、Lightbody等人牛。<br /><br /><div class="quote_title">引用</div><div class="quote_div">那么，我们为什么要用开源框架</div><br />为了赶时髦。:)<br />为了和外面的世界接轨，为了用标准开发，增加可移植性。<br />为了框架挈约杜绝不好的开发方式，使项目更容易维护。<br />为了各个项目组之间不再各自行事，都重复搞一套自己的轮子。<br />为了让员工积极性更高。<br />当然，最重要的是为了解决实际问题，更好更快速地完成任务，达成目标。像那个臭名昭著的数据库连接泄露问题，很简单地用一个拦截器就搞定了，还需要千方百计、想方设法吗？借鉴他人成果，减少自己无谓的工作量，提高项目开发效率，降低维护成本，这才最根本的。
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/105514#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 26 Jul 2007 01:31:02 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/105514</link>
        <guid>http://fyting.javaeye.com/blog/105514</guid>
      </item>
      <item>
        <title>Ruby语法中setter的实现</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/101045" style="color:red;">http://fyting.javaeye.com/blog/101045</a>&nbsp;
          发表时间: 2007年07月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          粗略翻了下Ruby的介绍，晕,Ruby里setter居然是这样搞出来的:<br /><pre name="code" class="java">
class User
  def name=(myname)
    @name = myname
  end
end

user1 = User.new("aaa")
</pre><br />调用时这样:<br /><pre name="code" class="java">
user1.name='test1'
</pre><br />看上去很直观吧，比Java里的user1.setName("test")简洁多了，很像C#的Property。实质上呢，这里只有普通的Ruby语法，仅仅用到了几种“魔术”：<br />Ruby的方法命名可以用问号，感叹号，等号结尾（?,!,=)，所以这里调用的是"name="这样一个方法<br />Ruby调用方法可以不带括号，也就是说，下面两句是等同的：<br /><pre name="code" class="java">
user1.name= ('test1')
user1.name= 'test1'
</pre><br />至于<br /><pre name="code" class="java">
user1.name = 'test1'
</pre><br />为什么也可以使用（等号前多了个空格），还是没有搞明白。
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/101045#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 14 Jul 2007 18:13:07 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/101045</link>
        <guid>http://fyting.javaeye.com/blog/101045</guid>
      </item>
      <item>
        <title>div垂直居中的几种办法</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/92437" style="color:red;">http://fyting.javaeye.com/blog/92437</a>&nbsp;
          发表时间: 2007年06月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          以前看到dlee讲过，将line-height设置为与DIV的高度相同就可以居中<br /><pre name="code" class="java">
&lt;style type="text/css">
&lt;!--
.con_div{
width:400px;
height:300px;
border:1px solid #777;
text-align:center;
display:table-cell;
vertical-align:middle;
background:red;
color:#fff;
line-height:300px;
}
-->
&lt;/style>

&lt;div class="con_div">
测试内容ddddddddddd
&lt;/div>
</pre><br /><br />今天又在<a href="http://blog.donews.com/dodo/archive/2007/06/20/1177832.aspx" target="_blank">这里</a>看到的一种方法，使用了CSS的vertical-align属性?<br /><pre name="code" class="java">
&lt;style type="text/css">
&lt;!--
.con_div{
width:400px;
height:300px;
border:1px solid #777;
text-align:center;
display:table-cell;
vertical-align:middle;
background:red;
color:#fff
}
/*FOR IE*/
.fixie{
width:0;
height:100%;
display:inline-block;
vertical-align:middle;
}
-->
&lt;/style>

&lt;div class="con_div">
&lt;span class="fixie">&lt;/span>
测试内容
&lt;/div>
</pre><br />再次看到<a href="http://tech.idv2.com/2007/07/22/center-div-horizontally-and-vertically-with-css/" target="_blank">一种</a><br /><pre name="code" class="html">
&lt;style>
#warp {
  position: absolute;
  width:500px;
  height:200px;
  left:50%;
  top:50%;
  margin-left:-250px;
  margin-top:-100px;
  border: solid 3px red;
}
&lt;/style>
&lt;body>
  &lt;div id=warp>Test&lt;/div>
&lt;/body></pre>
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/92437#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 20 Jun 2007 16:11:34 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/92437</link>
        <guid>http://fyting.javaeye.com/blog/92437</guid>
      </item>
      <item>
        <title>Code Review工具Jupiter的使用</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/87489" style="color:red;">http://fyting.javaeye.com/blog/87489</a>&nbsp;
          发表时间: 2007年06月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <h4 class="TextColor1" id="subjcns!4D79BBA4004E7E77!179" style="MARGIN-BOTTOM: 0px">&nbsp; </h4>
<div class="bvMsg" id="msgcns!4D79BBA4004E7E77!179">
<p>给公司写的介绍性文档，其实就是<a href="http://www.devx.com/enterprise/Article/31658/0/page/1" target="_blank">Peer Code Reviews Made Easy with Eclipse Plug-In</a>这篇文章的一点摘要&hellip;&hellip;</p>
<p>首先把jupiter安装到eclipse中&hellip;&hellip;</p>
<p>&nbsp;Jupiter里，代码评审(code review)分为4个流程 </p>
<ol>
    <li><strong>Configuration(配置)：</strong>review发起者设置&ldquo;Review ID&rdquo;，指定要评审的代码，参与代码评审的人员，要讨论的问题等等。 </li>
    <li><strong>Individual review(个人评审)：</strong>每个人独自审查代码，把可能出现问题的代码加入checklist </li>
    <li><strong>Team review(团队评审)：</strong>大家在一起讨论之前检查出的问题代码，并决定如何处理 </li>
    <li><strong>Rework：</strong>开发人员根据之前评审的结果，对代码进行修复</li>
</ol>
<p>下面对4个步骤进行简介： </p>
<p>1.<strong>Configuration</strong> </p>
<p>由评审发起者(代码作者、team leader或者PM)进行配置。 </p>
<p>打开项目属性-&gt;Review选项页。点击&ldquo;New...&rdquo;，设置相应的ReviewId和description </p>
<p><a href="http://tk4.storage.msn.com/y1pKiF4F1e4Y_mTDg4nourY2rd1C1TCfqu2fnqlB2GjDzd1uG0iOhXpDUBjnChYtSyQR2xz7ln4tS10UkFdn8R2eA"><img src="http://tk4.storage.msn.com/y1pKiF4F1e4Y_m7FDbzBbACt-2NXkveHI6ZqVGUN8gmbd_18XE4jX_5HI2i5KF67hzamuPMqvKCRRgMCYw8ShkbBQ" border="0" height="520" alt="2007-06-06_152003" style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" width="596" /></a> </p>
<p>接着添加本次要评审的代码和文件 </p>
<p><a href="http://tk4.storage.msn.com/y1pKiF4F1e4Y_ldfuB1jZHMA8J3XBHCL4ELVLRLYJcgrt4n9P0d7qIoCPVSzvOGFmSOHmadYVNqdkE6MY8PtoCuFw"><img src="http://tk4.storage.msn.com/y1pKiF4F1e4Y_nQjkm2IChPvLetDYy8zXzX8AmKiUnmStBYXeDVcExTwZDVkAVi6vI8cy4Qdij2PXk3WVLcgq682g" border="0" height="528" alt="2007-06-06_152841" style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" width="588" /></a> </p>
<p>添加参与代码评审的人员 </p>
<p><a href="http://tk4.storage.msn.com/y1pKiF4F1e4Y_mKi68wObqD_Lfmu5bo56Ct0P0tZNA1Z-QmYylfoKULAlyClfKC24Kx2BA663wn96bx_3cyaQ2rCg"><img src="http://tk4.storage.msn.com/y1pKiF4F1e4Y_nJWC2Ga082TwxwiLQAsOAj7sXrfu9uUsS4JmA4rrsEO_MeDdGqQOHemfX4XtULvcLwMg2SH0xydQ" border="0" height="411" alt="2007-06-06_153048" style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" width="553" /></a> </p>
<p>接下来设置各种缺陷类型、严重性之类的。然后就是指定存放评审数据的目录。这个目录是相对于项目根目录的。如下图的设置，数据就会存放在&ldquo;项目根目录/review&rdquo;里 </p>
<p><a href="http://tkfiles.storage.msn.com/y1pD5VyEc0Heb7oBWMH798J4m3dTbR-R6PtEutZI3Mh8yRMFKFWEcp2BNQHmKi7cFPP"><img src="http://tkfiles.storage.msn.com/y1pD5VyEc0Heb4OBRi0xU4RdPXeTcvgCCJSlbp6vmssy2Hd533LaKmyFnq6Qv2zKA-5" border="0" height="261" alt="2007-06-06_153648" style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" width="566" /></a> </p>
<p>设置完成后，Jupiter将在项目根目录下生成&ldquo;.jupiter&rdquo;文件，把此文件存入CVS。现在评审发起者可以通知大家进行代码评审了。可以通过发邮件的方式进行通知，通知的内容最好有以下部分： </p>
<ul>
    <li>项目名称、Review ID、参与评审人员名单。 </li>
    <li>被评审代码的描述信息，如功能，需求等等 </li>
    <li>新增加和删除的文件 </li>
    <li>受影响但没有在<em>Configuration</em>中指定的组件</li>
</ul>
<p>通知完毕后，各成员即可正式进行代码评审。 </p>
<p>2.<strong>Individual review</strong> </p>
<p>从CVS取出最新的代码和<em>.jupiter</em>文件，在eclipse里-&gt;窗口(Window)-&gt;打开透视图(Open Perspective)-&gt;Review。然后选择<em>Individual Phase</em>： </p>
<p><a href="http://tkfiles.storage.msn.com/y1pD5VyEc0Heb68cARiWsMVY1BM--i2a1h60V5jGZKs091YYaR4EMe5hD-k8o7MV32s"><img src="http://tkfiles.storage.msn.com/y1pD5VyEc0Heb5dtkiNPJ3uqrxgzTBFYYpO6y62FUwZZHFhtJg3_1cPJAxX0dQQK3Fw" border="0" height="179" alt="2007-06-06_161640" style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" width="286" /></a> </p>
<p>选择项目名称，Review ID和Reviewer ID(评审者ID)，然后就可以开始查看代码了。 </p>
<p>在代码评审过程中，发现有问题的代码，即可在上面点击右键菜单-&gt;<em>Add Review Issue...</em>把问题添加到Jupiter中，指定问题类型、严重性和描述信息，点击保存。 </p>
<p><a href="http://tkfiles.storage.msn.com/y1pD5VyEc0Heb6rsDB_agXzC77BYtOJjmMqluLQFJEiSh8PIO3U2A-4JPOvfQVql4Ak"><img src="http://tkfiles.storage.msn.com/y1pD5VyEc0Heb5IVuyPQviG5uq9kkWrryqxsYX1pIQAwVV--uiLU3oVALVdceFGU5gL" border="0" height="235" alt="2007-06-06_162654" style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" width="282" /></a> </p>
<p><a href="http://tkfiles.storage.msn.com/y1pD5VyEc0Heb5vxkFWcVL82a53pg6Q2eTjWqV8O8zk_lRA6qcz7k_NfSyCccMnJVy3"><img src="http://tkfiles.storage.msn.com/y1pD5VyEc0Heb4oWrQOv08137NKdbAcu3Ib2VFi-MN5GECD61IIHjTNz5UcwsSD0TI8" border="0" height="463" alt="2007-06-06_162900" style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" width="586" /></a> </p>
<p>完成个人的代码评审后，把Jupiter评审数据目录下的文件传入CVS，就可以一起进行讨论了。 </p>
<p>3.<strong>Team review</strong> </p>
<p>大家在一起，使用一台电脑或者投影仪，选择<em>Team Phase</em> </p>
<p><a href="http://tkfiles.storage.msn.com/y1pD5VyEc0Heb5BDCPHcZQyppLdo1S5Bba4woLybcta6yPDO3q-ni-nxBmjAl9NWGuh"><img src="http://tkfiles.storage.msn.com/y1pD5VyEc0Heb6qeF13vQRGwMHX4fLvb7vhEtUPwjsoQnS5Dybmx13aqaDzx437nDOQ" border="0" height="169" alt="2007-06-06_163518" style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" width="275" /></a> </p>
<p>现在<em>Individual Phase</em>里检查出的所有的问题都会显示在ReviewTable里，点击<em>Go To</em>就能链接到问题所在代码，然后大家讨论这段代码是否有问题，如何解决等等，把结果写到ReviewEditor里，保存。 </p>
<p><a href="http://tkfiles.storage.msn.com/y1pD5VyEc0Heb4Vq2_z4D2Tt2s_ftGy7vOaTgfB5tOrLxg2LVDX3Bhsk0DOamCsqzIe"><img src="http://tkfiles.storage.msn.com/y1pD5VyEc0Heb5-9SFCvFxNSraF2XanI3KvOc9AYKWIs_B917zcpdTG56uAh2rHKvq9" border="0" height="226" alt="2007-06-06_164057" style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" width="546" /></a> </p>
<p>所有的问题讨论出结果后，把Jupiter评审数据文件传入CVS，散会，各自回到自己位置，进行下一个步骤 </p>
<p>4.<strong>Rework</strong> </p>
<p>从CVS取出最新的Jupiter评审数据文件，选择<em>Rework Phase</em> </p>
<p><a href="http://tkfiles.storage.msn.com/y1pD5VyEc0Heb7YqFMF5RBrKZRVsO0dFVNNKpcM_M4CtNaaaj-fk4hwrg5DeoSgFyle"><img src="http://tkfiles.storage.msn.com/y1pD5VyEc0Heb5iqNx3Nv_-bfjq93MWMDe5RH0OHADtJ7I3W-FrUJuTs5eu_RGTT1YI" border="0" height="173" alt="2007-06-06_164516" style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" width="224" /></a> </p>
<p>选择自己的ID后，上一步骤中分配给自己的问题就会显示到ReviewTable里，一个一个地把问题修复吧，修复后把状态置为Resolved。完毕后把Jupiter数据传CVS。 </p>
<p>各自的rework完成后，各位评审者取出最新的Jupiter数据，关闭ReviewTable的过滤器，就能查看到本次评审中发现的各种问题，对各种问题进行验证，感到满意后可以把状态置为Closed，或者验证未通过,就置为Re-Opened。 </p>
<p>如此，便完成了一次代码评审&hellip;&hellip; </p>
<p>参考资料: </p>
<ul>
    <li>Jupiter User's Guide <a href="http://csdl.ics.hawaii.edu/Tools/Jupiter/Core/doc/UsersGuide.html" title="http://csdl.ics.hawaii.edu/Tools/Jupiter/Core/doc/UsersGuide.html">http://csdl.ics.hawaii.edu/Tools/Jupiter/Core/doc/UsersGuide.html</a> </li>
    <li>Effective Code Reviews Without the Pain <a href="http://www.developer.com/java/other/article.php/3579756" title="http://www.developer.com/java/other/article.php/3579756">http://www.developer.com/java/other/article.php/3579756</a> </li>
    <li>Peer Code Reviews Made Easy with Eclipse Plug-In <a href="http://www.devx.com/enterprise/Article/31658/0/page/1" title="http://www.devx.com/enterprise/Article/31658/0/page/1">http://www.devx.com/enterprise/Article/31658/0/page/1</a></li>
</ul>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/87489#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 07 Jun 2007 00:53:22 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/87489</link>
        <guid>http://fyting.javaeye.com/blog/87489</guid>
      </item>
      <item>
        <title>买了本《POJOs In Action》</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/82105" style="color:red;">http://fyting.javaeye.com/blog/82105</a>&nbsp;
          发表时间: 2007年05月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          前段时间发现一篇ORM测试的文章（ <a href="http://cleverpig.javaeye.com/blog/44706 " target="_blank">http://cleverpig.javaeye.com/blog/44706 </a>），原来内容是出自这本书-《POJOs In Action》。几天后在dearbook上看到这本书出中文版了，翻了下目录，讲了很多单元测试实践，ORM的使用和优化，以及数据库相关内容。再一看译者，居然是布娃娃老大翻译的。冲着各种测试策略和ORM知识，加上偶像的魅力，遂购入了本书。<br /><br />感觉很多TDD的书偏向于“传道”，比较虚，对于现实中的代码如何测试，特别是结合各种流行框架和数据库时，具体如何操作，都没有说很清楚。这本书果然是in action风格，很多测试实例，把自己的实践和书上作一对比，很多问题变清晰了，比如如何准备测试数据，如何测试Callback风格的代码。书上总结的各种ORM设计与优化策略，各种fetch使用的时机，开发中的常见问题，动态分页查询，还有数据库的锁机制，版本控制问题，可以把零碎的知识梳理一遍，感觉都很有用。(就是还来不及看 ……)<br />语文水平和技术水平都差得不行，直接复制序言... <img src="/images/smiles/icon_cool.gif"/><br /><br /><div class="quote_title">引用</div><div class="quote_div"><br />业界流传着一本经典的架构书籍——Martin Fowler的《企业架构模式》。《POJOs IN ACTION中文版》这本书可以看作是《企业架构模式》的深化进阶篇，它详细讲解了《企业架构模式》语焉不详的一些重要架构模式实战。读通了本书，您就可以和别人交流一些具有相当复杂度的高级企业应用模式了。 <br />我对本书涉及的技术方面比较熟悉，因此在这里写这篇序。《POJOs IN ACTION中文版》的主线是如何用Spring、iBATIS、Hibernate、JDO、EJB 3等流行框架搭建无侵入的Web三层构架。POJO（Plain Old Java Object）的含义已经超越了字面的意思，成为“无侵入”特性的代名词。“无侵入”的具体含义是：用户的业务逻辑代码不依赖于具体应用框架代码；更换或者升级持久层框架时，不需要修改原来的业务逻辑代码。<br />看过本书，读者会对一些流行词（IoC、AOP、Open Session In View、事务管理、悲观锁、乐观锁等）有深入的了解和掌握。本书作者对Spring IoC、Hibernate、JDO、EJB 3等框架非常熟悉，他熟知各种边边角角的高级用法，解决了很多架构上的难点。<br />本书构造了一个完整的应用程序，并对框架之间的各种组合进行了详细的举例说明——什么样的需求，适合采用什么样的框架组合。这与开源项目Appfuse有些类似，不同的是，本书例子的深度和难度都高于Appfuse。<br />实战（In Action）系列书籍的时效性是读者购书时关心的问题之一。本书既然以具体框架应用代码为例，自然也存在一定的时效性问题。比如，EJB 3的新持久化标准为JPA；其他一些框架也会不断地升级。幸运的是，本书作者的数据库基本功非常深厚，尤其在本书最后3章，表现得淋漓尽致。笔者认为，最后3章最为出彩，是本书的精华所在。作者将事务管理、悲观锁、乐观锁、条件组合搜索等难点都分析得鞭辟入里、头头是道。强烈推荐，值得一读。<br />当然，前面的章节也不错。IoC、AOP、Open Session In View等概念深入浅出，用例翔实。读者跟着本书实践一遍，充当一个Java应用程序架构师应已基本够用。书中各种框架的特性对比，对于框架应用设计人员而言，更是难得的珍贵资料。架构师可以根据具体需求，对框架进行组合、剪裁、模仿和改进。因此，在深度和广度上的这些优点一定程度上延长了本书的时效。<br />读者（尤其是渴望突破和提高的程序员）可以先翻阅最后3章（精华所在，详细讲解了其他书籍语焉不详的难点）。我相信，您一定会被作者的务实风格和深厚功底所吸引。<br />琳骁和我合作翻译了这本书。琳骁翻译了前8章，我翻译了后5章。这是我第一次翻译书稿，内心忐忑不安。深恐翻译有错漏，被读者骂还是小事，浪费了读者的时间和金钱才是大事。幸运的是，本书的主要译者琳骁是一位认真负责且有经验的译者，他对整个译文进行了多次仔细的检查和润色，解决了很多行文的通顺问题，令我受益匪浅。<br />祝愿各位读者能享受阅读本书的乐趣。 <br /><br /><br />                                               王海龙<br />于2007年2月13日<br /><br /></div><br /><br />网上地址：<br /><a href="http://www.dearbook.com.cn/Book/ViewBook.aspx?pno=ts00175890" target="_blank">http://www.dearbook.com.cn/Book/ViewBook.aspx?pno=ts00175890</a><br /><a href="http://www.china-pub.com/computers/common/info.asp?id=34697" target="_blank">http://www.china-pub.com/computers/common/info.asp?id=34697</a><br /><br /><span style="font-size: 8pt"><em>ps:china-pub真恶心，在页面里搞入好多隐藏字符，还不让复制，还没有目录。。。</em></span><br />八卦帖：<a href=" http://www.javaeye.com/topic/80322" target="_blank"> http://www.javaeye.com/topic/80322</a>
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/82105#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 23 May 2007 02:43:45 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/82105</link>
        <guid>http://fyting.javaeye.com/blog/82105</guid>
      </item>
      <item>
        <title>VIM colorschema 设置的常用命令</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/51392" style="color:red;">http://fyting.javaeye.com/blog/51392</a>&nbsp;
          发表时间: 2007年05月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          :h syntax-highlighting<br />:h highlight<br />:h group-name<br />:h colortest.vim<br />:runtime syntax/colortest.vim<br />:runtime! syntax/syncolor.vim<br />:so $VIMRUNTIME/syntax/hitest.vim<br />:h guicursor<br />:hi-normal
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/51392#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 07 May 2007 20:44:00 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/51392</link>
        <guid>http://fyting.javaeye.com/blog/51392</guid>
      </item>
      <item>
        <title>使用了代码提示带来的坏处……</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/71701" style="color:red;">http://fyting.javaeye.com/blog/71701</a>&nbsp;
          发表时间: 2007年04月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>今天配sessionFactory老是报错,并且是&quot;<font face="Arial"><font face="Arial">Error parsing XML: XML InputStream(1) Content is not allowed in prolog</font>.&quot;,心想多半是encoding的问题,用EmEditor打开spring配置，正常的啊，把hbm文件打开，也正常，检查了也没发现有BOM头。手动把xml文件又转换为GBK编码，问题依然。这下可奇怪了，难道classpath中有其他xerces的jar引起冲突？找了半天，无果。dom4j，换hibernate自带的，还是不行。百思不得其解，开始病急乱投医了，总不至于是中文注释的问题吧，把xml里的中文注释全部删除，累得半死之后，和预想的差不多，无效，继续报错。开始怀疑是hibernate的bug了（此时已经很晕了），换hibernate3.2.2.ga，问题依然。</font><font face="Arial">上网搜，发现一个帖子<font face="Arial"><a href="http://www.javaeye.com/topic/50333">http://www.javaeye.com/topic/50333</a></font>似乎有类似问题，不过把5页帖子看完后发现没用。心想，总不至于jdk的问题吧&hellip;&hellip;终于没办法偷懒了，手动配置一个hibernate.cfg.xml，好了。。。问题肯定出在spring上面了，拿出其他项目的sessionFactory配置，一行一行比较，终于发现问题所在&hellip;&hellip;把<font face="Arial">mappingDirectoryLocations写成了<font face="Arial">mappingLocations，阿门，<font face="Arial">原来得</font>感谢SpringIDE的自动提示，输入mapping时提示出来了，然后我就按了回车，所以就&hellip;&hellip;<br />
</font></font></font><font face="Arial"><font face="Arial"><font face="Arial">看来以后要建立一个分类，专门存放这些灵异事件了，再次印证了：灵异事件绝大多数来自于自身。。。</font></font></font></p>
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/71701#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 17 Apr 2007 02:46:57 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/71701</link>
        <guid>http://fyting.javaeye.com/blog/71701</guid>
      </item>
      <item>
        <title>Java里遇到的奇怪错误.注意分号</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/67111" style="color:red;">http://fyting.javaeye.com/blog/67111</a>&nbsp;
          发表时间: 2007年04月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <font face="Arial">
<div class="code_title">
<div class="code_title"><font face="Arial">找了半天,懒人啊,看似不起眼的东西,稍微修改就直接打包,部署,测试,不对,再来,都不先写一个单元测试,晕死....然后检查DAO,sql语句,还怀疑是不是Oracle出错了...最后还是不行,找不到错误.看来又应验了经常说的那句话,千奇百怪的错误,肯定是自己出问题了.</font></div>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">if</span><span>(statisticInfo&nbsp;==&nbsp;</span><span class="keyword">null</span><span>); &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.debug(</span><span class="string">&quot;the&nbsp;statistic&nbsp;of&nbsp;member:&nbsp;'&quot;</span><span>&nbsp;+&nbsp;memberName&nbsp;+&nbsp;</span><span class="string">&quot;'&nbsp;is&nbsp;not&nbsp;exists,then&nbsp;create&nbsp;it&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memberStatisticInfoDao.create(memberName); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>}&nbsp;&nbsp;</span> </li>
</ol>
</div>
</div>
</font>
          <br/>
          <span style="color:red;">
            <a href="http://fyting.javaeye.com/blog/67111#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 01 Apr 2007 17:54:00 +0800</pubDate>
        <link>http://fyting.javaeye.com/blog/67111</link>
        <guid>http://fyting.javaeye.com/blog/67111</guid>
      </item>
      <item>
        <title>python编码问题和i18n</title>
        <author>fyting</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fyting.javaeye.com">fyting</a>&nbsp;
          链接：<a href="http://fyting.javaeye.com/blog/66558" style="color:red;">http://fyting.javaeye.com/blog/66558</a>&nbsp;
          发表时间: 2007年03月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><font face="Arial">初学Python,遇到很多编码问题，记下来以免将来又忘了，很多东西不懂，都是属于不求甚解，乱下结论，但想到拿出来可以有热心同学指出错误所在，便厚起脸皮了&hellip;&hellip;<br />
首先需要了解Python中有两种字符串(严格地说,似乎不能这么叫)。一种是普通的str对象（每个字符用8bits表示），另一种是unicode字符串，它们可以相互转换。<br />
首先打开pyshell，输入一段代码。<br />
</font></p>
<div class="code_title">python 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-py">
    <li class="alt"><span><span>&gt;&gt;&gt;&nbsp;a&nbsp;=&nbsp;&quot;我&quot; &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&gt;&gt;&gt;&nbsp;b&nbsp;=&nbsp;</span><span class="builtins">unicode</span><span>(a,&quot;gb2312&quot;) &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&gt;&gt;&gt;&nbsp;a.__class__ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&lt;</span><span class="builtins">type</span><span>&nbsp;'</span><span class="builtins">str</span><span>'&gt; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&gt;&gt;&gt;&nbsp;b.__class__ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&lt;</span><span class="builtins">type</span><span>&nbsp;'</span><span class="builtins">unicode</span><span>'&gt; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&gt;&gt;&gt;&nbsp; &nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>看出来了吧，两种字符串。<br />
再来<br />
</p>
<div class="code_title">python 代码</div>
<div class="dp-highlighter">
<ol class="dp-py">
    <li class="alt"><span><span>&gt;&gt;&gt;&nbsp;a &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>'\xce\xd2' &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&gt;&gt;&gt;&nbsp;b &nbsp;&nbsp;</span> </li>
    <li class=""><span>u'\u6211'&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>变量a是两个字符，b是一个unicode字符。<br />
关于这两种字符串，Python文档--&gt;LanguageReference--&gt;DataModel--&gt;The standard type hierarchy--&gt;Sequences，有一些Strings,Unicode的描述。<br />
至于<br />
</p>
<div class="code_title">python 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-py">
    <li class="alt"><span><span>&gt;&gt;&gt;&nbsp;z&nbsp;=&nbsp;u&quot;我&quot; &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&gt;&gt;&gt;&nbsp;</span><span class="comment">#这种代码，其实什么都不是。 </span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&gt;&gt;&gt;&nbsp;z.__class__ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&lt;</span><span class="builtins">type</span><span>&nbsp;'</span><span class="builtins">unicode</span><span>'&gt; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&gt;&gt;&gt;&nbsp;z &nbsp;&nbsp;</span> </li>
    <li class=""><span>u'\xce\xd2'&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>看到了吧,这个奇怪的东西......<br />
<font color="#ff6600">后来在WindowsXP、纯python命令行下试过，得出的结论不同，z的结果变成了</font><font color="#ff6600"><font face="Arial">u'\u6211'，这里完全不应该在pyshell下作试验的，看来还有很多问题尚未理解清楚</font></font></p>
<font face="Arial">
<p><br />
<font size="4"><strong>再来看看encode，decode</strong></font><br />
什么情况用encode，什么情况又是decode呢，刚开始总是被搞昏。其实各种本地字符集的英文名是<strong>Coded</strong> Character Set，要转换为<strong>Coded</strong>，肯定是要encode了，同样，从里面解出来也应该叫decode&hellip;&hellip;<br />
decode就是把其他编码转换为unicode，等同于unicode函数；encode就是把unicode编码的字符串转换为特定编码。在pyshell里继续：<br />
a是Str类型的，所以再用encode会报错。用print输出时会调用默认编码转换为系统编码？<br />
</p>
<div class="code_title">python 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-py">
    <li class="alt"><span><span>&gt;&gt;&gt;&nbsp;a.decode(&quot;gb2312&quot;) &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>u'\u6211' &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&gt;&gt;&gt;&nbsp;</span><span class="keyword">print</span><span>&nbsp;a.decode(&quot;gb2312&quot;) &nbsp;&nbsp;</span> </li>
    <li class=""><span>我 &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&gt;&gt;&gt;&nbsp;a.encode(&quot;gb2312&quot;) &nbsp;&nbsp;</span> </li>
    <li class=""><span>Traceback&nbsp;(most&nbsp;recent&nbsp;call&nbsp;last): &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;File&nbsp;&quot;&lt;</span><span class="builtins">input</span><span>&gt;&quot;,&nbsp;line&nbsp;1,&nbsp;</span><span class="keyword">in</span><span>&nbsp;? &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="exceptions">UnicodeDecodeError</span><span>:&nbsp;'ascii'&nbsp;codec&nbsp;can't&nbsp;decode&nbsp;byte&nbsp;0xce&nbsp;</span><span class="keyword">in</span><span>&nbsp;position&nbsp;0:&nbsp;ordinal&nbsp;</span><span class="keyword">not</span><span>&nbsp;</span><span class="keyword">in</span><span>&nbsp;</span><span class="builtins">range</span><span>(128)&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>b是unicode类型，打印时需要先encode(编码)成系统编码<br />
</p>
<div class="code_title">python 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-py">
    <li class="alt"><span><span>&gt;&gt;&gt;&nbsp;</span><span class="keyword">print</span><span>&nbsp;b.encode(&quot;gb2312&quot;) &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>我 &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&gt;&gt;&gt;&nbsp;b.encode(&quot;gb2312&quot;) &nbsp;&nbsp;</span> </li>
    <li class=""><span>'\xce\xd2' &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&gt;&gt;&gt;&nbsp;b.decode(&quot;gb2312&quot;) &nbsp;&nbsp;</span> </li>
    <li class=""><span>Traceback&nbsp;(most&nbsp;recent&nbsp;call&nbsp;last): &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;File&nbsp;&quot;&lt;</span><span class="builtins">input</span><span>&gt;&quot;,&nbsp;line&nbsp;1,&nbsp;</span><span class="keyword">in</span><span>&nbsp;? &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="exceptions">UnicodeEncodeError</span><span>:&nbsp;'ascii'&nbsp;codec&nbsp;can't&nbsp;encode&nbsp;character&nbsp;u'\u6211'&nbsp;</span><span class="keyword">in</span><span>&nbsp;position&nbsp;0:&nbsp;ordinal&nbsp;</span><span class="keyword">not</span><span>&nbsp;</span><span class="keyword">in</span><span>&nbsp;</span><span class="builtins">range</span><span>(128)&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>python里默认的encode和decode是strict模式,所以会直接抛出Error，而Java里是默认replace模式，所以在处理servlet时经常会看到一串?????<br />
在decode时传入第二个参数errors为'replace'可以和Java相同，但总是没成功，还不知道为什么</p>
<p><font size="4"><strong>MySQLDb连接数据库的编码问题</strong></font><br />
试了很久，无论在connect的时候指定charset='utf8'，还是使用set_character_set()，或者执行&quot;SET NAMES UTF8&quot;，跟踪到character_set_name()方法返回的都是latin1...再跟代码,似乎就跑到mysql-api里去了,反正最后解决的办法也很简单，就是使用如下方式执行，而不要去拼sql语句&hellip;&hellip;<br />
</p>
<div class="code_title">python 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-py">
    <li class="alt"><span><span>&gt;&gt;&gt;&nbsp;sql&nbsp;=&nbsp;&quot;INSERT&nbsp;INTO&nbsp;t_user(name,nickname)&nbsp;</span><span class="builtins">values</span><span>(%s,%s)&quot; &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&gt;&gt;&gt;&nbsp;param&nbsp;=&nbsp;(&quot;张三&quot;,&quot;张三的昵称&quot;) &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&gt;&gt;&gt;&nbsp;cursor.execute(sql,param)&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p><strong><font size="4">Python的国际化/i18n问题</font></strong><br />
使用gettext来实现。其实就是一个文本替换的方式，和java里用ResourceBundle、properties比较类似&hellip;&hellip;<br />
<a href="http://wiki.wxpython.org/index.cgi/RecipesI18n" target="_blank">http://wiki.wxpython.org/index.cgi/RecipesI18n</a>有一个recipe,不过代码很旧了,现在python里自带了pygettext.py和msgfmt.py<br />
其实就是把http://blog.donews.com/limodou/archive/2004/06/15/28916.aspx的文章按自己思路组织了一下。<br />
步骤:<br />
1.导入gettext模块<br />
</p>
<div class="code_title">python 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-py">
    <li class="alt"><span><span class="keyword">import</span><span>&nbsp;gettext &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>gettext.install('i18ntest',&nbsp;'./</span><span class="commonlibs">locale</span><span>',&nbsp;</span><span class="builtins">unicode</span><span>=</span><span class="builtins">True</span><span>)&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>参数说明:<br />
作用域:用于限定翻译文件的主名<br />
路径:翻译文件所在路径<br />
unicode:使用unicode</p>
<p>2.把代码里需要国际化的文本全部使用_(&quot;text&quot;)的形式进行替换</p>
<p>3.需要进行国际化处理时，调用</p>
<div class="code_title">python 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-py">
    <li class="alt"><span><span>gettext.translation('i18ntest',&nbsp;'./</span><span class="commonlibs">locale</span><span>',&nbsp;languages=['cn']).install(</span><span class="builtins">True</span><span>)&nbsp;&nbsp;</span></span> </li>
</ol>
</div>
<p>来处理。</p>
<p>现在程序写好了，需要生成所需资源文件了：<br />
1.调用python安装目录的 Tools/i18n/pygettext.py抽取所需翻译的模板<br />
&gt;&gt;&gt; pygettext.py path/to/yourfile.py<br />
将生成一个名为messages.pot的文件<br />
2.生成模板文件后，修改这个模板文件，其中的msgid为键值，对应你程序里写的文本，如：_(&quot;New File&quot;)，而msgstr为翻译后的值。还有就是注意修改文件头部分Content-Type的charset为合适的编码，比如utf8<br />
3.编写好模板后，把扩展名修改为.po,运行Tools/i18n/msgfmt.py,生成二进制的资源文件<br />
&gt;&gt;&gt; msgfmt.py messages.po<br />
将生成一个名为messages.mo的文件<br />
4.把这个mo文件放在正确的位置.<br />
比如你在程序中是这样写的:<br />
gettext.install('i18ntest', './locale', unicode=True)<br />
gettext.translation('i18ntest', './locale', languages=[