﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-超越次元的追求</title><link>http://www.blogjava.net/wolfsquare/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 03 May 2026 04:29:46 GMT</lastBuildDate><pubDate>Sun, 03 May 2026 04:29:46 GMT</pubDate><ttl>60</ttl><item><title>小经验两则</title><link>http://www.blogjava.net/wolfsquare/archive/2006/08/03/61459.html</link><dc:creator>wolfsquare</dc:creator><author>wolfsquare</author><pubDate>Thu, 03 Aug 2006 01:54:00 GMT</pubDate><guid>http://www.blogjava.net/wolfsquare/archive/2006/08/03/61459.html</guid><wfw:comment>http://www.blogjava.net/wolfsquare/comments/61459.html</wfw:comment><comments>http://www.blogjava.net/wolfsquare/archive/2006/08/03/61459.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wolfsquare/comments/commentRss/61459.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wolfsquare/services/trackbacks/61459.html</trackback:ping><description><![CDATA[1.Oracle 8i 下使用最新的oracle thin driver时用DatabaseMetaData获取主键等信息时,需要将<br />connection.getMetaData().getPrimaryKeys(connection.getCatalog(),null,tableName);<br />中的tableName转为大写,否则无法得到数据。<br /><br />2.正则表达式中,需要以","分割字符串,但是要分割的字串中含有","号,为了避免冲突,引入前置转义字符"\",这样的正则怎么写呢?<br />例如:<br />String txt = "STATE_COUNTY=kj\\\\,,ADDR_LINE1=l=j,ADDR_LINE2=mj\n\n,ADDR_LINE3=n\\,o,\n\nADDR_LINE4=\np";<br />需要把键值对切分出来:<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000"> Pattern.compile(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">[^\\\\],)</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span></div>这个是不行的,会将","号前一个字符消耗掉。<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000"> Pattern.compile(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">(?![\\\\]),)</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span></div>也不行<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">Pattern p </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> Pattern.compile,</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,(?![\\\\])</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span></div>倒是可以,但是把转义字符放后面似乎有点诡异。<br />找了一个折衷办法,不切割使用正则获取"键=值"子串:<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">Pattern p </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> Pattern.compile(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">\\w+\\s*=.*?[,]*.*?(?=,|$)</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,Pattern.DOTALL);</span></div>但是还是带来了子串中不能含有"="的问题。<br />最后查了一个JDK1.4 DOC,发现了一个反向的非匹配串写法:<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">Pattern p </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> Pattern.compile(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">(?&lt;!\\\\),\\s*</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span></div>这样一来就解决了以上问题。<img src ="http://www.blogjava.net/wolfsquare/aggbug/61459.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wolfsquare/" target="_blank">wolfsquare</a> 2006-08-03 09:54 <a href="http://www.blogjava.net/wolfsquare/archive/2006/08/03/61459.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>回复 乱弹权限系统续一</title><link>http://www.blogjava.net/wolfsquare/archive/2006/07/04/56606.html</link><dc:creator>wolfsquare</dc:creator><author>wolfsquare</author><pubDate>Tue, 04 Jul 2006 14:45:00 GMT</pubDate><guid>http://www.blogjava.net/wolfsquare/archive/2006/07/04/56606.html</guid><wfw:comment>http://www.blogjava.net/wolfsquare/comments/56606.html</wfw:comment><comments>http://www.blogjava.net/wolfsquare/archive/2006/07/04/56606.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/wolfsquare/comments/commentRss/56606.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wolfsquare/services/trackbacks/56606.html</trackback:ping><description><![CDATA[
		<p>
				<a class="singleposttitle" id="viewpost1_TitleUrl" href="/RongHao/archive/2006/07/03/56258.html">乱弹权限系统续一</a>
				<br />原文在这:http://www.blogjava.net/RongHao/archive/2006/07/03/56258.html<br /><br />仔细分析一,二,三,四权限背后的实质可以发现:<br />一系统权限的概念有一些冗余,很难想象这样一种情况:你已经有了子系统下的很多权限,结果因为没有模块权限而使得无法使用该模块进行任何操作,分配权限的人要非常小心才行.这个世界已经够复杂了,不要再给开发,部署人员增加复杂度了.很明白的,这个权限是不需要资源的权限<br />二数据库操作权限的概念,有一点疑惑,不知道为什么要建立这样的一个概念,和行级权限有什么区别呢? 从你的上下文理解来看,似乎是这样子的:有操作X表的业务,如果用户有增加权限,则可以任意增加数据,如果用户有编辑权限,则可以编辑任意数据.实际上对应标准权限模型为:不需要限定资源的操作,即不需要资源标识的权限.<br />三行级数据权限,这个概念很直白,对应标准权限模型就是: 资源(行数据)+操作<br />四列级数据权限,由于不是针对某特定行数据,所以它也是无资源型权限<br />就这样,所有的权限最终可划为需要资源标识和不需要资源标识,换句话说,所有权限可划分为控制某些集合的权限和控制单体的权限两种,在某些时候,也称之为 功能权限和数据权限</p>
		<p>
				<br />谈到把权限分给别人,很自然的就是如何控制权限的权限的问题了,很拗口,是吧?仔细想想,这样很直观,也没有什么后遗症,权限自递归控制和自解释,真是一个完美的循环.<br />有爱思考的同学想深了,会觉得非常麻烦,难实现.当然,概念上一回事,具体实现上可以是另一回事,可以做很多的变通来达到目的.只要保持概念上的简单性,就足以使得非常多的人得以解脱了。</p>
		<p>另外，作为架构设计者，非常非常不赞成动辄就把很底层的概念扯进高层设计中（例如行级，数据库什么的），很容易把自己和别人搞胡涂。<br />可以最近状态不好，要不好好blog一篇，8过，有句话怎么说来着：“都素那浮云而已。。。”</p>
<img src ="http://www.blogjava.net/wolfsquare/aggbug/56606.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wolfsquare/" target="_blank">wolfsquare</a> 2006-07-04 22:45 <a href="http://www.blogjava.net/wolfsquare/archive/2006/07/04/56606.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不完美的世界－看到了IOC工具的又一个发展方向</title><link>http://www.blogjava.net/wolfsquare/archive/2006/06/08/51227.html</link><dc:creator>wolfsquare</dc:creator><author>wolfsquare</author><pubDate>Wed, 07 Jun 2006 16:30:00 GMT</pubDate><guid>http://www.blogjava.net/wolfsquare/archive/2006/06/08/51227.html</guid><wfw:comment>http://www.blogjava.net/wolfsquare/comments/51227.html</wfw:comment><comments>http://www.blogjava.net/wolfsquare/archive/2006/06/08/51227.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.blogjava.net/wolfsquare/comments/commentRss/51227.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wolfsquare/services/trackbacks/51227.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在本篇文章中，作者在一个系统的构建中深度地被各种配置逻辑所困扰，由此发现了IOC工具（如Spring，Nuts等）的又一个发展方向。&nbsp;&nbsp;<a href='http://www.blogjava.net/wolfsquare/archive/2006/06/08/51227.html'>阅读全文</a><img src ="http://www.blogjava.net/wolfsquare/aggbug/51227.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wolfsquare/" target="_blank">wolfsquare</a> 2006-06-08 00:30 <a href="http://www.blogjava.net/wolfsquare/archive/2006/06/08/51227.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>结合WebWork实现高复用度系统的探索(上) </title><link>http://www.blogjava.net/wolfsquare/archive/2006/05/17/46710.html</link><dc:creator>wolfsquare</dc:creator><author>wolfsquare</author><pubDate>Wed, 17 May 2006 15:40:00 GMT</pubDate><guid>http://www.blogjava.net/wolfsquare/archive/2006/05/17/46710.html</guid><wfw:comment>http://www.blogjava.net/wolfsquare/comments/46710.html</wfw:comment><comments>http://www.blogjava.net/wolfsquare/archive/2006/05/17/46710.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wolfsquare/comments/commentRss/46710.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wolfsquare/services/trackbacks/46710.html</trackback:ping><description><![CDATA[
		<p>需求: 某机构体系下,机构类型分为子公司,部门,人员等,以后可能在某机构或者其子孙机构下可能会再分出其他子机构类型,希望在增加新类型过程中,尽可能的避免修改已有代码。</p>
		<p>情况：子公司，部分，人员等已完成所有编码（界面，商业逻辑，数据逻辑）<br />变化：需要把这个机构体系组成为一颗树状结构<br />策略：鉴于除了树结构外的其他部分代码已经完成，那么应该首先保持这些代码不予改动。复用修改的优先级从高到低的顺序如下：<br />  界面×JSP，Action层<br />  商业逻辑 Service层<br />  数据逻辑层<br />  数据物理层<br />有经验的人知道，大部分情况下，越是下层的改动，越是影响越广泛（注意不是修改难度），所以我们只有在无计可施的情况下，才进行低层的修改。</p>
		<p>分析: 回到我们的需求,从功能上看，维护一个组织机构的需求，已经涵盖了每一个子结构的维护需求，以部门的建立为例，在新建一个部门时，同时也必须建立机构树上的节点，<br /> 这样，如果需要直接使用原有的创建部门的所有代码，需要在其上加上创建组织机构所需要的父节点，以及当前节点名称信息(在这里department的增加界 面JSP是需要修改的,不过实际上我没有修改该文件,而是利用DHTML来动态加入需要新增加的信息),然后提交给原创建部门的URI （departmentSave.action）和组织机构创建URI(orgCreate.action)，在这里我们利用ww提供的action chain功能来完成这两个操作。<br /> 这里需要修改department.action的配置,拦截save方法使其执行完后跳过原来的relist结果页面转向组织结构的创建orgCreate.action：<br /> &lt;action name="unitSave" class="com.wolfsquare.ibase.org.action.UnitAction" method="save"&gt;<br />   &lt;result name="input"&gt;/org/unit/input.jsp&lt;/result&gt;<br />   &lt;result name="relist" type="chain"&gt;<br />       &lt;param name="actionName"&gt;orgCreate&lt;/param&gt;<br />                &lt;param name="namespace"&gt;/org&lt;/param&gt;   <br />            &lt;/result&gt;<br />   &lt;result name="xxx" type="redirect"&gt;/org/unit.action?start=${start}&lt;/result&gt;<br />   &lt;interceptor-ref name="validationStack"/&gt;<br />  &lt;/action&gt;<br />可能有同学看到这里会问：创建组织节点时应该还需要关联前面创建的部门对象啊，这个操作是如何实现的？信息是如何传递的？<br />在这里，由于整个架构体系并没有支持这种信息传递的功能，所以只好以一种比较”脏“的方式实现：<br />        在department.action类里增加了一个方法getModel()返回刚刚创建的部门对象，然后在org.action类中增加一个接收的方法setModel(object o)这样在整action chain执行的时候，ww会自动将getModel后的数据填入setModel中，这样做的后果是以后增加新的机构类型的功能时，action必须也照这样的语意设置getModel方法。（如果要解决这个问题，这能需要使用一个特定的Context，然后拦截指定Service的创建方法，把创建结果放入Context，不过这又带来如何清除Context的问题，于是又要求助与ww的interspector，专门写一个拦截器来擦屁股，够麻烦。。。）</p>
		<p>        就这样,我们完成了新增，修改组织机构的功能合成,虽然有点拖沓,但是还是达到了复用,少修改原有代码,而且扩展性也很好的目标。这上篇说的是两个简单业务的功能揉合问题,下篇我们来看看稍微复杂点的情况,看看还能不能继续依葫芦画瓢来完成功能合的成<br />   <br />(未完待续)   <br /></p>
<img src ="http://www.blogjava.net/wolfsquare/aggbug/46710.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wolfsquare/" target="_blank">wolfsquare</a> 2006-05-17 23:40 <a href="http://www.blogjava.net/wolfsquare/archive/2006/05/17/46710.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>log4j配置简要说明</title><link>http://www.blogjava.net/wolfsquare/archive/2006/04/20/42242.html</link><dc:creator>wolfsquare</dc:creator><author>wolfsquare</author><pubDate>Thu, 20 Apr 2006 15:21:00 GMT</pubDate><guid>http://www.blogjava.net/wolfsquare/archive/2006/04/20/42242.html</guid><wfw:comment>http://www.blogjava.net/wolfsquare/comments/42242.html</wfw:comment><comments>http://www.blogjava.net/wolfsquare/archive/2006/04/20/42242.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wolfsquare/comments/commentRss/42242.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wolfsquare/services/trackbacks/42242.html</trackback:ping><description><![CDATA[虽然以前一直在用log4j,但是对其配置不甚了了，突然间因为需解决某些问题，要理解log4j的配置，<br />然而用google搜了一下，却发现网上没有一个简单直观的说明，于是只好看log4j的官方介绍,终于<br />理解了log4j的配置用法，以下是我对log4j配置的一点认识，如有谬误还请不吝赐教.
<p>首先我们搞清楚log4j能干什么，简单来说就是提供一个记录不同级别信息内容的日志工具，<br />可以把不同级别，不同包路径的信息，以指定格式输出到多种设备（控制台，文件等）<br />在程序中，可以以以下方式来使用<br />   Log log = org.apache.commons.logging.LogFactory.LogFactory.getLog(yourClassName.class);<br />  log.debug("debug message -------------------");<br />  log.info("info message ******************");<br />  log.warn("warn message +++++++++++++++");<br />  log.error("error msg================="); <br />  <br />本文主要讲的是如何配置log4j，先让我们先看看一个典型的log4j配置：   </p><p>==========log4j.properties==================</p><p>log4j.appender.stdout=org.apache.log4j.ConsoleAppender<br />log4j.appender.stdout.layout=org.apache.log4j.PatternLayout<br />log4j.appender.stdout.layout.ConversionPattern=%d{MM-dd HH\:mm\:ss.SSS} %-5p [%F\:%L]%x %m%n</p><p>log4j.appender.fileout=org.apache.log4j.RollingFileAppender<br />log4j.appender.fileout.File=D:/workspace/log4jtest/log/application.log<br />log4j.appender.fileout.MaxFileSize=10000KB<br />log4j.appender.fileout.MaxBackupIndex=10<br />log4j.appender.fileout.layout=org.apache.log4j.PatternLayout<br />log4j.appender.fileout.layout.ConversionPattern=%d{MM-dd HH:mm:ss.SSS}[%24F:%-3L:%-5p]%x %m%n</p><p>log4j.rootCategory=INFO, stdout, fileout<br />log4j.logger.com.wolfsquare.log2=DEBUG,stdout<br />===================================</p><p>这个文件可以划为三小块</p><p>===========第一块定义了一个名为 stdout 的appender和layout (appender,layout的概念后面再解释，目前先记着有这样两个名词)：</p><p>log4j.appender.stdout=org.apache.log4j.ConsoleAppender<br />定义stdout的实际输出实现类，从这个appender实现类名可以猜到，这个类是负责控制台输出的。<br />log4j.appender.stdout.layout=org.apache.log4j.PatternLayout<br />定义stdout的输出装饰器<br />log4j.appender.stdout.layout.ConversionPattern=%d{MM-dd HH\:mm\:ss.SSS} %-5p [%F\:%L]%x %m%n<br />装饰器参数配置</p><p><br />============第二块定义了一个名为 fileout 的appender和layout:<br />log4j.appender.fileout=org.apache.log4j.RollingFileAppender<br />同理可猜这个实现类是输出到文件的<br />log4j.appender.fileout.File=D:/workspace/log4jtest/log/application.log<br />log4j.appender.fileout.MaxFileSize=10000KB<br />log4j.appender.fileout.MaxBackupIndex=10<br />log4j.appender.fileout.layout=org.apache.log4j.PatternLayout<br />log4j.appender.fileout.layout.ConversionPattern=%d{MM-dd HH:mm:ss.SSS}[%24F:%-3L:%-5p]%x %m%n</p><p>============第三块定义了名字分别为rootCategory,log4j.logger.com.wolfsquare.log2的两个logger<br />log4j.rootCategory=INFO, stdout, fileout<br />log4j.logger.com.wolfsquare.log2=DEBUG,stdout</p><p>rootCategory logger是缺省的logger，记录所有的包的信息输出。<br />第二个logger是只输出指定包com.wolfsquare.log2下的日志信息。<br />那么INFO,DEBUG又是什么意思呢，他们是信息的分级标识，通过继承实现这个实现自定义级别的分级。<br />第三块配置两句的意思是这样的：<br />rootCategory 把所有类的INFO级别以上的信息输出到stdout和fileout两个appender中，<br />logger.com.wolfsquare.log2，把com.wolfsquare.log2包中的所有类（包括子包）DEBUG级别（含）以上的信息输出到stdout 中<br />一个logger可以输出到很多个设备中（appender）,如果需要增加输出设备则用分号分隔开appender名称即可。</p><p>输出信息的分类级别是DEBUG &gt; INFO &gt; WARN &gt; ERROR,信息细节由细到粗，指定输出某一级别的信息时，<br />过细的信息输出将会被忽略</p><p>如果一个配置中有多个logger，他们之间会有什么关系呢？答案是，在输出上，他们没有任何关系，都是独立运作的，<br />不相关的，但是在配置上，父包的配置会传给子包，如果子包没有另外定义配置的话。<br />例如上面配置文件中的两个logger：<br />log4j.logger.com.wolfsquare<br />log4j.logger.com.wolfsquare.log2</p><p>这里认为 log4j.logger.com.wolfsquare.log2 继承自 log4j.logger.com.wolfsquare，他们的配置声明如下：<br />log4j.rootCategory=INFO, stdout, fileout<br />log4j.logger.com.wolfsquare.log2=,stdout<br />注意第二句没有指定输出级别,那么根据配置继承规则会继承父logger的配置，在这里就是INFO。</p><p>同时需要强调的是，如果两个logger有继承关系，且输出到同一个appender，根据输出独立原则，那么将会出现两行一样的信息，<br />例如上面的两个logger定义会导致这样的情况。<br />最后以一幅图来概括：<br /><img src="http://java.mblogger.cn/upimgs/java.mblogger.cn/wolfsquare/2006-4/2006_420273.gif" /></p><img src ="http://www.blogjava.net/wolfsquare/aggbug/42242.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wolfsquare/" target="_blank">wolfsquare</a> 2006-04-20 23:21 <a href="http://www.blogjava.net/wolfsquare/archive/2006/04/20/42242.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring配置中bean的循环引用问题及解决方法</title><link>http://www.blogjava.net/wolfsquare/archive/2006/02/07/29750.html</link><dc:creator>wolfsquare</dc:creator><author>wolfsquare</author><pubDate>Tue, 07 Feb 2006 00:53:00 GMT</pubDate><guid>http://www.blogjava.net/wolfsquare/archive/2006/02/07/29750.html</guid><wfw:comment>http://www.blogjava.net/wolfsquare/comments/29750.html</wfw:comment><comments>http://www.blogjava.net/wolfsquare/archive/2006/02/07/29750.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wolfsquare/comments/commentRss/29750.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wolfsquare/services/trackbacks/29750.html</trackback:ping><description><![CDATA[<P>问题：Spring+Hibernate的应用中，定义了两个业务Service，这里分别称它们为serivceA，ServiceB。<BR>它们的关系简单点来说是这样的：<BR>serviceA需要引用serviceB，在serviceB中定义了一个接口列表，serverA必须在serviceB初始化时设置进列表。<BR>在纯bean的情况下，也就是这两个类不需要设置其他bean的情况下，循环引用是正常的，可以通过的。例如下面配置所表示：</P>
<P>&nbsp;&nbsp;&nbsp; &lt;bean id="serviceA" class="A"&nbsp; autowire="byName"&nbsp; lazy-init="true"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="serviceB"&gt;&lt;ref local="serviceB"/&gt;&lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<BR>&nbsp;&lt;bean id="serviceB" class="B"&nbsp; autowire="byName"&nbsp; lazy-init="true"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="serviceA"&gt;&lt;ref bean="serviceA"/&gt;&lt;/property&gt;<BR>&nbsp;&lt;/bean&gt;<BR>但是作为一个业务接口，它应该是不需要关心事务，回滚这些无关的东西，<BR>但现实又有这样的需求，所以我们必须保证透明的实现这个功能，于是引<BR>入了AOP方式解决该问题，利用的是Spring自带的org.springframework.t<BR>ransaction.interceptor.TransactionProxyFactoryBean.<BR>重新声明文件如下：<BR>&nbsp;&nbsp; &lt;bean id="baseTxProxy" lazy-init="true" <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="proxyTargetClass"&gt;&lt;value&gt;true&lt;/value&gt;&lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="transactionAttributes"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;props&gt;<BR>&nbsp; &lt;prop key="*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/props&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; &lt;bean id="serviceA" parent="baseTxProxy"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="target"&gt;&lt;ref local="serviceAImpl"/&gt;&lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp; &lt;bean id="serviceAImpl" class="serviceA"&nbsp; autowire="byName"&nbsp; lazy-init="true"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="serviceB"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ref bean="serviceB"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<BR>&nbsp;&nbsp; &lt;/bean&gt;<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; &lt;bean id="serviceB" parent="baseTxProxy" lazy-init="true"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="target"&gt;&lt;ref local="serviceBImpl"/&gt;&lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<BR>&nbsp;&nbsp; <BR>&nbsp;&nbsp; &lt;bean id="serviceBImpl" class="D" lazy-init="true"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="serviceA"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ref bean="serviceA"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<BR>&nbsp;&nbsp; &lt;/bean&gt;<BR>于是问题就出现了，Spring报了FactoryBeanCircularReferenceException，无法继续完成设置工作。<BR>查看TransactionProxyFactoryBean源码，其实现了FactoryBean和InitializingBean接口，应该是<BR>做了代理之后，两个代理Bean需要等待所有Bean设置完成后才会标识状态为初始化完毕，于是造成了<BR>冲突。</P>
<P>&nbsp;&nbsp;&nbsp; 由于两个业务服务互相调用的路径是不相交的，所以采用了一种变通的方法，在声明serviceA时，<BR>直接定义serviceB：<BR>&nbsp; &lt;bean id="serviceAImpl" class="serviceA"&nbsp; autowire="byName"&nbsp; lazy-init="true"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="serviceB"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean class="B"&nbsp; autowire="byName"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<BR>&nbsp;&lt;/bean&gt;<BR>相当于serviceB和serviceA中使用的serviceB不是同一个实例。<BR>&nbsp;<BR>&nbsp;但是如果确实调用重合时怎么办？<BR>&nbsp;<BR>&nbsp;解决方法是这样的：<BR>&nbsp;<BR>&nbsp;&lt;bean id="serviceAImpl" class="serviceA"&nbsp; autowire="byName"&nbsp; lazy-init="true"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="serviceB"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ref bean="serviceBImpl"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<BR>&nbsp;&lt;/bean&gt;<BR>&nbsp;<BR>&nbsp; 非常简单，serviceAImpl调用时，可能已经在事务环境中了，不需再使用serviceB代理的事务支持，<BR>&nbsp; 于是直接引用serviceB实例。这个方法是我写这篇文章时想到的，-_-!!!，看来知识果真还是好好<BR>&nbsp; 整理呀。</P>
<P>&nbsp;</P><img src ="http://www.blogjava.net/wolfsquare/aggbug/29750.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wolfsquare/" target="_blank">wolfsquare</a> 2006-02-07 08:53 <a href="http://www.blogjava.net/wolfsquare/archive/2006/02/07/29750.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring+Hibernate+Websphere5.0经验一则</title><link>http://www.blogjava.net/wolfsquare/archive/2006/02/07/29749.html</link><dc:creator>wolfsquare</dc:creator><author>wolfsquare</author><pubDate>Tue, 07 Feb 2006 00:50:00 GMT</pubDate><guid>http://www.blogjava.net/wolfsquare/archive/2006/02/07/29749.html</guid><wfw:comment>http://www.blogjava.net/wolfsquare/comments/29749.html</wfw:comment><comments>http://www.blogjava.net/wolfsquare/archive/2006/02/07/29749.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wolfsquare/comments/commentRss/29749.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wolfsquare/services/trackbacks/29749.html</trackback:ping><description><![CDATA[<P>环境Spring1.1.3,Hibernate 2.1.8， Websphere5.01</P>
<P>hbm文件采用通配符获取：</P>
<P><BEAN class=com.wolfsquare.core.hibernate.DefaultSessionFactoryBean id=sessionFactory><BR>&nbsp;&nbsp;<property name="dataSource"><REF bean="dataSource" /></property><BR>&nbsp;&nbsp;<property name="mappingLocations"><BR>&nbsp;&nbsp;&nbsp;<VALUE>classpath:/**/*.hbm.xml</VALUE><BR>&nbsp;&nbsp;</property><BR>&nbsp;&nbsp;<property name="hibernateProperties"><REF bean="hibernateProperties" /></property><BR>&nbsp;</BEAN></P>
<P>问题症状：</P>
<P>应用启动报错说不能重复定义某类，去掉该类后仍然报下一个类重复定义。</P>
<P>仔细查看Log输出发现，所有的hbm文件均找到了两份 -_-!!!</P>
<P>项目组认为应该是websphere不太厚道，在classpath中使用了多处目录(web-inf &amp; classes)，并以这些目录为根进行递归搜索匹配文件，可是如果这些目录有包含关系，WebSphere就没有处理重复查找的文件了。</P>
<P>于是在以上配置中改为：</P>
<P><BEAN class=com.wolfsquare.core.hibernate.DefaultSessionFactoryBean id=sessionFactory><BR>&nbsp;&nbsp;<property name="dataSource"><REF bean="dataSource" /></property><BR>&nbsp;&nbsp;<property name="mappingLocations"><BR>&nbsp;&nbsp;&nbsp;<VALUE>classpath:/classes/**/*.hbm.xml</VALUE><BR>&nbsp;&nbsp;</property><BR>&nbsp;&nbsp;<property name="hibernateProperties"><REF bean="hibernateProperties" /></property><BR>&nbsp;</BEAN></P>
<P>问题虽然解决了，可是tomcat中却又无效了。 ：（</P>
<P>什么时候，企业应用才能一次拷贝，到处运行啊～～</P><img src ="http://www.blogjava.net/wolfsquare/aggbug/29749.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wolfsquare/" target="_blank">wolfsquare</a> 2006-02-07 08:50 <a href="http://www.blogjava.net/wolfsquare/archive/2006/02/07/29749.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>修改Tds驱动Url声明解决两个Sql Server问题</title><link>http://www.blogjava.net/wolfsquare/archive/2006/02/07/29748.html</link><dc:creator>wolfsquare</dc:creator><author>wolfsquare</author><pubDate>Tue, 07 Feb 2006 00:49:00 GMT</pubDate><guid>http://www.blogjava.net/wolfsquare/archive/2006/02/07/29748.html</guid><wfw:comment>http://www.blogjava.net/wolfsquare/comments/29748.html</wfw:comment><comments>http://www.blogjava.net/wolfsquare/archive/2006/02/07/29748.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wolfsquare/comments/commentRss/29748.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wolfsquare/services/trackbacks/29748.html</trackback:ping><description><![CDATA[<P>问题1：JDBC Sql Server varchar的取出最大长度限制</P>
<P>环境： JDBC驱动inet tds驱动(版本不明),SQLServer2K</P>
<P>问题症状：对于数据库声明为varchar的长度大于256的字段，可以正常保存，但是无法取出多于256字符以后的内容</P>
<P>问题2：使用Hibernate映射时0长度字符串保存后，取出多加了一个空格</P>
<P>环境：inet tds驱动Hibernate2.1.8,SQL Server2K</P>
<P>问题症状：保存0长度字符串后，取出增加了多余的空格。</P>
<P>以上两个问题都是因为没有使用最新的通讯协议引起的，修改URL声明方式如下：</P>
<P>jdbc:inetdae7:127.0.0.1:1433?database=xxx</P>
<P>问题解决，收工。</P>
<P>ps:发现协议inetdae时，数据库字段为Null时，Hibernate取出声明为基本类型（例如boolean）的对象属性并不会报错，实际上在其他数据库如Oracle和新协议上是会报错的。为了避免此类问题出现，最好还是严格遵守：Hibernate声明对象的基本类型属性，一定不能在数据库端置为空值。</P>
<P>ps2:在解决以上问题中发现,Oracle居然对传人0长度字符串，会转为空值,不知道是为了节省空间还是别的什么理由。-_-!!!</P>
<P>（<STRONG><FONT color=#0000ff>全文完</FONT></STRONG>）</P><img src ="http://www.blogjava.net/wolfsquare/aggbug/29748.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wolfsquare/" target="_blank">wolfsquare</a> 2006-02-07 08:49 <a href="http://www.blogjava.net/wolfsquare/archive/2006/02/07/29748.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java高精度打印</title><link>http://www.blogjava.net/wolfsquare/archive/2006/02/06/29732.html</link><dc:creator>wolfsquare</dc:creator><author>wolfsquare</author><pubDate>Mon, 06 Feb 2006 13:44:00 GMT</pubDate><guid>http://www.blogjava.net/wolfsquare/archive/2006/02/06/29732.html</guid><wfw:comment>http://www.blogjava.net/wolfsquare/comments/29732.html</wfw:comment><comments>http://www.blogjava.net/wolfsquare/archive/2006/02/06/29732.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/wolfsquare/comments/commentRss/29732.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wolfsquare/services/trackbacks/29732.html</trackback:ping><description><![CDATA[<P>&nbsp;&nbsp;&nbsp; 在Java环境中,可以使用 java.awt.Toolkit.getScreenResolution()可以得到屏幕每英寸的象素数,但是好像没有什么方法能知道某一台打印机的分辨率,更别提去控制打印粒度了。于是可耻的使用着丑陋的缺省打印精度几年后，终于找到了解决方法，不知道该高兴还是悲伤，其原理说出来也是非常的简单： <BR>&nbsp;&nbsp;&nbsp; 提高打印精度，其实就是把本来是A3纸的内容往A4纸里画，也就是说，打印区域（这里对应着Java里的Graphics对象）需要缩小，然后由于缺省情况下打印是照72DPI来打的，不做改变的话，打印内容也会跟着变小。这样就不是我们想要的效果了，所以还得把打印内容成比例放大。一个缩小，一个放大，于是画完后，在指定大小的纸张内，便容纳了比以往更多象素的内容，这下世界总算完美了。</P>
<P>&nbsp;&nbsp;&nbsp; 以上做法形象的说应该是这样：<STRONG>把需要产生的图形对象先放大，画在一张“纸上”，然后整体缩小</STRONG>，这样精度就提高了。</P>
<P>&nbsp;&nbsp;&nbsp; tips 1：在一般企业报表表格打印中，使用144DPI得到的表格线的宽度看起来最舒服。<BR>&nbsp;&nbsp;&nbsp; tips 2：现在号称600DPI的打印机其实是576DPI，如果想使用这个分辨率的精度，需要用好一点的纸张，因为已经到极限了，纸张稍差点，打印墨粉就沾不上，导致线体残缺。</P>
<P>附源码（修改分辨率就改动变量iResMul就好）：</P>
<P>&nbsp;</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;java.awt.</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;java.awt.print.</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR><IMG id=Codehighlighter1_97_2979_Open_Image onclick="this.style.display='none'; Codehighlighter1_97_2979_Open_Text.style.display='none'; Codehighlighter1_97_2979_Closed_Image.style.display='inline'; Codehighlighter1_97_2979_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_97_2979_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_97_2979_Closed_Text.style.display='none'; Codehighlighter1_97_2979_Open_Image.style.display='inline'; Codehighlighter1_97_2979_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;MyPrintableObject&nbsp;</SPAN><SPAN style="COLOR: #0000ff">implements</SPAN><SPAN style="COLOR: #000000">&nbsp;Printable&nbsp;</SPAN><SPAN id=Codehighlighter1_97_2979_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_97_2979_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;iResMul&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;1&nbsp;=&nbsp;72&nbsp;dpi;&nbsp;4&nbsp;=&nbsp;288&nbsp;dpi<IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;print(Graphics&nbsp;g,&nbsp;PageFormat&nbsp;pf,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;iPage)<BR><IMG id=Codehighlighter1_238_2608_Open_Image onclick="this.style.display='none'; Codehighlighter1_238_2608_Open_Text.style.display='none'; Codehighlighter1_238_2608_Closed_Image.style.display='inline'; Codehighlighter1_238_2608_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_238_2608_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_238_2608_Closed_Text.style.display='none'; Codehighlighter1_238_2608_Open_Image.style.display='inline'; Codehighlighter1_238_2608_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">throws</SPAN><SPAN style="COLOR: #000000">&nbsp;PrinterException&nbsp;</SPAN><SPAN id=Codehighlighter1_238_2608_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_238_2608_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">final</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;FONTSIZE&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">12</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">final</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&nbsp;PNT_MM&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">25.4</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">72</SPAN><SPAN style="COLOR: #000000">.;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">&nbsp;iPage)<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;NO_SUCH_PAGE;<BR><IMG id=Codehighlighter1_351_2508_Open_Image onclick="this.style.display='none'; Codehighlighter1_351_2508_Open_Text.style.display='none'; Codehighlighter1_351_2508_Closed_Image.style.display='inline'; Codehighlighter1_351_2508_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_351_2508_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_351_2508_Closed_Text.style.display='none'; Codehighlighter1_351_2508_Open_Image.style.display='inline'; Codehighlighter1_351_2508_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">try</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN id=Codehighlighter1_351_2508_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_351_2508_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;iPosX&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;iPosY&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;iAddY&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;FONTSIZE&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;iResMul;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;iWdth&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">)&nbsp;Math.round(pf.getImageableWidth()&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;iResMul)&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;iHght&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">)&nbsp;Math.round(pf.getImageableHeight()&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;iResMul)&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;iCrcl&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;Math.min(iWdth,&nbsp;iHght)&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">4</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;iResMul;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;Graphics2D&nbsp;g2&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(Graphics2D)&nbsp;g;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;PrinterJob&nbsp;prjob&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;((PrinterGraphics)&nbsp;g2).getPrinterJob();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;g2.translate(pf.getImageableX(),&nbsp;pf.getImageableY());<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;g2.scale(</SPAN><SPAN style="COLOR: #000000">1.0</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">&nbsp;iResMul,&nbsp;</SPAN><SPAN style="COLOR: #000000">1.0</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">&nbsp;iResMul);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;g2.setFont(</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Font(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">SansSerif</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;Font.PLAIN,&nbsp;FONTSIZE&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;iResMul));<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;g2.setColor(Color.black);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;g2.drawRect(iPosX,&nbsp;iPosY,&nbsp;iWdth,&nbsp;iHght);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;g2.drawLine(iPosX,&nbsp;iHght&nbsp;</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;iWdth&nbsp;</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">50</SPAN><SPAN style="COLOR: #000000">,&nbsp;iPosX&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;iWdth,&nbsp;iHght&nbsp;</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;iWdth&nbsp;</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">50</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;g2.drawLine(iPosX,&nbsp;iHght&nbsp;</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;iWdth&nbsp;</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">50</SPAN><SPAN style="COLOR: #000000">,&nbsp;iPosX&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;iWdth,&nbsp;iHght&nbsp;</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;iWdth&nbsp;</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">50</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;g2.drawOval(iPosX&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;iResMul,&nbsp;iHght&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;iCrcl&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;iResMul,<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iCrcl,&nbsp;iCrcl);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;iPosX&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;iAddY;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;iPosY&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;iAddY&nbsp;</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;g2.drawString(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">PrinterJob-UserName:&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;prjob.getUserName(),&nbsp;iPosX,<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iPosY&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;iAddY);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;g2.drawString(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Betriebssystem:&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;System.getProperty(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">os.name</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;System.getProperty(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">os.version</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">),&nbsp;iPosX,<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iPosY&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;iAddY);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;g2<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.drawString(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Java-Version:&nbsp;JDK&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;System.getProperty(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">java.version</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">),&nbsp;iPosX,<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iPosY&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;iAddY);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;g2.drawString(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Width/Height:&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;dbldgt(pf.getWidth())&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;/&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;dbldgt(pf.getHeight())&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;points&nbsp;=&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;dbldgt(pf.getWidth()&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;PNT_MM)&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;/&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;dbldgt(pf.getHeight()&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;PNT_MM)&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;mm</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;iPosX,<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iPosY&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;iAddY);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;g2.drawString(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Imageable&nbsp;Width/Height:&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;dbldgt(pf.getImageableWidth())&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;/&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;dbldgt(pf.getImageableHeight())&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;points&nbsp;=&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;dbldgt(pf.getImageableWidth()&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;PNT_MM)&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;/&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;dbldgt(pf.getImageableHeight()&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;PNT_MM)&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;mm</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;iPosX,<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iPosY&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;iAddY);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;g2.drawString(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Imageable&nbsp;X/Y:&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;dbldgt(pf.getImageableX())<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;/&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;dbldgt(pf.getImageableY())&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;points&nbsp;=&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;dbldgt(pf.getImageableX()&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;PNT_MM)&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;/&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;dbldgt(pf.getImageableY()&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;PNT_MM)&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;mm</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;iPosX,<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iPosY&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;iAddY);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;g2.drawString(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">versuchte&nbsp;Druckaufl&nbsp;sung:&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">72</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;iResMul&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;dpi</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iPosX,&nbsp;iPosY&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;iAddY);<BR><IMG id=Codehighlighter1_2531_2583_Open_Image onclick="this.style.display='none'; Codehighlighter1_2531_2583_Open_Text.style.display='none'; Codehighlighter1_2531_2583_Closed_Image.style.display='inline'; Codehighlighter1_2531_2583_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_2531_2583_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_2531_2583_Closed_Text.style.display='none'; Codehighlighter1_2531_2583_Open_Image.style.display='inline'; Codehighlighter1_2531_2583_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000">&nbsp;(Exception&nbsp;ex)&nbsp;</SPAN><SPAN id=Codehighlighter1_2531_2583_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_2531_2583_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">throw</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;PrinterException(ex.getMessage());<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;PAGE_EXISTS;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG id=Codehighlighter1_2651_2720_Open_Image onclick="this.style.display='none'; Codehighlighter1_2651_2720_Open_Text.style.display='none'; Codehighlighter1_2651_2720_Closed_Image.style.display='inline'; Codehighlighter1_2651_2720_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_2651_2720_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_2651_2720_Closed_Text.style.display='none'; Codehighlighter1_2651_2720_Open_Image.style.display='inline'; Codehighlighter1_2651_2720_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&nbsp;dbldgt(</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&nbsp;d)&nbsp;</SPAN><SPAN id=Codehighlighter1_2651_2720_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_2651_2720_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;Math.round(d&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">10</SPAN><SPAN style="COLOR: #000000">.)&nbsp;</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">10</SPAN><SPAN style="COLOR: #000000">.;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;show&nbsp;one&nbsp;digit&nbsp;after&nbsp;point</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG id=Codehighlighter1_2763_2977_Open_Image onclick="this.style.display='none'; Codehighlighter1_2763_2977_Open_Text.style.display='none'; Codehighlighter1_2763_2977_Closed_Image.style.display='inline'; Codehighlighter1_2763_2977_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_2763_2977_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_2763_2977_Closed_Text.style.display='none'; Codehighlighter1_2763_2977_Open_Image.style.display='inline'; Codehighlighter1_2763_2977_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;main(String[]&nbsp;args)&nbsp;</SPAN><SPAN id=Codehighlighter1_2763_2977_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_2763_2977_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;PrinterJob&nbsp;pj&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;PrinterJob.getPrinterJob();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;pj.setPrintable(</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;MyPrintableObject());<BR><IMG id=Codehighlighter1_2879_2974_Open_Image onclick="this.style.display='none'; Codehighlighter1_2879_2974_Open_Text.style.display='none'; Codehighlighter1_2879_2974_Closed_Image.style.display='inline'; Codehighlighter1_2879_2974_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_2879_2974_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_2879_2974_Closed_Text.style.display='none'; Codehighlighter1_2879_2974_Open_Image.style.display='inline'; Codehighlighter1_2879_2974_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(pj.printDialog())&nbsp;</SPAN><SPAN id=Codehighlighter1_2879_2974_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_2879_2974_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG id=Codehighlighter1_2888_2909_Open_Image onclick="this.style.display='none'; Codehighlighter1_2888_2909_Open_Text.style.display='none'; Codehighlighter1_2888_2909_Closed_Image.style.display='inline'; Codehighlighter1_2888_2909_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_2888_2909_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_2888_2909_Closed_Text.style.display='none'; Codehighlighter1_2888_2909_Open_Image.style.display='inline'; Codehighlighter1_2888_2909_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">try</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN id=Codehighlighter1_2888_2909_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_2888_2909_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pj.print();<BR><IMG id=Codehighlighter1_2938_2970_Open_Image onclick="this.style.display='none'; Codehighlighter1_2938_2970_Open_Text.style.display='none'; Codehighlighter1_2938_2970_Closed_Image.style.display='inline'; Codehighlighter1_2938_2970_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_2938_2970_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_2938_2970_Closed_Text.style.display='none'; Codehighlighter1_2938_2970_Open_Image.style.display='inline'; Codehighlighter1_2938_2970_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000">&nbsp;(PrinterException&nbsp;e)&nbsp;</SPAN><SPAN id=Codehighlighter1_2938_2970_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_2938_2970_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(e);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN></DIV>
<P><BR>（<STRONG><FONT color=#0000ff>全文完</FONT></STRONG>）&nbsp;&nbsp;&nbsp; </P><img src ="http://www.blogjava.net/wolfsquare/aggbug/29732.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wolfsquare/" target="_blank">wolfsquare</a> 2006-02-06 21:44 <a href="http://www.blogjava.net/wolfsquare/archive/2006/02/06/29732.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于拦截器的企业应用构造</title><link>http://www.blogjava.net/wolfsquare/archive/2005/12/06/22772.html</link><dc:creator>wolfsquare</dc:creator><author>wolfsquare</author><pubDate>Tue, 06 Dec 2005 12:49:00 GMT</pubDate><guid>http://www.blogjava.net/wolfsquare/archive/2005/12/06/22772.html</guid><wfw:comment>http://www.blogjava.net/wolfsquare/comments/22772.html</wfw:comment><comments>http://www.blogjava.net/wolfsquare/archive/2005/12/06/22772.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/wolfsquare/comments/commentRss/22772.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wolfsquare/services/trackbacks/22772.html</trackback:ping><description><![CDATA[<P>&nbsp;&nbsp;&nbsp; 在<A HREF="/wolfsquare/archive/2005/12/05/22630.html">上一篇文章</A>里，我们使用了基于事件传递的机制来对企业应用的子系统进行解耦，但是由于需要强制地继承或者实现一个广播事件的接口EventBrocast，实际上，就职责分离和功能单一的角度来看，前篇文章中的例子中，这个机制对OrderService侵入太大了，我们必须寻找更为有效的方法，不需要程序实现某个接口或继承某个超类来完成这个工作，这一切必须对具体程序完全透明，这个责任谁能承担呢，毫无疑问，历史的重担就落在了AOP身上 ；） 。下面我们来看看具体的实现：<BR>&nbsp;&nbsp;&nbsp; OrderService已经实现，除了订单的处理，没有任何的职责，为了完成事件的广播，必须要有一个途径能够拦截到OrderService的所有方法调用，然后分析调用的语义（参数），并根据这些内容给广播出去。而恰好，AOP组织统一的接口MethodInterceptor可以完成这个功能。于是上篇文章的程序可以这样修改：</P>
<P>&nbsp;&nbsp; // 订单服务只负责做好自己的事<BR>&nbsp;&nbsp;</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;OrderService&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;Order&nbsp;saveOrder(Order&nbsp;order){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;。。。。处理订单<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;。。。保存<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}</SPAN></DIV>
<P>&nbsp;</P>
<P>&nbsp; 而为了拦截任何的方法调用，则实现了拦截器EventBrocaster：<BR>&nbsp; </P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;EventBrocaster&nbsp;</SPAN><SPAN style="COLOR: #0000ff">extends</SPAN><SPAN style="COLOR: #000000">&nbsp;LifeEventBrocast&nbsp;</SPAN><SPAN style="COLOR: #0000ff">implements</SPAN><SPAN style="COLOR: #000000">&nbsp;MethodInterceptor&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;List&nbsp;eventListeners;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;setEventListener(List&nbsp;list){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.eventListeners</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">list;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;List&nbsp;geteEventListeners(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;eventListeners;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;Object&nbsp;invoke(MethodInvocation&nbsp;invoke)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;invoke.proceed();</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;执行被拦截的方法完成业务操作</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object[]&nbsp;params&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;invoke.getArguments();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;param&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;params.length&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">?</SPAN><SPAN style="COLOR: #000000">&nbsp;params&nbsp;:&nbsp;params[</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Event&nbsp;le&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Event(param,&nbsp;eventType);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;brocast(le);</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;广播</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}</SPAN></DIV>
<P>&nbsp;</P>
<P>&nbsp; 事件侦听器：<BR>&nbsp;</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;OrderEventListener&nbsp;</SPAN><SPAN style="COLOR: #0000ff">implements</SPAN><SPAN style="COLOR: #000000">&nbsp;EventListener{<BR>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;FinancialService&nbsp;&nbsp;financialService;<BR>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;setFinancialService(FinancialService&nbsp;fs){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.financialService</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">fs;<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;performed(Event&nbsp;e){<BR>&nbsp;&nbsp;&nbsp;Order&nbsp;order&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">(Order)&nbsp;e.getObject();<BR>&nbsp;&nbsp;&nbsp;&nbsp;financialService.createRequestOfMoney(order.getAmount()<IMG src="http://www.blogjava.net/images/dot.gif">);<BR>&nbsp;&nbsp;}<BR>&nbsp;}</SPAN></DIV>
<P>&nbsp;</P>
<P><BR>&nbsp; 然后，在Spring配置里将这些组件全部连接起来：</P>
<P>&nbsp;1.OrderService实现:<BR>&nbsp;&lt;bean id="orderServiceImpl" class="OrderService" autowire="byName"&gt;<BR>&nbsp;&lt;/bean&gt;</P>
<P>&nbsp;2. 声明OrderService代理:</P>
<P>&nbsp;&lt;bean id="orderService" class="org.springframework.aop.framework.ProxyFactoryBean"&gt;<BR>&nbsp;&nbsp;&lt;property name="target"&gt;<BR>&nbsp;&nbsp;&nbsp;&lt;ref local="orderServiceImpl"/&gt;<BR>&nbsp;&nbsp;&lt;/property&gt;<BR>&nbsp;&nbsp;&lt;property name="interceptorNames"&gt; &lt;!--拦截器列表--&gt;<BR>&nbsp;&nbsp;&nbsp;&lt;list&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;eventBrocaster&lt;/value&gt;<BR>&nbsp;&nbsp;&nbsp;&lt;/list&gt;<BR>&nbsp;&nbsp;&lt;/property&gt;<BR>&nbsp;&nbsp;&lt;property name="singleton"&gt;<BR>&nbsp;&nbsp;&nbsp;&lt;value&gt;true&lt;/value&gt;<BR>&nbsp;&nbsp;&lt;/property&gt;<BR>&nbsp;&lt;/bean&gt;<BR>&nbsp; 3.事件广播拦截器<BR>&nbsp;&lt;bean id="eventBrocaster" class="com.wolfsquare.core.service.EventBrocaster" singleton="true"&gt;<BR>&nbsp;&nbsp;&lt;property name="lifecycleListeners"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&lt;list&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&lt;ref bean="orderEventListener"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&lt;/list&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<BR>&nbsp;&lt;/bean&gt;<BR>&nbsp; 4.具体的财务子系统的侦听器实现与财务系统的通讯：<BR>&nbsp; &lt;bean id="orderEventListener" class="OrderEventListener" autowire="byName"&gt;<BR>&nbsp; &nbsp;&lt;propety name="financialService"&gt;&lt;ref bean="financialService"/&gt;&lt;/property&gt;<BR>&nbsp;&lt;/bean&gt;</P>
<P>&nbsp;&nbsp;&nbsp; 这样，我们与具体实现无关的事件广播就做到了，聪明的朋友看到这里，肯定想到了拦截器方式不仅仅适用与事件广播，还可以实现事务的统一管理，事实上Spring的事务管理就是这样完成的，还可以实现权限的控制例如Acegi，简直有点象万能的胶水，呵呵。</P>
<P>&nbsp;&nbsp;&nbsp; 从两篇文章的逐步探讨下，同一个机器，同一个虚拟机之内的数据通讯都可以实现了，那么异构系统和多虚拟机间的通讯又如何处理呢，于是ESB（企业服务总线）的概念就慢慢浮现出来了，不过这个不在本文探讨的范畴了，也许在不久的将来，我会补上这一篇。</P>
<P><FONT color=#0000ff><STRONG>（全文完）</STRONG></FONT></P>
<P>&nbsp;</P>
<P>&nbsp;</P><img src ="http://www.blogjava.net/wolfsquare/aggbug/22772.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wolfsquare/" target="_blank">wolfsquare</a> 2005-12-06 20:49 <a href="http://www.blogjava.net/wolfsquare/archive/2005/12/06/22772.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>