??xml version="1.0" encoding="utf-8" standalone="yes"?>国产高清久久,中文成人激情娱乐网,国产在线观看一区二区三区http://www.aygfsteel.com/cherishchen/category/23923.htmlzh-cnWed, 12 May 2010 02:35:11 GMTWed, 12 May 2010 02:35:11 GMT60关于Java String的intern and ==的笔试题Q没有全{对http://www.aygfsteel.com/cherishchen/archive/2008/03/17/186782.html凭栏观v凭栏观vMon, 17 Mar 2008 07:43:00 GMThttp://www.aygfsteel.com/cherishchen/archive/2008/03/17/186782.htmlhttp://www.aygfsteel.com/cherishchen/comments/186782.htmlhttp://www.aygfsteel.com/cherishchen/archive/2008/03/17/186782.html#Feedback0http://www.aygfsteel.com/cherishchen/comments/commentRss/186782.htmlhttp://www.aygfsteel.com/cherishchen/services/trackbacks/186782.html
package testPackage;
class Test {
public static void main(String[] args) {
String hello = "Hello", lo = "lo";
System.out.print((hello == "Hello") + " ");
System.out.print((Other.hello == hello) + " ");
System.out.print((other.Other.hello == hello) + " ");
System.out.print((hello == ("Hel"+"lo")) + " ");
System.out.print((hello == ("Hel"+lo)) + " ");
System.out.println(hello == ("Hel"+lo).intern());
}
}
class Other { static String hello = "Hello"; }

       

        and the compilation unit:

package other;
public class Other { static String hello = "Hello"; }
 正确{案Qtrue true true true false true
 

This example illustrates six points:

  • Literal strings within the same class (§8) in the same package (§7) represent references to the same String object (§4.3.1).
  • Literal strings within different classes in the same package represent references to the same String object.
  • Literal strings within different classes in different packages likewise represent references to the same String object.
  • Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals.
  • Strings computed at run time are newly created and therefore distinct.
  • The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents.

 

呵呵Q我是没有能够全部答?/p>

 

另外一关于String intern的文章:

http://laiseeme.javaeye.com/blog/102442



凭栏观v 2008-03-17 15:43 发表评论
]]>
设计及设计模式:关于Java权限控制法(转)http://www.aygfsteel.com/cherishchen/archive/2008/02/25/181882.html凭栏观v凭栏观vMon, 25 Feb 2008 01:20:00 GMThttp://www.aygfsteel.com/cherishchen/archive/2008/02/25/181882.htmlhttp://www.aygfsteel.com/cherishchen/comments/181882.htmlhttp://www.aygfsteel.com/cherishchen/archive/2008/02/25/181882.html#Feedback0http://www.aygfsteel.com/cherishchen/comments/commentRss/181882.htmlhttp://www.aygfsteel.com/cherishchen/services/trackbacks/181882.htmlhttp://publish.itpub.net/j/2008-01-24/200801240919412.shtml

作者:来自ITPUB论坛  2008-01-24


向大家介l一U很不错Q也是Linux中的权限理法?

  定义a^b为:a的bơ方

  假如Q我们ؓ每一个操作设定一个唯一的整数|比如Q?/p>

  删除A---0

  修改A---1

  dA---2

  删除B---3

  修改B---4

  dB---5

  。。?/p>

  理论上可以有N个操作,q取决于你用于储存用h限值的数据cd了?/p>

  q样Q如果用h权限Q添加A---2;删除B---3;修改B---4

  那用L权限?purview =2^2+2^3+2^4=28Q也是2的权的和?/p>

  化成二进制可以表CZؓ11100

  如果要验证用h否有删除B的权限,可以通过位与q算来实现?/p>

  在Java里,位与q算q算W号?amp;

  xQint value = purview &((int)Math.pow(2,3));

  你会发现Q当用户有操作权限时Q运出来的l果都会{于q个操作需要的权限?

  原理Q?/p>

  位与q算Q顾名思义是对位q行与运:

  以上面的式子ZQpurview & 2^3 也就是 28&8

  它们化成二q制?/p>

  11100

  & 01000

  -------------------

  01000 == 8(十进? == 2^3

  同理Q如果要验证是否有删除A---0的权?/p>

  可以用:purview &((int)Math.pow(2,0));

  卻I

  11100

  & 00001

  ------------------------

  00000 == 0(十进?  != 2^0

  q种法的一个优Ҏ速度快。可以同时处理N个权限,讄NU角?

  如果想验证是否同时有删除A---0和删除B---3的权?/p>

  可以用purview&(2^0+2^3)==(2^0+2^3)?true:false;

  讄多角色用戗根据权限值判断用L角色。。?/p>

  下面提供一个java的单操作权限判断的代码:

  //userPurview是用户具有的L?br /> //optPurview是一个操作要求的权限Z个整?没有l过权的!)

public static boolean checkPower(int userPurview, int optPurview){
int purviewValue = (int)Math.pow(2, optPurview);
return (userPurview & purviewValue) == purviewValue;
}

  当然Q多权限的验证只要扩展一下就可以了?/p>

  几点注意事项Q首先,一个系l可能有很多的操作,因此Q请建立数据字典Q以便查阅,修改时用。其ơ,如果用数据库储存用户权限Q请注意数值的 有效范围。操作权限D用唯一的整?Java的intcd最多可以储?1个权限和.如果过Q可以选择其它数据cdQ而且不同模块Q用多个权? 变量.

 



凭栏观v 2008-02-25 09:20 发表评论
]]>
java基础Qbyte与inthttp://www.aygfsteel.com/cherishchen/archive/2007/07/31/133588.html凭栏观v凭栏观vTue, 31 Jul 2007 07:54:00 GMThttp://www.aygfsteel.com/cherishchen/archive/2007/07/31/133588.htmlhttp://www.aygfsteel.com/cherishchen/comments/133588.htmlhttp://www.aygfsteel.com/cherishchen/archive/2007/07/31/133588.html#Feedback0http://www.aygfsteel.com/cherishchen/comments/commentRss/133588.htmlhttp://www.aygfsteel.com/cherishchen/services/trackbacks/133588.htmlbyte与int的区别:

  • byte uses 1 byte while int uses 4 bytes.
  • integer literals like "45" are of int not byte.If you want a literal to be a byte, you have to cast it: "(byte)45".
  • When values are promoted as part of an expression or as parameters to a method call, they may be promoted to int, but never to byte.
  • Many parts of the Java language used int, but none of them use byte. For example, the length of an array is an int.

bytecd的用场合:

׃不同的机器对?strong>多字节数?int 是采用4个byte保存数据Q?/strong>的存储方式不?可能?低字节向高字节存?也可能是从高字节向低字节存储,q样,?分析|络协议或文件格?/strong>,Z解决不同机器上的字节存储序问题,用bytecd来表C数据是合适的?strong>而通常情况?׃其表C的数据范围很小,Ҏ造成溢出,应避免用?/strong>


/**
     * Convert  an int to a byte array
     *
     * @param value int
     * @return byte[]
     */
public static byte[] intToByteArray(int value) {
        byte[] b = new byte[4];

     // 使用4个byte表示int
        for (int i = 0; i < 4; i++) {
            int offset = (b.length - 1 - i) * 8;  // 偏移?br>            b[i] = (byte) ((value >> offset) & 0xFF); //每次?bit
        }
        return b;
    }


    /**
     * Convert the byte array to an int starting from the given offset.
     *
     * @param b The byte array
     * @param offset The array offset,如果byte数组长度是4Q则该gؓ0
     * @return The integer
     */  

public static int byteArrayToInt(byte[] b, int offset) {
        int value = 0;
        for (int i = 0; i < b.length; i++) {
            int shift = (b.length - 1 - i) * 8;
            value += (b[i + offset] & 0xFF) << shift;
        }
        return value;
    }

 

public static void main(String[] args) {
        byte[] bb=intToByteArray(255);
        for(int i=0;i<bb.length;i++){
            System.out.println(bb[i]);
        }       
    }

输出l果Q?/p>

0
0
0
-1

q是补码的Ş式(10000001Q,取反?可以得到源码Q?1111111Q?

凭栏观v 2007-07-31 15:54 发表评论
]]>
判断resultset是否含有记录http://www.aygfsteel.com/cherishchen/archive/2007/07/30/133368.html凭栏观v凭栏观vMon, 30 Jul 2007 08:42:00 GMThttp://www.aygfsteel.com/cherishchen/archive/2007/07/30/133368.htmlhttp://www.aygfsteel.com/cherishchen/comments/133368.htmlhttp://www.aygfsteel.com/cherishchen/archive/2007/07/30/133368.html#Feedback0http://www.aygfsteel.com/cherishchen/comments/commentRss/133368.htmlhttp://www.aygfsteel.com/cherishchen/services/trackbacks/133368.htmlboolean hasRows = false;
while (rs.next()){
  hasRows  = true;
  //Do your stuff
}
if (!hasRows ){
  //Empty result set
}
//You dont have to test for null result set



凭栏观v 2007-07-30 16:42 发表评论
]]>
java的数据类型(备用Q?/title><link>http://www.aygfsteel.com/cherishchen/archive/2007/07/27/132720.html</link><dc:creator>凭栏观v</dc:creator><author>凭栏观v</author><pubDate>Fri, 27 Jul 2007 03:11:00 GMT</pubDate><guid>http://www.aygfsteel.com/cherishchen/archive/2007/07/27/132720.html</guid><wfw:comment>http://www.aygfsteel.com/cherishchen/comments/132720.html</wfw:comment><comments>http://www.aygfsteel.com/cherishchen/archive/2007/07/27/132720.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/cherishchen/comments/commentRss/132720.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/cherishchen/services/trackbacks/132720.html</trackback:ping><description><![CDATA[  l合了前D|间看unicode的知识补补基<br><br> <ul> <li><strong>byte</strong>: The <code>byte</code> data type is an 8-bit signed two's complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive). The <code>byte</code> data type can be useful for saving memory in large <a >arrays</a>, where the memory savings actually matters. They can also be used in place of <code>int</code> where their limits help to clarify your code; the fact that a variable's range is limited can serve as a form of documentation. </li> <li><strong>short</strong>: The <code>short</code> data type is a 16-bit signed two's complement integer. It has a minimum value of -32,768 and a maximum value of 32,767 (inclusive). As with <code>byte</code>, the same guidelines apply: you can use a <code>short</code> to save memory in large arrays, in situations where the memory savings actually matters. </li> <li><strong>int</strong>: The <code>int</code> data type is a 32-bit signed two's complement integer. It has a minimum value of -2,147,483,648 and a maximum value of 2,147,483,647 (inclusive). For integral values, this data type is generally the default choice unless there is a reason (like the above) to choose something else. This data type will most likely be large enough for the numbers your program will use, but if you need a wider range of values, use <code>long</code> instead. </li> <li><strong>long</strong>: The <code>long</code> data type is a 64-bit signed two's complement integer. It has a minimum value of -9,223,372,036,854,775,808 and a maximum value of 9,223,372,036,854,775,807 (inclusive). Use this data type when you need a range of values wider than those provided by <code>int</code>. </li> <li><strong>float</strong>: The <code>float</code> data type is a single-precision 32-bit IEEE 754 floating point. Its range of values is beyond the scope of this discussion, but is specified in section <a >4.2.3</a> of the Java Language Specification. As with the recommendations for <code>byte</code> and <code>short</code>, use a <code>float</code> (instead of <code>double</code>) if you need to save memory in large arrays of floating point numbers. This data type should never be used for precise values, such as currency. For that, you will need to use the <a >java.math.BigDecimal</a> class instead. <a >Numbers and Strings</a> covers <code>BigDecimal</code> and other useful classes provided by the Java platform. </li> <li><strong>double</strong>: The <code>double</code> data type is a double-precision 64-bit IEEE 754 floating point. Its range of values is beyond the scope of this discussion, but is specified in section <a >4.2.3</a> of the Java Language Specification. For decimal values, this data type is generally the default choice. As mentioned above, this data type should never be used for precise values, such as currency. </li> <li><strong>boolean</strong>: The <code>boolean</code> data type has only two possible values: <code>true</code> and <code>false</code>. Use this data type for simple flags that track true/false conditions. This data type represents one bit of information, but its "size" isn't something that's precisely defined. </li> <li><strong>char</strong>: The <code>char</code> data type is a single 16-bit Unicode character. It has a minimum value of <code>'\u0000'</code> (or 0) and a maximum value of <code>'\uffff'</code> (or 65,535 inclusive). </li> </ul> <p> </p> <table unselectable="on" border="0" cellpadding="2" cellspacing="0" width="828"> <tbody> <tr> <td valign="top" width="173"> <p><strong>cd名称</strong></p> </td> <td valign="top" width="177"><strong>cd定义</strong></td> <td valign="top" width="474"><strong>cd取?/strong></td> </tr> <tr> <td valign="top" width="173"><em>boolean</em></td> <td valign="top" width="177">布尔?/td> <td valign="top" width="473"><em>true</em>, <em>false</em></td> </tr> <tr> <td valign="top" width="173"><em>byte</em></td> <td valign="top" width="177">8?strong>有符h?/strong></td> <td valign="top" width="473">最?128Q最大?27</td> </tr> <tr> <td valign="top" width="173"><em>short</em></td> <td valign="top" width="177">16?strong>有符h?/strong></td> <td valign="top" width="472"> <p>最?32768Q?2<sup>15</sup>Q,最大?2767Q?<sup>15</sup>-1Q?/p> </td> </tr> <tr> <td valign="top" width="173"><em>int</em></td> <td valign="top" width="177">32?strong>有符h?/strong></td> <td valign="top" width="472">最?2147483648Q?2<sup>31</sup>Q,最大?147483647Q?<sup>31</sup>-1Q?/td> </tr> <tr> <td valign="top" width="173"><em>long</em></td> <td valign="top" width="177">64?strong>有符h?/strong></td> <td valign="top" width="472"> <p>-2<sup>63</sup>~(2<sup>63</sup>-1)</p> </td> </tr> <tr> <td valign="top" width="173"><em>float</em></td> <td valign="top" width="177">32位QҎ</td> <td valign="top" width="472"> <p>1.4E-45~3.4028235E38</p> </td> </tr> <tr> <td valign="top" width="173"><em>double</em></td> <td valign="top" width="177">64位QҎ</td> <td valign="top" width="472">4.9E-324~1.7976931348623157E308</td> </tr> <tr> <td valign="top" width="173">char</td> <td valign="top" width="177">16位Unicode字符</td> <td valign="top" width="472"> </td> </tr> <tr> <td valign="top" width="173"> </td> <td valign="top" width="177"> </td> <td valign="top" width="472"> </td> </tr> </tbody> </table> <p> </p> <p> </p> <p> </p> <div id="wmqeeuq" class="ad_in_page"> <script type="text/javascript"><!-- google_ad_client = "pub-7843511305731432"; google_ad_width =" 468; google_ad_height" = 60; google_ad_format =" "468x60_as"; google_ad_type" = "text_image"; //2007-07-22: test google_ad_channel =" "2043099642"; google_color_border" = "ffffff"; google_color_bg =" "ffffff"; google_color_link" = "ffffff"; google_color_text =" "000000"; google_color_url" = "000033"; //--> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script> </div><img src ="http://www.aygfsteel.com/cherishchen/aggbug/132720.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/cherishchen/" target="_blank">凭栏观v</a> 2007-07-27 11:11 <a href="http://www.aygfsteel.com/cherishchen/archive/2007/07/27/132720.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java语言中的bit UM操作http://www.aygfsteel.com/cherishchen/archive/2007/07/27/132717.html凭栏观v凭栏观vFri, 27 Jul 2007 03:08:00 GMThttp://www.aygfsteel.com/cherishchen/archive/2007/07/27/132717.htmlhttp://www.aygfsteel.com/cherishchen/comments/132717.htmlhttp://www.aygfsteel.com/cherishchen/archive/2007/07/27/132717.html#Feedback0http://www.aygfsteel.com/cherishchen/comments/commentRss/132717.htmlhttp://www.aygfsteel.com/cherishchen/services/trackbacks/132717.html
 

java 位操作符Q?/strong>

取反Q?/strong>~x
- flips each bit to the opposite value.

与操作:AND

x & y
- AND operation between the corresponding bits in x and y.

或操作:OR
x | y
- OR operation between the corresponding bits in x and y.

异或操作QXOR
x ^ y
- XOR operation between the corresponding bits in x and y.

左移操作QShift left
x << y
- shifts x to the left by y bits. The high order bits are lost while zeros fill the right bits.

x左移y位,Udq程中,高位会丢?

有符h右移操作QShift Right - Signed
x >> y
- shifts x to the right by y bits. The low order bits are lost while the sign bit value (0 for positive numbers, 1 for negative) fills in the left bits.

无符h右移QShift Right - Unsigned
x >>> y
- shifts x to the right by y bits. The low order bits are lost while zeros fill in the left bits regardless of the sign.

例子Q?/strong>

下面的例子显C如何将一个int数组通过UM操作压羃C个int内保存,其原理是在java语言中,intcd使用4 bytes来保存,因此对于需要压~的int数组Q其中的每一个int值的大小不能过255Q??ơ方-1Q,因此q只是一个实例:

  int [] aRGB = {0x56, 0x78, 0x9A, 0xBC};   // 是用16q制保存?U颜色?br>  int color_val = aRGB[3];   
  color_val = color_val | (aRGB[2] << 8);  // Z压羃Q需要放|到color_val值的W二个字节位|上Q将aRGB[2] 左移到第二个byteQ同时与color_valq行或操作,下面同理
  color_val = color_val | (aRGB[1] << 16);  
  color_val = color_val | (aRBG[0] << 24);

操作完的l果?6 78 9A BC

如果要从colorVal q原为int数组Q或者得到数l中的某个|只需要对colorVal q行相应的右UL作即可:

  int alpha_val = (colorVal >>> 24) & 0xFF;
  int red_val   = (colorVal >>> 16) & 0xFF;
  int green_val = (colorVal >>>  8) & 0xFF;
  int blue_val  =  colorVal & 0xFF;

参考资料:

Bits in Java



凭栏观v 2007-07-27 11:08 发表评论
]]>
JPA --Java EE 5.0 ORM 规范Q{Q?/title><link>http://www.aygfsteel.com/cherishchen/archive/2007/07/21/131658.html</link><dc:creator>凭栏观v</dc:creator><author>凭栏观v</author><pubDate>Sat, 21 Jul 2007 12:50:00 GMT</pubDate><guid>http://www.aygfsteel.com/cherishchen/archive/2007/07/21/131658.html</guid><wfw:comment>http://www.aygfsteel.com/cherishchen/comments/131658.html</wfw:comment><comments>http://www.aygfsteel.com/cherishchen/archive/2007/07/21/131658.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.aygfsteel.com/cherishchen/comments/commentRss/131658.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/cherishchen/services/trackbacks/131658.html</trackback:ping><description><![CDATA[<p>作? 它山 出处:<a >IT168</a></p> <p><a title="http://tech.it168.com/j/n/2007-03-05/200703051354348.shtml" >http://tech.it168.com/j/n/2007-03-05/200703051354348.shtml</a></p> <p>PA作ؓ一对象持久化的标准,不但可以获得Java EE应用服务器的支持Q还可以直接在Java SE中用?/p> <p>介绍得很清楚的文?/p> <p> </p> <p><strong>JPA概述</strong> <p>JPA(Java Persistence API)作ؓJava EE 5.0q_标准的ORM规范Q将得到所有Java EE服务器的支持。Sunq次吸取了之前EJB规范惨痛p|的经历,在充分吸收现有ORM框架的基上,得到了一个易于用、׾~性强的ORM规范。从目前的开发社区的反应上看QJPA受到了极大的支持和赞扬,JPA作ؓORM领域标准化整合者的目标应该不难实现?nbsp; <p>JPA通过JDK 5.0注解或XML描述对象Q关p表的映关p,q将q行期的实体对象持久化到数据库中Q图 1很好地描qCJPA的结构: <p><img height="305" alt="" src="http://developer.51cto.com/files/uploadimg/20070305/1547200.JPG" width="450"> <p>Sun引入新的JPA ORM规范Z两个原因Q其一Q简化现有Java EE和Java SE应用的对象持久化的开发工作;其二QSun希望整合对ORM技术,实现天下归一?nbsp; <p>JPA由EJB 3.0软g专家l开发,作ؓJSR-220实现的一部分。但它不囿于EJB 3.0Q你可以在Web应用、甚x面应用中使用。JPA的宗旨是为POJO提供持久化标准规范,由此可见Q经q这几年的实跉|索,能够q容器独立q行Q方便开发和试的理念已l深入h心了。目前Hibernate 3.2、TopLink 10.1.3以及OpenJpa都提供了JPA的实现? <p>JPA的M思想和现有Hibernate、TopLinkQJDO{ORM框架大体一致。ȝ来说QJPA包括以下3斚w的技术:  <ul> <li>ORM映射元数据,JPA支持XML和JDK 5.0注解两种元数据的形式Q元数据描述对象和表之间的映关p,框架据此实体对象持久化到数据库表中Q?nbsp; <li>JPA 的APIQ用来操作实体对象,执行CRUD操作Q框架在后台替我们完成所有的事情Q开发者从J琐的JDBC和SQL代码中解脱出来?nbsp; <li>查询语言Q这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据Q避免程序的SQL语句紧密耦合?nbsp;</li></ul><img src ="http://www.aygfsteel.com/cherishchen/aggbug/131658.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/cherishchen/" target="_blank">凭栏观v</a> 2007-07-21 20:50 <a href="http://www.aygfsteel.com/cherishchen/archive/2007/07/21/131658.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个简单blog备䆾工具的实?/title><link>http://www.aygfsteel.com/cherishchen/archive/2007/07/16/130508.html</link><dc:creator>凭栏观v</dc:creator><author>凭栏观v</author><pubDate>Mon, 16 Jul 2007 03:22:00 GMT</pubDate><guid>http://www.aygfsteel.com/cherishchen/archive/2007/07/16/130508.html</guid><wfw:comment>http://www.aygfsteel.com/cherishchen/comments/130508.html</wfw:comment><comments>http://www.aygfsteel.com/cherishchen/archive/2007/07/16/130508.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.aygfsteel.com/cherishchen/comments/commentRss/130508.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/cherishchen/services/trackbacks/130508.html</trackback:ping><description><![CDATA[<p> </p> <p>Z备䆾blogQ简单写了一个适用于blogjava{metaWeblog的blog备䆾工具Q功能:</p> <p>Q?Q备份post的正文到本地</p> <p>Q?Q备份正文中的图片、css文g到本?/p> <p>Q?Q基于以上两的步骤,修改相关的链接,实现本地脱机览</p> <p>惛_了但是未实现的功能:</p> <p>Q?Q评论无法保?/p> <p>Q?Q合适的话可以考虑以Eclipes RCP形式包装</p> <p> </p> <div id="wmqeeuq" class="ad_in_page"> <script type="text/javascript"><!-- google_ad_client = "pub-7843511305731432"; google_ad_width = 468; google_ad_height = 60; google_ad_format = "468x60_as"; google_ad_type = "text_image"; //2007-07-22: test google_ad_channel = "2043099642"; google_color_border = "FFFFFF"; google_color_bg = "FFFFFF"; google_color_link = "FFFFFF"; google_color_text = "000000"; google_color_url = "000033"; //--> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script> </div> <h2>一、实现原?/h2> <p>Q?Q获取post的方法:使用MetaWeblog提供的API接口</p> <p>metaWeblog.getRecentPosts (blogid, username, password, numberOfPosts) returns array of structs,</p> <p>Each struct represents a recent weblog post, containing the same information that a call to metaWeblog.getPost would return. </p> <p>If numberOfPosts is 1, you get the most recent post. If it's 2 you also get the second most recent post, as the second array element. If numberOfPosts is greater than the number of posts in the weblog you get all the posts in the weblog. </p> <p> </p> <p>(2) 使用正则表达式分析获取下来的postQ解析出post中包含的css和图片文件的地址Q执行两步操?/p> <ul> <li>Ҏ地址Q抓取图片保存到本地 <li>修改post中的地址为本C存地址 </li></ul> <p>(3) 使用xml-rpc来简化远E调用过E的~程</p> <p> </p> <h2>二、主要的代码</h2> <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%; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff">public</span><span style="color: #000000"> ArrayList</span><span style="color: #000000"><</span><span style="color: #000000">SimplePost</span><span style="color: #000000">></span><span style="color: #000000"> getAllPosts(String blogID, String name,String password, </span><span style="color: #0000ff">int</span><span style="color: #000000"> num) </span><span style="color: #0000ff">throws</span><span style="color: #000000"> XmlRpcException {<br>        ArrayList</span><span style="color: #000000"><</span><span style="color: #000000">SimplePost</span><span style="color: #000000">></span><span style="color: #000000"> posts </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> ArrayList</span><span style="color: #000000"><</span><span style="color: #000000">SimplePost</span><span style="color: #000000">></span><span style="color: #000000">();<br>        Object[] params </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> Object[] { blogID, name, password,</span><span style="color: #0000ff">new</span><span style="color: #000000"> Integer(num) };<br>        Object[] result </span><span style="color: #000000">=</span><span style="color: #000000"> (Object[]) client.execute(</span><span style="color: #000000">"</span><span style="color: #000000">metaWeblog.getRecentPosts</span><span style="color: #000000">"</span><span style="color: #000000">, params);<br><br>        </span><span style="color: #0000ff">for</span><span style="color: #000000"> (</span><span style="color: #0000ff">int</span><span style="color: #000000"> i </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">; i </span><span style="color: #000000"><</span><span style="color: #000000"> result.length; i</span><span style="color: #000000">++</span><span style="color: #000000">) {<br>            Map map </span><span style="color: #000000">=</span><span style="color: #000000"> (Map) result[i];<br>            String postUrl </span><span style="color: #000000">=</span><span style="color: #000000"> (String) map.get(</span><span style="color: #000000">"</span><span style="color: #000000">link</span><span style="color: #000000">"</span><span style="color: #000000">);<br>            String title </span><span style="color: #000000">=</span><span style="color: #000000"> (String) map.get(</span><span style="color: #000000">"</span><span style="color: #000000">title</span><span style="color: #000000">"</span><span style="color: #000000">);<br>            String postId </span><span style="color: #000000">=</span><span style="color: #000000"> (String) map.get(</span><span style="color: #000000">"</span><span style="color: #000000">postid</span><span style="color: #000000">"</span><span style="color: #000000">);<br><br>                        </span><span style="color: #008000">//</span><span style="color: #008000"> post的内?/span><span style="color: #008000"><br></span><span style="color: #000000">            String description </span><span style="color: #000000">=</span><span style="color: #000000"> (String) map.get(</span><span style="color: #000000">"</span><span style="color: #000000">description</span><span style="color: #000000">"</span><span style="color: #000000">);<br>            <br>            Map</span><span style="color: #000000"><</span><span style="color: #000000">String, String</span><span style="color: #000000">></span><span style="color: #000000"> images </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> HashMap</span><span style="color: #000000"><</span><span style="color: #000000">String, String</span><span style="color: #000000">></span><span style="color: #000000">();<br>            images </span><span style="color: #000000">=</span><span style="color: #000000"> getImagesURL(description);<br>                    <br>            String newDes </span><span style="color: #000000">=</span><span style="color: #000000"> handleImagesURL(description,postId);            <br>            String descriptioFileName </span><span style="color: #000000">=</span><span style="color: #000000"> savePostContent(savePath, title,postId, newDes, css);<br><br>            SimplePost post </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> SimplePost(postUrl, title, postId,descriptioFileName);<br>            </span><span style="color: #008000">//</span><span style="color: #008000">从postContent获取囑փ的地址和名Uͼ以便获取囄q保?/span><span style="color: #008000"><br></span><span style="color: #000000">            post.setImages(images);<br>            posts.add(post);<br>            log.debug(</span><span style="color: #000000">"</span><span style="color: #000000">postID: </span><span style="color: #000000">"</span><span style="color: #000000"> </span><span style="color: #000000">+</span><span style="color: #000000"> postId </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">"</span><span style="color: #000000">postTitle :</span><span style="color: #000000">"</span><span style="color: #000000"> </span><span style="color: #000000">+</span><span style="color: #000000"> title);<br>        }<br>        </span><span style="color: #0000ff">return</span><span style="color: #000000"> posts;<br>    }</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%; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">static</span><span style="color: #000000"> Map</span><span style="color: #000000"><</span><span style="color: #000000">String, String</span><span style="color: #000000">></span><span style="color: #000000"> getImagesURL(String description) {<br><br>       </span><span style="color: #008000"></span><span style="color: #000000">  Map</span><span style="color: #000000"><</span><span style="color: #000000">String, String</span><span style="color: #000000">></span><span style="color: #000000"> map </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> HashMap</span><span style="color: #000000"><</span><span style="color: #000000">String, String</span><span style="color: #000000">></span><span style="color: #000000">();<br>        </span><span style="color: #008000">//</span><span style="color: #008000"> img 的正则表辑ּ<br>      </span><span style="color: #008000"></span><span style="color: #000000">  String imgPattern </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">"</span><span style="color: #000000"><\\s*img\\s+([^>]+)\\s*></span><span style="color: #000000">"</span><span style="color: #000000">;<br>        Pattern p </span><span style="color: #000000">=</span><span style="color: #000000"> Pattern.compile(imgPattern, Pattern.CASE_INSENSITIVE);<br>        Matcher matcher </span><span style="color: #000000">=</span><span style="color: #000000"> p.matcher(description);<br><br>        </span><span style="color: #008000">//</span><span style="color: #008000"> img src元素的正则表辑ּ</span><span style="color: #008000"><br></span><span style="color: #000000">        String srcPattern </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">"</span><span style="color: #000000">\\s*src\\s*=\\s*\</span><span style="color: #000000">"</span><span style="color: #000000">([</span><span style="color: #000000">^</span><span style="color: #000000">\</span><span style="color: #000000">"</span><span style="color: #000000">]+)\\s*\</span><span style="color: #000000">""</span><span style="color: #000000">;</span><span style="color: #000000"><br></span><span style="color: #000000">       </span><span style="color: #008000"></span><span style="color: #000000">  Pattern p2 </span><span style="color: #000000">=</span><span style="color: #000000"> Pattern.compile(srcPattern, Pattern.CASE_INSENSITIVE);<br><br>        </span><span style="color: #0000ff">while</span><span style="color: #000000"> (matcher.find()) {<br>            Matcher matcher2 </span><span style="color: #000000">=</span><span style="color: #000000"> p2.matcher(matcher.group());<br>            </span><span style="color: #008000">//</span><span style="color: #008000"> 一定要find(),q是实际的匹配动?/span><span style="color: #008000"><br></span><span style="color: #000000">            </span><span style="color: #0000ff">if</span><span style="color: #000000"> (matcher2.find()) {<br>                String src </span><span style="color: #000000">=</span><span style="color: #000000"> matcher2.group();<br>                log.info(src);<br>                </span><span style="color: #0000ff">int</span><span style="color: #000000"> i2 </span><span style="color: #000000">=</span><span style="color: #000000"> src.lastIndexOf(</span><span style="color: #000000">'</span><span style="color: #000000">/</span><span style="color: #000000">'</span><span style="color: #000000">);<br>                </span><span style="color: #0000ff">int</span><span style="color: #000000"> i1 </span><span style="color: #000000">=</span><span style="color: #000000"> src.indexOf(</span><span style="color: #000000">"</span><span style="color: #000000">http</span><span style="color: #000000">"</span><span style="color: #000000">);<br>                </span><span style="color: #0000ff">if</span><span style="color: #000000"> (i1 </span><span style="color: #000000">!=</span><span style="color: #000000"> </span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">) {<br>                    map.put(src.substring(i2 </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">, src.length() </span><span style="color: #000000">-</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">), src<br>                            .substring(i1, src.length() </span><span style="color: #000000">-</span><span style="color: #000000"> </span><span style="color: #000000">1</span><span style="color: #000000">));<br>                }<br>            }<br>        }<br>        log.debug(</span><span style="color: #000000">"</span><span style="color: #000000">囄Q?/span><span style="color: #000000">"</span><span style="color: #000000"> </span><span style="color: #000000">+</span><span style="color: #000000"> map);<br>        </span><span style="color: #0000ff">return</span><span style="color: #000000"> map;<br>    }</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%; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008000">/**</span><span style="color: #008000"><br>     * 替换description的图片链接ؓ本地的相寚w接,l构为blogFiles/images/postid/<br>     * <br>     * </span><span style="color: #808080">@param</span><span style="color: #008000"> description<br>     * </span><span style="color: #808080">@param</span><span style="color: #008000"> userName<br>     * </span><span style="color: #808080">@param</span><span style="color: #008000"> postId<br>     * </span><span style="color: #808080">@return</span><span style="color: #008000"><br>     </span><span style="color: #008000">*/</span><span style="color: #000000"><br>    </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">static</span><span style="color: #000000"> String handleImagesURL(String description, String postId) {<br>        String tmp </span><span style="color: #000000">=</span><span style="color: #000000"> description;        <br>        String address</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">images/</span><span style="color: #000000">"</span><span style="color: #000000"> </span><span style="color: #000000">+</span><span style="color: #000000"> postId </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000000">"</span><span style="color: #000000">/</span><span style="color: #000000">"</span><span style="color: #000000">;<br>        <br>        String imgPattern </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">"</span><span style="color: #000000"><\\s*img\\s+([^>]+)\\s*></span><span style="color: #000000">"</span><span style="color: #000000">;<br>        Pattern p </span><span style="color: #000000">=</span><span style="color: #000000"> Pattern.compile(imgPattern, Pattern.CASE_INSENSITIVE);<br>        Matcher matcher </span><span style="color: #000000">=</span><span style="color: #000000"> p.matcher(tmp);<br><br>        </span><span style="color: #008000">//</span><span style="color: #008000"> img src元素的正则表辑ּ</span><span style="color: #008000"><br></span><span style="color: #000000">        String srcPattern </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">"</span><span style="color: #000000">\\s*src\\s*=\\s*\</span><span style="color: #000000">"</span><span style="color: #000000">([</span><span style="color: #000000">^</span><span style="color: #000000">\</span><span style="color: #000000">"</span><span style="color: #000000">]+)\\s*\</span><span style="color: #000000">""</span><span style="color: #000000">;</span><span style="color: #000000"><br></span><span style="color: #000000">        </span><span style="color: #008000">//</span><span style="color: #008000"> String srcPattern = "\\s*src\\s*=\\s*\'([^\']+)\\s*\'";</span><span style="color: #008000"><br></span><span style="color: #000000">        Pattern p2 </span><span style="color: #000000">=</span><span style="color: #000000"> Pattern.compile(srcPattern, Pattern.CASE_INSENSITIVE);<br>        </span><span style="color: #0000ff">while</span><span style="color: #000000"> (matcher.find()) {<br>            Matcher matcher2 </span><span style="color: #000000">=</span><span style="color: #000000"> p2.matcher(matcher.group());<br>            </span><span style="color: #008000">//</span><span style="color: #008000"> 一定要find(),q是实际的匹配动?/span><span style="color: #008000"><br></span><span style="color: #000000">            </span><span style="color: #0000ff">if</span><span style="color: #000000"> (matcher2.find()) {<br>                String src </span><span style="color: #000000">=</span><span style="color: #000000"> matcher2.group();<br>                log.info(src);                <br>                </span><span style="color: #0000ff">int</span><span style="color: #000000"> l2</span><span style="color: #000000">=</span><span style="color: #000000">src.lastIndexOf(</span><span style="color: #000000">'</span><span style="color: #000000">/</span><span style="color: #000000">'</span><span style="color: #000000">)</span><span style="color: #000000">+</span><span style="color: #000000">1</span><span style="color: #000000">;<br>                log.info(src.substring(l2,src.length()</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">));<br>                tmp</span><span style="color: #000000">=</span><span style="color: #000000">tmp.replace(src,</span><span style="color: #000000">"</span><span style="color: #000000">  src=\</span><span style="color: #000000">""</span><span style="color: #000000">+address+src.substring(l2,src.length()-1)+</span><span style="color: #000000">"</span><span style="color: #000000">\</span><span style="color: #000000">""</span><span style="color: #000000">);                <br>            }<br>        }        <br>        </span><span style="color: #0000ff">return</span><span style="color: #000000"> tmp;<br>    }</span></div><img src ="http://www.aygfsteel.com/cherishchen/aggbug/130508.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/cherishchen/" target="_blank">凭栏观v</a> 2007-07-16 11:22 <a href="http://www.aygfsteel.com/cherishchen/archive/2007/07/16/130508.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正则表达式的ȝhttp://www.aygfsteel.com/cherishchen/archive/2007/07/12/129757.html凭栏观v凭栏观vThu, 12 Jul 2007 01:44:00 GMThttp://www.aygfsteel.com/cherishchen/archive/2007/07/12/129757.htmlhttp://www.aygfsteel.com/cherishchen/comments/129757.htmlhttp://www.aygfsteel.com/cherishchen/archive/2007/07/12/129757.html#Feedback2http://www.aygfsteel.com/cherishchen/comments/commentRss/129757.htmlhttp://www.aygfsteel.com/cherishchen/services/trackbacks/129757.html一、JDK提供的正则表辑ּ

Java's java.util.regex 包包括:PatterncRMatchercRMatchResult接口和PatternSyntaxException异常Q?/p>

  • Pattern 对象代表了编译了的正则表辑ּQA compiled representation of a regular expression.Q?
  • Matcher QAn engine that performs match operations on a character sequence by interpreting a Pattern.
  • MatchResult接口QThe result of a match operation.
  • PatternSyntaxException对象Q描q非法的regex patternsQUnchecked exception thrown to indicate a syntax error in a regular-expression pattern.

 同时q需要了解是CharSequenceQJDK 1.4定义的新的接口,它提供了String和StringBufferq两个类的字W序列的抽象

interface CharSequence {

charAt(int i);

length();

subSequence(int start, int end);

toString();

}

Z实现q个新的CharSequence接口QStringQStringBuffer以及CharBuffer都作了修改,很多的正则表辑ּ的操作都要拿CharSequence作参数?

 

Matchercȝ几个重要的方法:

  • boolean matches()QPattern匚w整个字符?
  • boolean lookingAt()QPattern匚w字符串的开?
  • boolean find()Q发现CharSequence里的Q与pattern相匹配的多个字符序列
    boolean find(int start)Q告诉方法从参数start位置开始查?/li>

group的概?/h2>

Group是指里用括号括v来的Q能被后面的表达式调用的正则表达式?/p>

Group 0 表示整个表达式,group 1表示W一个被括v来的groupQ以此类推。所以;

A(B(C))D

里面有三个groupQgroup 0是ABCDQ?group 1是BCQgroup 2是C?

你可以用下述MatcherҎ来用groupQ?

  • public int groupCount( )q回matcher对象中的group的数目。不包括group0?
  • public String group( ) q回上次匚w操作(比方说find( ))的group 0(整个匚w)
  • public String group(int i)q回上次匚w操作的某个group。如果匹配成功,但是没能扑ֈgroupQ则q回null?
  • public int start(int group)q回上次匚w所扑ֈ的group的开始位|?
  • public int end(int group)q回上次匚w所扑ֈ的group的结束位|,最后一个字W的下标加一?
  • split( ) 是指以正则表达式ؓ界,字W串分割成String数组,如果带有limit参数Qsplit( )会限定分割的ơ数?
  • replaceFirst(String replacement)字W串里,W一个与模式相匹配的子串替换成replacement?
  • replaceAll(String replacement)Q将输入字符串里所有与模式相匹配的子串全部替换成replacement?
  • appendReplacement(StringBuffer sbuf, String replacement)对sbufq行逐次替换Q而不是像replaceFirst( )或replaceAll( )那样Q只替换W一个或全部子串。这是个非常重要的方法,因ؓreplacement(replaceFirst( )和replaceAll( )只允许用固定的字W串来充当replacement)。有了这个方法,你就可以~程区分groupQ从而实现更强大的替换功能?
  • 调用完appendReplacement( )之后Qؓ了把剩余的字W串拯回去Q必调用appendTail(StringBuffer sbuf, String replacement)?

 

使用group可以做到逐步~小匚w的范_直至_匚w的目的?

start( )和end( )Q如果匹配成功,start( )会返回此ơ匹配的开始位|,end( )会返回此ơ匹配的l束位置Q即最后一个字W的下标加一。如果之前的匚w不成?或者没匚w)Q那么无论是调用start( )q是end( )Q都会引发一个IllegalStateException?/p>

 

二?大用方法:

查询

String str="abc efg ABC";

 

String regEx="a|f"; //表示a或f

 

Pattern p=Pattern.compile(regEx);

 

Matcher m=p.matcher(str);

 

boolean rs=m.find();

 

如果str中有regExQ那么rs为trueQ否则ؓflase。如果想在查找时忽略大小写,则可以写成Pattern p=Pattern.compile(regEx,Pattern.CASE_INSENSITIVE);

 

 

提取

String regEx=".+\\\\(.+)$";

 

String str="c:\\dir1\\dir2\\name.txt";

 

Pattern p=Pattern.compile(regEx);

 

Matcher m=p.matcher(str);

 

boolean rs=m.find();

 

for(int i=1;i<=m.groupCount();i++){

 

System.out.println(m.group(i));

 

}

 

以上的执行结果ؓname.txtQ提取的字符串储存在m.group(i)中,其中i最大gؓm.groupCount();

 

 

分割

 

String regEx="::";

 

Pattern p=Pattern.compile(regEx);

 

String[] r=p.split("xd::abc::cde");

 

执行后,r是{"xd","abc","cde"}Q其实分割时q有跟简单的ҎQ?

 

String str="xd::abc::cde";

 

String[] r=str.split("::");

 

 

替换或者删?/strong>

String regEx="a+"; //表示一个或多个a

 

Pattern p=Pattern.compile(regEx);

 

Matcher m=p.matcher("aaabbced a ccdeaa");

 

String s=m.replaceAll("A");

 

l果?Abbced A ccdeA"

 

如果写成IZQ既可达到删除的功能Q比如:

 

String s=m.replaceAll("");

 

l果?bbced ccde"

 

 

三、一个实际的例子

下面的函数是一个实际应用的例子Q需求是需要将抓取的网中?lt;img src=''http://aa.bb.cc.com/images/**.jpg"> 中的地址Q保存到一个地址列表中(以供抓取囄使用Q,q将l对地址替换成本地的相对地址Q即<img src="images/**.jpg">?/p>

public static Map<String, String> getImagesURL(String description) {

      Map<String, String> map = new HashMap<String, String>();
        // img 的正则表辑ּ:匚w<img>标签       
        String imgPattern = "<\\s*img\\s+([^>]+)\\s*>";
        Pattern pattern1 = Pattern.compile(imgPattern, Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern1.matcher(description);

        // img src元素的正则表辑ּQ匹配img标签内的src属?br />         String srcPattern = "\\s*src\\s*=\\s*\"([^\"]+)\\s*\"";
        Pattern pattern2 = Pattern.compile(srcPattern, Pattern.CASE_INSENSITIVE);

        while (matcher.find()) {

           //group()q回W合表达式的内容
            Matcher matcher2 = pattern2 .matcher(matcher.group());
            // 一定要find(),q是实际的匹配动?br />             if (matcher2.find()) {
                String src = matcher2.group();
                log.info(src);
                int i2 = src.lastIndexOf('/');
                int i1 = src.indexOf("http");
                if (i1 != -1) {
                    map.put(src.substring(i2 + 1, src.length() - 1), src
                            .substring(i1, src.length() - 1));
                }
            }
        }
        log.debug("囄Q? + map);
        return map;
    }

 

整体思\是先匚w到img标签Q然后匹配src属性,q修改src的属?/p>

"<\\s*img\\s+([^>]+)\\s*>" 的解释:

\\s* :0 或多个空?nbsp;  \\s+: 臛_一个空?/p>

([^>]+)Q指的是?gt;的所有的字符Q至一?/p>

 

常用的正则表辑ּQ参考jdk的regex文档Q?/h1>

字符集类

.                            表示L一个字W?

[abc]                     表示字符aQbQc中的L一?与a|b|c相同)

[^abc]                   除aQbQc之外的Q意一个字W?否定)

[a-zA-Z]                从a到z或A到Z当中的Q意一个字W?范围)

[abc[hij]]              a,b,c,h,i,j中的L一个字W?与a|b|c|h|i|j相同)(q)

[a-z&&[hij]]          h,i,j中的一?交集)

\s                          I格字符(I格? tab, 换行, 换页, 回R)

\S                         非空格字W?[^\s])

\d                         一个数字,也就是[0-9]

\D                         一个非数字的字W,也就是[^0-9]

\w                        一个单词字W?word character)Q即[a-zA-Z_0-9]

\W                       一个非单词的字W,[^\w]

字符c:

B                         字符B

\xhh                    16q制?xhh所表示的字W?

\uhhhh                16q制?xhhhh所表示的Unicode字符

\t                         Tab

\n                        换行W?

\r                         回RW?

\f                        换页W?

\e                       Escape

逻辑q算W?/strong>

XY                      X 后面跟着 Y

X|Y                    X或Y

(X)                     一?要匹配的l?capturing group)". 以后可以用\i来表C第i个被匚w的组?

边界匚wW?/strong>

^                      一行的开?

$                      一行的l尾

\b                    一个单词的边界

\B                    一个非单词的边?

\G                   前一个匹配的l束

 

数量表示W?/strong>

"数量表示W?quantifier)"的作用是定义模式应该匚w多少个字W?

  • Greedy(贪婪?Q?除非另有表示Q否则数量表C符都是greedy的。Greedy的表辑ּ会一直匹配下去,直到匚w不下Mؓ止?u>(如果你发现表辑ּ匚w的结果与预期的不W?Q很有可能是因ؓQ你以ؓ表达式会只匹配前面几个字W,而实际上它是greedy的,因此会一直匹配下厅R?
  • Reluctant(勉强?Q?用问可C,它会匚w最的字符。也UCؓlazy, minimal matching, non-greedy, 或ungreedy?
  • Possessive(占有?Q?目前只有Java支持(其它语言都不支持)。它更加先进Q所以你可能q不太会用。用正则表达式匹配字W串的时候会产生很多中间状态,(一般的匚w引擎会保存这U中间状态,)q样匚wp|的时候就能原路返回了。占有型的表辑ּ不保存这U中间状态,因此也就不会回头重来了。它能防止正则表辑ּ的失控,同时也能提高q行的效率?

 

Greedy                    Reluctant                           Possessive                      匚w

 

X?                            X??                                      X?+                                  匚w一个或零个X

X*                            X*?                                      X*+                                  匚w零或多个X

X+                           X+?                                      X++                                 匚w一个或多个X

X{n}                        X{n}?                                   X{n}+                               匚w正好n个X

X{n,}                       X{n,}?                                 X{n,}+                              匚w臛_n个X

X{n,m}                   X{n,m}?                                X{n,m}+                           匚w臛_n个,臛_m个X

 

 

参考资?/h2>

要想q一步学习正则表辑ּQ徏议看Mastering Regular Expression, 2nd EditionQ作者Jeffrey E. F. Friedl (O’Reilly, 2002)?

"Regular Expressions and the Java Programming Language," Dana Nourie and Mike McCloskey (Sun Microsystems, August 2002) presents a brief overview of java.util.regex, including five illustrative regex-based applications:
http://developer.java.sun.com/developer/technicalArticles/releases/1.4regex/

http://www.aygfsteel.com/beike/archive/2006/04/28/43832.html 

http://wcjok.bokee.com/4293762.html



凭栏观v 2007-07-12 09:44 发表评论
]]>用HttpClient来模拟浏览器GET POST(收藏)http://www.aygfsteel.com/cherishchen/archive/2007/07/10/129369.html凭栏观v凭栏观vTue, 10 Jul 2007 08:05:00 GMThttp://www.aygfsteel.com/cherishchen/archive/2007/07/10/129369.htmlhttp://www.aygfsteel.com/cherishchen/comments/129369.htmlhttp://www.aygfsteel.com/cherishchen/archive/2007/07/10/129369.html#Feedback1http://www.aygfsteel.com/cherishchen/comments/commentRss/129369.htmlhttp://www.aygfsteel.com/cherishchen/services/trackbacks/129369.html用HttpClient来模拟浏览器GET POST

http://www.xd-tech.com.cn/blog/article.asp?id=34

作?jaddy0302 日期:2006-12-21

      一般的情况下我们都是用IE或者Navigator览器来讉K一个WEB服务器,用来览面查看信息或者提交一些数据等{。所讉K的这些页面有的仅仅是一些普通的面Q有的需要用L录后方可使用Q或者需要认证以及是一些通过加密方式传输Q例如HTTPS。目前我们用的览器处理这些情况都不会构成问题。不q你可能在某些时候需要通过E序来访问这L一些页面,比如从别人的|页中“偷”一些数据;利用某些站点提供的页面来完成某种功能Q例如说我们想知道某个手机号码的归属地而我们自己又没有q样的数据,因此只好借助其他公司已有的网站来完成q个功能Q这个时候我们需要向|页提交手机Lq从q回的页面中解析出我们想要的数据来。如果对方仅仅是一个很单的面Q那我们的程序会很简单,本文也就没有必要大张旗鼓的在q里费口舌。但是考虑C些服务授权的问题Q很多公司提供的面往往q不是可以通过一个简单的URL可以访问的Q而必ȝq注册然后登录后方可使用提供服务的页面,q个时候就涉及?COOKIE问题的处理。我们知道目前流行的***|术例如ASP、JSP无不是通过COOKIE来处理会话信息的。ؓ了我们的程序能使用别h所提供的服务页面,p求程序首先登录后再访问服务页面,q过E就需要自行处理cookieQ想惛_你用java.net.HttpURLConnection 来完成这些功能时是多么恐怖的事情啊!况且q仅仅是我们所说的固的WEB服务器中的一个很常见的“顽固”!再有如通过HTTP来上传文件呢Q不需要头|q些问题有了“它”就很容易解决了Q?

我们不可能列举所有可能的固Q我们会针对几种最常见的问题进行处理。当然了Q正如前面说到的Q如果我们自׃?java.net.HttpURLConnection来搞定这些问题是很恐怖的事情Q因此在开始之前我们先要介l一下一个开放源码的目Q这个项目就?Apache开源组l中的httpclientQ它隶属于Jakarta的commons目Q目前的版本?.0RC2。commons下本来已l有一个net的子目Q但是又把httpclient单独提出来,可见http服务器的讉Kl非易事?

Commons-httpclient目是专门设计来简化HTTP客户端与服务器进行各U通讯~程。通过它可以让原来很头疼的事情现在L的解冻I例如你不再管是HTTP或者HTTPS的通讯方式Q告诉它你想使用HTTPS方式Q剩下的事情交给 httpclient替你完成。本文会针对我们在编写HTTP客户端程序时l常到的几个问题进行分别介l如何用httpclient来解军_们,Z让读者更快的熟悉q个目我们最开始先l出一个简单的例子来读取一个网늚内容Q然后@序渐q解x前进中的所形侍?/font>

1Q?d|页(HTTP/HTTPS)内容

下面是我们给出的一个简单的例子用来讉K某个面

/*

 * Created on 2003-12-14 by Liudong

 */

package http.demo;

import java.io.IOException;

import org.apache.commons.httpclient.*;

import org.apache.commons.httpclient.methods.*;

/**

 * 最单的HTTP客户?用来演示通过GET或者POST方式讉K某个面

 * @author Liudong

 */

public class SimpleClient {

    public static void main(String[] args) throws IOException

    {

        HttpClient client = new HttpClient();   

        //讄代理服务器地址和端?nbsp;   

        //client.getHostConfiguration().setProxy("proxy_host_addr",proxy_port);

        //使用GETҎQ如果服务器需要通过HTTPSq接Q那只需要将下面URL中的http换成https

        HttpMethod method = new GetMethod("        //使用POSTҎ

        //HttpMethod method = new PostMethod("        client.executeMethod(method);

        //打印服务器返回的状?

        System.out.println(method.getStatusLine());

        //打印q回的信?

        System.out.println(method.getResponseBodyAsString());

        //释放q接

        method.releaseConnection();

    }
}

在这个例子中首先创徏一个HTTP客户?HttpClient)的实例,然后选择提交的方法是GET或?POSTQ最后在HttpClient实例上执行提交的ҎQ最后从所选择的提交方法中d服务器反馈回来的l果。这是使用HttpClient的基本流E。其实用一行代码也可以搞定整个请求的q程Q非常的单!

2Q?以GET或者POST方式向网|交参?

其实前面一个最单的CZ中我们已l介l了如何使用GET或者POST方式来请求一个页面,本小节与之不同的是多了提交时讑֮面所需的参敎ͼ我们知道如果是GET的请求方式,那么所有参数都直接攑ֈ面的URL后面用问号与面地址隔开Q每个参数用&隔开Q例如:http://java.sun.com?name=liudong&mobile=123456Q但是当使用POSTҎ时就会稍微有一点点ȝ。本节的例子演C向如何查询手机L所在的城市Q代码如下:

/*

 * Created on 2003-12-7 by Liudong

 */

package http.demo;

import java.io.IOException;

import org.apache.commons.httpclient.*;

import org.apache.commons.httpclient.methods.*;

/**

 * 提交参数演示

 * 该程序连接到一个用于查询手机号码所属地的页?

 * 以便查询LD?330227所在的省䆾以及城市

 * @author Liudong

 */

public class SimpleHttpClient {

    public static void main(String[] args) throws IOException

    {

        HttpClient client = new HttpClient();

        client.getHostConfiguration().setHost("        HttpMethod method = getPostMethod();//使用POST方式提交数据

        client.executeMethod(method);

       //打印服务器返回的状?

        System.out.println(method.getStatusLine());

        //打印l果面

        String response =  new String(method.getResponseBodyAsString().getBytes("8859_1"));

       //打印q回的信?

        System.out.println(response);

        method.releaseConnection();

    }

    /**

     * 使用GET方式提交数据

     * @return

     */

    private static HttpMethod getGetMethod(){

        return new GetMethod("/simcard.php?simcard=1330227");

    }

    /**

     * 使用POST方式提交数据

     * @return

     */

    private static HttpMethod getPostMethod(){

        PostMethod post = new PostMethod("/simcard.php");

        NameValuePair simcard = new NameValuePair("simcard","1330227");

        post.setRequestBody(new NameValuePair[] { simcard});

        return post;

    }

}

在上面的例子中页?a >http://www.imobile.com.cn/simcard.php需要一个参数是simcardQ这个参数gؓ手机LD,x机号码的前七位,服务器会q回提交的手机号码对应的省䆾、城市以及其他详l信息。GET的提交方法只需要在URL后加入参C息,而POST则需要通过NameValuePaircL讄参数名称和它所对应的?

3Q?处理面重定?

在JSP/Servlet~程中response.sendRedirectҎ是使用HTTP协议中的重定向机制。它与JSP中的<jsp:forward ?gt;的区别在于后者是在服务器中实现页面的跌{Q也是说应用容器加载了所要蟩转的面的内容ƈq回l客LQ而前者是q回一个状态码Q这些状态码的可能D下表Q然后客Ld需要蟩转到的页面的URLq新加载新的页面。就是这样一个过E,所以我们编E的时候就要通过 HttpMethod.getStatusCode()Ҏ判断q回值是否ؓ下表中的某个值来判断是否需要蟩转。如果已l确认需要进行页面蟩转了Q那么可以通过dHTTP头中的location属性来获取新的地址?

状态码
 对应HttpServletResponse的常?br> 详细描述
301  SC_MOVED_PERMANENTLY
 面已经怹Ud另外一个新地址
302  SC_MOVED_TEMPORARILY
 面暂时Ud到另外一个新的地址
303  SC_SEE_OTHER
 客户端请求的地址必须通过另外的URL来访?br>307  SC_TEMPORARY_REDIRECT  同SC_MOVED_TEMPORARILY

下面的代码片D|C如何处理页面的重定?

client.executeMethod(post);

        System.out.println(post.getStatusLine().toString());

        post.releaseConnection();

        //查是否重定向

        int statuscode = post.getStatusCode();

        if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY) ||

            (statuscode == HttpStatus.SC_MOVED_PERMANENTLY) ||

            (statuscode == HttpStatus.SC_SEE_OTHER) ||

(statuscode == HttpStatus.SC_TEMPORARY_REDIRECT)) {

//d新的URL地址

            Header header = post.getResponseHeader("location");

            if (header != null) {

                String newuri = header.getValue();

                if ((newuri == null) || (newuri.equals("")))

                    newuri = "/";

                GetMethod redirect = new GetMethod(newuri);

                client.executeMethod(redirect);

                System.out.println("Redirect:"+ redirect.getStatusLine().toString());

                redirect.releaseConnection();

            } else

                System.out.println("Invalid redirect");

        }

我们可以自行~写两个JSP面Q其中一个页面用response.sendRedirectҎ重定向到另外一个页面用来测试上面的例子?

4Q?模拟输入用户名和口oq行d

本小节应该说是HTTP客户端编E中最常碰见的问题Q很多网站的内容都只是对注册用户可见的,q种情况下就必须要求使用正确的用户名和口令登录成功后Q方可浏览到惌的页面。因为HTTP协议是无状态的Q也是q接的有效期只限于当前请求,h内容l束后连接就关闭了。在q种情况下ؓ了保存用Ld信息必须使用到Cookie机制。以JSP/ServletZQ当览器请求一个JSP或者是Servlet的页面时Q应用服务器会返回一个参敎ͼ名ؓjsessionidQ因不同应用服务器而异Q,值是一个较长的唯一字符串的CookieQ这个字W串g是当前讉K该站点的会话标识。浏览器在每讉K该站点的其他面时候都要带上jsessionidq样的Cookie信息Q应用服务器Ҏdq个会话标识来获取对应的会话信息?

对于需要用L录的|站Q一般在用户d成功后会用戯料保存在服务器的会话中,q样当访问到其他的页面时候,应用服务器根据浏览器送上的Cookie中读取当前请求对应的会话标识以获得对应的会话信息Q然后就可以判断用户资料是否存在于会话信息中Q如果存在则允许讉K面Q否则蟩转到d面中要求用戯入帐号和口oq行d。这是一般用JSP开发网站在处理用户d的比较通用的方法?

q样一来,对于HTTP的客L来讲Q如果要讉K一个受保护的页面时必L拟浏览器所做的工作Q首先就是请求登录页面,然后dCookie|再次hd面q加入登录页所需的每个参敎ͼ最后就是请求最l所需的页面。当然在除第一ơ请求外其他的请求都需要附带上 Cookie信息以便服务器能判断当前h是否已经通过验证。说了这么多Q可是如果你使用httpclient的话Q你甚至q一行代码都无需增加Q你只需要先传递登录信息执行登录过E,然后直接讉K惌的页面,跟访问一个普通的面没有M区别Q因为类HttpClient已经帮你做了所有该做的事情了,太棒了!下面的例子实Cq样一个访问的q程?

/*

 * Created on 2003-12-7 by Liudong

 */

package http.demo;

import org.apache.commons.httpclient.*;

import org.apache.commons.httpclient.cookie.*;

import org.apache.commons.httpclient.methods.*;

/**

 * 用来演示d表单的示?

 * @author Liudong

 */

public class FormLoginDemo {

    static final String LOGON_SITE = "localhost";

    static final int    LOGON_PORT = 8080;

    public static void main(String[] args) throws Exception{

        HttpClient client = new HttpClient();

        client.getHostConfiguration().setHost(LOGON_SITE, LOGON_PORT);

       //模拟d面login.jsp->main.jsp

        PostMethod post = new PostMethod("/main.jsp");

        NameValuePair name = new NameValuePair("name", "ld");    

        NameValuePair pass = new NameValuePair("password", "ld");    

        post.setRequestBody(new NameValuePair[]{name,pass});

       int status = client.executeMethod(post);

        System.out.println(post.getResponseBodyAsString());

        post.releaseConnection(); 

       //查看cookie信息

        CookieSpec cookiespec = CookiePolicy.getDefaultSpec();

        Cookie[] cookies = cookiespec.match(LOGON_SITE, LOGON_PORT, "/", false, client.getState().getCookies());

       if (cookies.length == 0) {

           System.out.println("None");   

       } else {

           for (int i = 0; i < cookies.length; i++) {

               System.out.println(cookies[i].toString());   

           }

       }

       //讉K所需的页面main2.jsp

        GetMethod get = new GetMethod("/main2.jsp");

        client.executeMethod(get);

        System.out.println(get.getResponseBodyAsString());

        get.releaseConnection();

    }

}

5Q?提交XML格式参数

提交XML格式的参数很单,仅仅是一个提交时候的ContentType问题Q下面的例子演示从文件文件中dXML信息q提交给服务器的q程Q该q程可以用来试Web服务?

import java.io.File;

import java.io.FileInputStream;

import org.apache.commons.httpclient.HttpClient;

import org.apache.commons.httpclient.methods.EntityEnclosingMethod;

import org.apache.commons.httpclient.methods.PostMethod;

/**

 * 用来演示提交XML格式数据的例?

 */

public class PostXMLClient {

    public static void main(String[] args) throws Exception {

        File input = new File(“test.xml?;

        PostMethod post = new PostMethod(“http://localhost:8080/httpclient/xml.jsp?;

        // 讄h的内容直接从文g中读?

        post.setRequestBody(new FileInputStream(input));

        if (input.length() < Integer.MAX_VALUE)

            post.setRequestContentLength(input.length());

        else           

post.setRequestContentLength(EntityEnclosingMethod.CONTENT_LENGTH_CHUNKED);

        // 指定h内容的类?

        post.setRequestHeader("Content-type", "text/xml; charset=GBK");

        HttpClient httpclient = new HttpClient();

        int result = httpclient.executeMethod(post);

        System.out.println("Response status code: " + result);

        System.out.println("Response body: ");

        System.out.println(post.getResponseBodyAsString());

        post.releaseConnection();

    }

}

6Q?通过HTTP上传文g

httpclient使用了单独的一个HttpMethod子类来处理文件的上传Q这个类是MultipartPostMethodQ该cdl封装了文g上传的细节,我们要做的仅仅是告诉它我们要上传文g的全路径卛_Q下面的代码片段演示如何使用q个cR?

MultipartPostMethod filePost = new MultipartPostMethod(targetURL);

filePost.addParameter("fileName", targetFilePath);

HttpClient client = new HttpClient();

//׃要上传的文g可能比较?因此在此讄最大的q接时旉

client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);

int status = client.executeMethod(filePost);

上面代码中,targetFilePath即ؓ要上传的文g所在的路径?

7Q?讉K启用认证的页?

我们l常会碰到这L面Q当讉K它的时候会弹出一个浏览器的对话框要求输入用户名和密码后方可,q种用户认证的方式不同于我们在前面介l的Z表单的用戯n份验证。这是HTTP的认证策略,httpclient支持三种认证方式包括Q基本、摘要以及NTLM认证。其中基本认证最单、通用但也最不安全;摘要认证是在HTTP 1.1中加入的认证方式Q而NTLM则是微Y公司定义的而不是通用的规范,最新版本的NTLM是比摘要认证q要安全的一U方式?

下面例子是从httpclient的CVS服务器中下蝲的,它简单演C如何访问一个认证保护的面Q?

import org.apache.commons.httpclient.HttpClient;

import org.apache.commons.httpclient.UsernamePasswordCredentials;

import org.apache.commons.httpclient.methods.GetMethod;

public class BasicAuthenticationExample {

    public BasicAuthenticationExample() {

    }

    public static void main(String[] args) throws Exception {

        HttpClient client = new HttpClient();

        client.getState().setCredentials(

            "            "realm",

            new UsernamePasswordCredentials("username", "password")

        );

        GetMethod get = new GetMethod("        get.setDoAuthentication( true );

        int status = client.executeMethod( get );

        System.out.println(status+""+ get.getResponseBodyAsString());

        get.releaseConnection();

    }

}

8Q?多线E模式下使用httpclient

多线E同时访问httpclientQ例如同时从一个站点上下蝲多个文g。对于同一个HttpConnection 同一个时间只能有一个线E访问,Z保证多线E工作环境下不生冲H,httpclient使用了一个多U程q接理器的c: MultiThreadedHttpConnectionManagerQ要使用q个cd单,只需要在构造HttpClient实例的时候传入即可,代码如下Q?pre>MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); HttpClient client = new HttpClient(connectionManager);

 

 

以后管讉Kclient实例卛_?

参考资料:

httpclient首页Q?nbsp;   http://jakarta.apache.org/commons/httpclient/
关于NTLM是如何工作:  http://davenport.sourceforge.net/ntlm.html



凭栏观v 2007-07-10 16:05 发表评论
]]>java IO?学习记录http://www.aygfsteel.com/cherishchen/archive/2007/07/10/129313.html凭栏观v凭栏观vTue, 10 Jul 2007 04:30:00 GMThttp://www.aygfsteel.com/cherishchen/archive/2007/07/10/129313.htmlhttp://www.aygfsteel.com/cherishchen/comments/129313.htmlhttp://www.aygfsteel.com/cherishchen/archive/2007/07/10/129313.html#Feedback0http://www.aygfsteel.com/cherishchen/comments/commentRss/129313.htmlhttp://www.aygfsteel.com/cherishchen/services/trackbacks/129313.html所有类的根接口QInputStream/OutputStream

一、底层的q是装饰?/b>

1、底层的直接与文件系l或者硬件打交道的类(充当数据源的c?Q?

包括InputStream和OutPutStream两大c,分别用于输入和输出,数据源可以是bytes arrayQString对象Qfile文gQstream序列{:

  • FileInputStream/FileOutputStream
  • ByteArrayInputStream/ByteArrayOutputStream
  • StringBufferInputStream/StringBufferOutputStream

{,具体参看下面的java iocd

2、充当装饰功能的ioc?通过装饰底层的类来实现更高的功能,l承自FilterOutputStream/FilterOutputStreamQ包括:

  • BufferedOutputStream/BufferedInputStream
  • Datainputstream/Dataoutputstream

{,具体参看下面的java iocd

使用FilterOutputStream/FilterOutputStreamӞ首先创徏一个数据源IOQ然后根据需要的功能创徏装饰cioQ其构造函数的参数为已创徏的数据源io?

clip_image002

二、面向字W还是面向字?/b>

同时Qjava的IO体系又可以分成:inputStream/outputStream和reader/writer两类Q?

Q?Q?Reader/Writer是面向Unicode字符的(CharactersQ?

Q?Q?InputStream/OutputStream是直接面向字节的QbytesQ?

Reader/Writerl承体系之所以存在,最重要的原因是Z国际化,旧式I/O stream 的承体pM仅支?-bit byte streamQ而且无法处理16-bit unicode 字符。由于unicode被用于字W国际化Q所以加入Reader/Writer以便在所有的io动作上提供对unicode的支持?

几乎所有的java io stream classes都有相应的Reader和Writer来提供对unicode的支持,但是在某些场合,使用byte-oriented InputStream和OutPutStream才是正取的方法,最合理的方式是可能先试使用Read和WriterQ其ơ才使用byte-oriented库?

三、从InputStream/OutPutStream到Reader/Writer的{?/b>

InputStreamReader和OutputStreamWriterQ可以把一个以字节为导向的stream转换成一个以字符为导向的stream?

Java 1.0 classQbyte orientedQ?nbsp;     Java 1.1 class(unicode character oriented)

装饰前的行ؓ

InputStream                                                       Reader  转换器:InputStreamReader

OutputStreamReader                                          Writer  转换器:OutputStreamWriter

FileInputSream                                                   FileOutputStream

FileReader                                                          FileWriter

StringBufferInputStream                                    StringReader/StringWriter                                    

ByteArrayInputStream                                        ByteArrayOutputStream                 

CharArrayReader                                                CharArrayWriter

装饰后的行ؓ

BufferedInputStream                                          BufferedOutputStream

BufferedReader                                                  BufferedWriter

PrintStream                                                        PrintWriter

四、示?/b>

DataInputStream和DataOutputStream

Java中除了二q制文g和用文本文件外q有ZData的数据操作,q里的Data指的是Java的基本数据类型和String。基本数据类型包括byte、int、char、long、float、double、boolean和short?/b>

例子Q?/b>

protected void connect (Socket socket)

throws IOException, SocketException

{

this.socket = socket;

applyTimeout();

serverIn = new DataInputStream (

new BufferedInputStream (socket.getInputStream ())

);

serverOut = new DataOutputStream(

new BufferedOutputStream(socket.getOutputStream(), 2048)

);

usable = true;

cnt[CONNECT]++;

setChanged();

notifyObservers();

}

在DataInputStream和DataOutputStream两个cM的方法都很简单,基本l构为readXXXX()和writeXXXX()其中XXXX代表基本数据cd或者String?/p>

凭栏观v 2007-07-10 12:30 发表评论
]]>
牛刀试-用jdom来解析ant的build文ghttp://www.aygfsteel.com/cherishchen/archive/2007/07/05/128235.html凭栏观v凭栏观vThu, 05 Jul 2007 01:11:00 GMThttp://www.aygfsteel.com/cherishchen/archive/2007/07/05/128235.html/**
* 学习jdom操作xml的习作:解析ant的build文gQ目的是得到target的执行顺?br>*
*/
import
 java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

public class AntFileParser {
    
private static Map<String, Element> targetMap;

    
/**
     * 
@param args
     
*/
    
public static void main(String[] args) {
        String xmlfile 
= "xmlfile/aaa.xml";
        Document doc;
        String finalTarget 
= "run";
        
try {
            doc 
= build(xmlfile);
        } 
catch (JDOMException e) {
            
throw new RuntimeException("parse error" + e, e);
        } 
catch (IOException e) {
            
throw new RuntimeException("parse error" + e, e);
        }

        generateTargetNameMap(doc);
        
// 首先最lQ务入?/span>
        Stack<String> stack = new Stack<String>();
        stack.push(finalTarget);
        
// 计算其他d的执行顺?/span>
        getExecuteOrder(findElementByAttributeName(finalTarget), stack);
        System.out.print(
"执行序Q?nbsp; ");
        
while (!stack.isEmpty()) {
            System.out.print(stack.pop() 
+ " ");
        }

    }

    
public static Document build(String file) throws JDOMException, IOException {
        SAXBuilder b 
= new SAXBuilder();
        Document doc 
= b.build(new File(file));
        
return doc;
    }

    
/**
     * 获取所有target元素
     * 
     * 
@param doc
     * 
@return
     
*/
    
public static List getTarget(Document doc) {
        
return doc.getRootElement().getChildren("target");
    }

    
/**
     * 获取指定元素的所有依?br>     * 
     * 
@param element
     * 
@return
     
*/
    
public static String[] getDepents(Element element) {
        String depends 
= element.getAttribute("depends").getValue();
        
return depends.split(",");
    }

    
/**
     * 使用递归的方法查找执行顺?br>     * 
     * 
@param element
     * 
@param stack
     
*/
    
public static void getExecuteOrder(Element element, Stack<String> stack) {
        String cur;
        
if (element.getAttribute("depends"== null) {
            
// 已经扑ֈ了第一个Q务,退?/span>
            return;
        } 
else {
            String[] depends 
= getDepents(element);
            cur 
= depends[0];
            
if (depends.length != 1) {
                
// 存在多个依赖dQ可能有两种情况Q?br>                // Q?Q多个Q务之间有依赖关系Q则q回依赖最大的dQ?br>                // Q?Q多个Q务之间没有依赖关p,则返回全部依赖,用逗号分隔
                cur = getmaxDependence(depends);
            }
            String[] curs 
= cur.split(",");
            
// 如果存在q行d且ƈ行Q务之间没有互怾赖,则一q放入堆栈,无所谓顺?/span>
            for (String string : curs) {
                element 
= findElementByAttributeName(string);
                
// 查是否已l入?/span>
                if (!stack.contains(element.getAttributeValue("name")))
                    stack.push(element.getAttributeValue(
"name"));
            }
            
// 递归
            getExecuteOrder(element, stack);
        }

    }

    
/**
     * 从缓存的Map中,依据target元素的name属性查找target元素
     * 
     * 
@param name
     * 
@return
     
*/
    
public static Element findElementByAttributeName(String name) {
        
return targetMap.get(name);
    }

    
/**
     * target元素和其name属性缓存到map?br>     * 
     * 
@param doc
     
*/
    
public static void generateTargetNameMap(Document doc) {
        List targetList 
= getTarget(doc);
        targetMap 
= new HashMap<String, Element>();
        
for (Object object : targetList) {
            Element ele 
= (Element) object;
            String name 
= ele.getAttributeValue("name");
            targetMap.put(name, ele);
        }
    }

    
public static String getmaxDependence(String[] depends) {
        
int size = depends.length;
        String target 
= "";
        
// 保存每一个Q务对其他d的存在依赖关pȝơ数
        int[] counts = new int[size];
        
//
        for (int i = 0; i < size; i++) {
            Element cur 
= findElementByAttributeName(depends[i]);
            
// 数l{换成ArrayList
            List list = arrayToList(getDepents(cur));
            
for (int j = i + 1; j < size; j++) {
                
// 查当前Q务对depends数组中的其他d是否存在依赖
                if (list.contains(depends[j])) {
                    counts[i]
++;
                }
            }
        }
        
// 获取最大依?/span>
        int max = 0;
        
for (int a : counts) {
            
if (max < a)
                max 
= a;
        }
        
// 如果最大依赖ؓ0Q则说明depends中的d之间没有互相依赖Qؓq行dQ{换逗号分隔q回
        if (max == 0) {
            
for (int i = 0; i < size; i++) {
                target 
= target + depends[i] + ",";
            }
            
// 除去最后一个逗号
            target = target.substring(0, target.length() - 1);
            
return target;
        }
        
// 否则QQ务之间存在依赖,取最大依?/span>
        for (int i = 0; i < size; i++) {
            
if (counts[i] == max)
                target 
= depends[i];
        }
        
return target;
    }

    
public static List<String> arrayToList(String[] array) {
        ArrayList
<String> list = new ArrayList<String>();
        
for (String string : array) {
            list.add(string);
        }
        
return list;
    }

}

用到的xml文g

<?xml version="1.0" encoding="UTF-8"?>
<project name="srping_study" default="run">

    
<property name="src" value="src" />
    
<property name="bin" value="bin" />
    
<property name="test" value="test" />
    
<property name="run.classpath" value="bin" />
    
<property name="lib" value="lib" />
    
<property name="xmlfile" value="xmlfile" />

    
<path id="spring.lib">
        
<pathelement path="${lib}" />
        
<fileset dir="${lib}" includes="*.jar" />
    
</path>

    
<target name="clear">
        
<delete dir="${bin}" quiet="true" />
    
</target>

    
<target name="compile" depends="clear">
        
<mkdir dir="bin" />
        
<javac destdir="${run.classpath}" srcdir="${src}" classpathref="spring.lib">
        
</javac>
        
<copy todir="${run.classpath}">
            
<fileset dir="${xmlfile}">
                
<include name="*.xml" />
                
<include name="*.properties" />
            
</fileset>
        
</copy>
    
</target>

    
<target name="deploy" depends="compile">
        
<java classname="org.chen.spring_study.HibernateUtil" classpathref="spring.lib">
            
<classpath path="${run.classpath}" />
        
</java>
    
</target>
    
    
<target name="deploy1" depends="deploy">
            
<java classname="org.chen.spring_study.HibernateUtil" classpathref="spring.lib">
                
<classpath path="${run.classpath}" />
            
</java>
        
</target>

    
<target name="test" depends="compile">
        
<java classname="org.chen.spring_study.transaction.programmic.ProgramicCodingTrans" classpathref="spring.lib">
            
<classpath path="${run.classpath}" />
        
</java>
    
</target>
    


    
<target name="run" depends="test,deploy,deploy1">
        
<java classname="org.chen.spring_study.transaction.declaretrans.DeclareClient" classpathref="spring.lib">
            
<classpath path="${run.classpath}" />
        
</java>
    
</target>
</project>


凭栏观v 2007-07-05 09:11 发表评论
]]>
Jdom 常用APIhttp://www.aygfsteel.com/cherishchen/archive/2007/07/04/128138.html凭栏观v凭栏观vWed, 04 Jul 2007 08:35:00 GMThttp://www.aygfsteel.com/cherishchen/archive/2007/07/04/128138.htmlhttp://www.aygfsteel.com/cherishchen/comments/128138.htmlhttp://www.aygfsteel.com/cherishchen/archive/2007/07/04/128138.html#Feedback0http://www.aygfsteel.com/cherishchen/comments/commentRss/128138.htmlhttp://www.aygfsteel.com/cherishchen/services/trackbacks/128138.html使用JdomQ操作xml从此变得方便Q^_^

一、创建XML文g

Document doc = new Document(new Element("rootElement"))

或?

Document doc = new Document();
// 根元?/p>

 Element root = new Element("persons");
 doc.addContent(root);

// add person
Element person = new Element("person").setText("test1");
root.addContent(person);

//add person 2
person = new Element("person").setText("test2");
root.addContent(person);

 

另外一U方式:

Document doc = new Document(new Element("family")
.addContent(new Element("mom"))
.addContent(new Element("dad").addContent("kidOfDad")));

二、解析XML文g

   一般而言Q用org.jdom.input.SAXBuilder更快Q推荐用,而org.jdom.input.DOMBuilder适用于已l存在DOM对象的场合?

SAXBuilder b = new SAXBuilder();
            // Create the document
Document doc = b.build(new File(xmlfilename));

  • 获取根元素:Element webapp = doc.getRootElement();
  • 获取子节点(支持namespaceQ:

// Get a List of direct children as Elements
List allChildren = element.getChildren();

// Get all direct children with a given name
List namedChildren = element.getChildren("name");

// Get the first kid with a given name
Element kid = element.getChild("name");

  • 增加/删除子节点,可以像操作List对象一h作子节点集合Q当然也可以以传l的方式来操?/li>

List allChildren = element.getChildren();
// Remove the fourth child
allChildren.remove(3);
// Remove all children named "jack"
allChildren.removeAll(element.getChildren("jack"));

或?br /> element.removeChildren("jack");
// Add a new child
allChildren.add(new Element("jane"));

或?br /> element.addContent(new Element("jane"));
// Add a new child in the second position
allChildren.add(1, new Element("second"));

  • d/讄属?/li>

// d属性:

String value =table.getAttributeValue("width");// table 是element
// 也可以在d属性的同时q行cd转换
try {
value =table.getAttribute("border").getIntValue();
}
catch (DataConversionException e) { }

// 讄属?

// Add an attribute
table.addAttribute("vspace", "0");
// Add an attribute more formally 比较正式的写?br /> table.addAttribute(new Attribute("name", "value"))
// Remove an attribute
table.removeAttribute("border");
// Remove all attributes U除所有属?br /> table.getAttributes().clear();

  • 获取元素的内?/li>

比如<description>A cool demo</description>Q则可以直接获取内容

String content = element.getText();

// U除多余的空白,字符串前后的I白Q不会移除字W串内部的空?

element.getTextNormalize();

  • 讄元素的内?/li>

// This blows away all current content
element.setText("A new description");

//Special characters are interpreted correctly: Ҏ字符可以被正地转义

element.setText("<xml> content");

// 创徏cdata元素

element.addContent(new CDATA("<xml> content"));

三、输出XML

XMLOutputter cȝ来实现XML文g的输出,在创建的时候需要一个Format对象来格式化XML文gQFormat对象是一个工厂类Q提供几个静态的工厂Ҏ来提供一些常规的XML格式Q比如getPrettyFormat()Q?

XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
        try {
            outputter.output(doc, new FileOutputStream(new File("xmlfile/persons.xml")));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

 

四、xml Namespace的支?/h2>
  • 获取名空?/li>

Namespace xhtml = Namespace.getNamespace("xhtml", “http://www.w3.org/1999/xhtml”);

  • Namespace 对象可以作ؓElement 和Attribute的大多数Ҏ的可选参敎ͼ

List kids = element.getChildren("p", xhtml);
Element kid = element.getChild("title", xhtml);
Attribute height = element.getAttribute("height", xhtml);

附录QJava下XML~程接口比较QDOM SAX JDOM JAXPQ网l装载)

一、DOM Q文档对象模型)
?XML 文档的已解析版本定义了一l接口。解析器d整个文档Q然后构Z个驻留内存的树结构,然后代码可以?DOM 接口来操作这个树l构?br /> 优点Q整个文档树在内存中Q便于操作;支持删除、修攏V重新排列等多种功能Q?br /> ~点Q将整个文档调入内存Q包括无用的节点Q,费旉和空_
使用场合Q一旦解析了文档q需多次讉Kq些数据Q?br /> g资源充Q内存、CPUQ?br />  二、SAX
决DOM的问题,出现了SAX?br /> SAX Q事仉动。当解析器发现元素开始、元素结束、文本、文档的开始或l束{时Q发送事ӞE序员编写响应这些事件的代码Q保存数据?br /> 优点Q不用事先调入整个文档,占用资源;
SAX解析器代码比DOM解析器代码小Q适于AppletQ下?br /> ~点Q不是持久的Q事件过后,若没保存数据Q那么数据就丢了Q?br /> 无状态性;从事件中只能得到文本Q但不知该文本属于哪个元素;
使用场合QApplet;
只需XML文档的少量内容,很少回头讉KQ?br /> 机器内存;
 三、JDOM
为减DOM、SAX的编码量Q出CJDOMQ?br /> 优点Q?0-80原则Q极大减了代码?br /> 使用场合Q要实现的功能简单,如解析、创建等Q但在底层,JDOMq是使用SAXQ最常用Q、DOM、Xanan
四、JAXP
为多个XML解析器提供了l一~程接口
更换解析器,不用更改代码
使用场合Q若不用JdomQ一般徏议用JAPXQ将代码与各U解析器的实现细节隔R?/p>



凭栏观v 2007-07-04 16:35 发表评论
]]>The JDOM Philosophyhttp://www.aygfsteel.com/cherishchen/archive/2007/07/04/128048.html凭栏观v凭栏观vWed, 04 Jul 2007 03:19:00 GMThttp://www.aygfsteel.com/cherishchen/archive/2007/07/04/128048.htmlhttp://www.aygfsteel.com/cherishchen/comments/128048.htmlhttp://www.aygfsteel.com/cherishchen/archive/2007/07/04/128048.html#Feedback0http://www.aygfsteel.com/cherishchen/comments/commentRss/128048.htmlhttp://www.aygfsteel.com/cherishchen/services/trackbacks/128048.htmlThe JDOM Philosophy

• JDOM should be straightforward for Java programmers
– Use the power of the language (Java 2)
– Take advantage of method overloading, the Collections APIs, reflection, weak references
– Provide conveniences like type conversions


• JDOM should hide the complexities of XML wherever possible
An Element has content, not a child Text node with content
– Exceptions should contain useful error messages
– Give line numbers and specifics, use no SAX or DOM specifics

• JDOM should integrate with DOM and SAX
– Support reading and writing DOM documents and SAX events
– Support runtime plug-in of any DOM or SAX parser
– Easy conversion from DOM/SAX to JDOM
– Easy conversion from JDOM to DOM/SAX


• JDOM should stay current with the latest XML standards
– DOM Level 2, SAX 2.0, XML Schema


• JDOM does not need to solve every problem
– It should solve 80% of the problems with 20% of the effort
– We think we got the ratios to 90% / 10%

JDOM consists of five packages

 

image

 

The org.jdom.input Package


• Classes for reading XML from existing sources:
– DOMBuilder
– SAXBuilder
• Also, outside contributions in jdom-contrib:
– ResultSetBuilder
– SpitfireBuilder
• New support for JAXP-based input
– Allows consistency across applications
– Builders pick up JAXP information and user automatically
– Sets stage for JAXP version.next

 

The org.jdom.output Package


Classes for writing XML to various forms of output:
– DOMOutputter
– SAXOutputter
– XMLOutputter
Also, outside contributions in jdom-contrib:
– JTreeOutputter

 

org.jdom.transform

• TRaX is now supported in org.jdom.transform
– Supports XSLT transformations
– Defines Source and Result interfaces
– JDOMSource
– JDOMResult

 

General Program Flow


• Normally XML Document -> SAXBuilder ->XMLOutputter

image




完整的pdf下蝲地址Q?span style="font-weight: bold;">JDOM: How It Works,and How It Opened the Java Processby Jason Hunter

http://www.aygfsteel.com/Files/cherishchen/JDOM%20How%20It%20Works.zip



凭栏观v 2007-07-04 11:19 发表评论
]]>
一家之a--Java异常处理http://www.aygfsteel.com/cherishchen/archive/2007/07/04/128014.html凭栏观v凭栏观vWed, 04 Jul 2007 01:18:00 GMThttp://www.aygfsteel.com/cherishchen/archive/2007/07/04/128014.htmlhttp://www.aygfsteel.com/cherishchen/comments/128014.htmlhttp://www.aygfsteel.com/cherishchen/archive/2007/07/04/128014.html#Feedback0http://www.aygfsteel.com/cherishchen/comments/commentRss/128014.htmlhttp://www.aygfsteel.com/cherishchen/services/trackbacks/128014.htmlJava异常为我们提供了一致的识别和处理程序错误的机制Q有效的异常处理能增强程序的健壮性和易于调试性?/span>

首先q是重温?/span>java的异怽pȝ构,如图所C,所有异常的ҎThrowableQ异常又分ؓchecked exception?/span>unchecked exceptionQ?/span>RuntimeException是属于unchecked exceptionQ?/span>JVM 一旦捕捉到unchecked exception ׃l止当前q行的程序,q在console中打出错误信息?/span>

 

Java exception hierarchyption hierarchy

一?/span>Unchecked exceptions VS Checked exceptions

 下表列出使用两种异常的场合:

Client's reaction when exception happens

Exception type

Client code cannot do anything

Make it an unchecked exception

Client code will take some useful recovery action based on information in exception

Make it a checked exception

 q个斚w的例?/span>hibernate是一个,?/span>hibernate2中,HibernateExceptionq是checked exceptionsQ但是到?/span>hibernate3中就成了unchecked exceptionsQ因为对于数据库操作来说Q一旦出现异常,是比较严重的错误,而且?/span>client端基本上是无能ؓ力的Q?/span>unchecked exceptions更加合适?/span>

另外Q?/span>unchecked exceptions的优点在于不客户端代码显式地处理他们Q异常可以一直往上传递(除非需要{化异常,否则异常不需要在中间被捕捉,节省了很多的try{}catch()Q代码更加简z)Q直Cx捉处理他们,Q有Z问,如何不强制客L处理他们Q比如像checked exceptionsq样Q不处理是语法错误Q如何保证异常能够得到处理呢Q在q点上,java提供的完善的文档机制Q通过API客户端程序员可以很方便地知道他调用的Ҏ可能会抛Z么异常,一个负责h的程序员应该对其进?/span>catch和处理)Q?/span>Java API提供了很多的unchecked exceptionsQ比?/span>NullPointerException, IllegalArgumentException, and IllegalStateExceptionQ?span lang="EN-US">java提供的标准的unchecked exceptions是值得推荐的,q样的好处在于代码更加zƈ可以减少代码对内存的占用?/span>

二?/span>Java异常的推q处?/span>

Java异常应该可能地推迟处理Q除非要转化异常Q重新抛出,否则最好不要处理,而是留给最后能够处理异常的地方?/span>

通过为方法添?/span>throws声明Q可以将处理异常的责M递到更高的层ơ。在声明哪些需要抛出的时候,应该可能地详细。这样做的目的是可以?/span>API中详l地表述Ҏ可能会出现的异常Q从而让调用该方法的clinetE序员做好处理异常的准备Q比如对于代码通过throws语句详细地声明了可能会抛出的异常Q这栯用该Ҏ的程序员׃知道会有什么样的异怼发生?/span>

public void readPreferences(String filename)

    
throws IllegalArgumentException,

          FileNotFoundException, IOException
{

    
if (filename == null)
    {

        
throw new IllegalArgumentException

                        (
"filename is null");

    }  
//if
    
//
    InputStream in = new FileInputStream(filename);

    
//
}

从语法上ԌIllegalArgumentException?/span>unckecked exception 是不需要声明的Q但是ؓ了从文档的角度考虑Q最好还是加上,q样可以让调用这个方法的E序员知道,q个Ҏ会可能抛异常Q需要加以捕捉和处理?/span>

 

三、异常的处理

不管如何Q最l程序肯定是要对异常q行处理的,否则会导致不定情况的发生,但是选择异常处理的位|却是有技巧的Q通常要么是程序在q些地方从异怸恢复、l执行且不会Dq一步异常的发生Q要么是在这些地方能为用户反馈特定的信息Q比如,如何避免异常的发生或者如何从异常中恢复。因此,对于有用L面层的程序,异常的捕捉和处理推q到UI层是有好处的Q在UI层可以用对话框或者其他方式提C用户出现异常?/span>
 

参考文?/span>

Best Practices for Exception Handling by Gunjan Doshi

Three Rules for Effective Exception Handling by Jim Cushing



凭栏观v 2007-07-04 09:18 发表评论
]]>
Dijkstra法-L有向图中最短\?/title><link>http://www.aygfsteel.com/cherishchen/archive/2007/07/03/127882.html</link><dc:creator>凭栏观v</dc:creator><author>凭栏观v</author><pubDate>Tue, 03 Jul 2007 08:28:00 GMT</pubDate><guid>http://www.aygfsteel.com/cherishchen/archive/2007/07/03/127882.html</guid><wfw:comment>http://www.aygfsteel.com/cherishchen/comments/127882.html</wfw:comment><comments>http://www.aygfsteel.com/cherishchen/archive/2007/07/03/127882.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.aygfsteel.com/cherishchen/comments/commentRss/127882.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/cherishchen/services/trackbacks/127882.html</trackback:ping><description><![CDATA[<p><strong>Dijkstra法</strong>是由荷兰计算机科学家艑օ?#183;q科斯彻发现的。算法解决的是有向图中最短\径问题?/p> <p>举例来说Q如果图中的点表示城市Q而边上的权重表示著城市间开车行l的距离?Dijkstra法可以用来扑ֈ两个城市之间的最短\径?/p> <p>Dijkstra法的输入包含了一个有权重的有向图<em>G</em>Q以及G中的一个来源顶?em>S</em>?我们?em>V</em>表示<em>G</em>中所有顶点的集合。图中的每一个边Q都是两个顶Ҏ形成的有序元素对?<em>u</em>,<em>v</em>)表示从顶?em>u</em>?em>v</em>有\径相q?假设<em>E?/em>所有边的集合,而边的权重则由权重函?em>w</em>: <em>E</em> → [0, ∞]定义?因此Q?em>w</em>(<em>u</em>,<em>v</em>)是从顶?em>u</em>到顶?em>v</em>的非负花费?cost)?边的p可以惛_成两个顶点之间的距离。Q两点间\径的p|是该\径上所有边的花费值d?已知?em>V</em>中有点<em>s</em>?em>t</em>QDijkstra法可以扑ֈ<em>s</em>?em>t</em>的最低花费\?i.e. 最短\??q个法也可以在一个图中,扑ֈ从一个顶?em>s</em>CQ何其他顶点的最短\径?/p> <br> <h3>法描述</h3> <p>  q个法是通过为每个顶?em>v</em>保留目前为止所扑ֈ的从s到v的最短\径来工作的。初始时Q源点s的\径长度D赋ؓ0Q?em>d[s]</em>=0Q, 同时把所有其他顶点的路径长度设ؓ无穷大,卌C我们不知道M通向q些点的\径(对于<em>V</em>中所有顶?em>v</em>?em>s</em>?em>d[v]</em>= ∞Q。当法l束Ӟ<em>d[v]</em>中储存的便是?em>s</em>?em>v</em>的最短\径,或者是无穷大(如果路径不存在的话)?<br></p> <p>   Dijstra法的基操作是边的拓展:如果存在一条从<em>u</em>?em>v</em>的边Q那么从<em>s</em>到v的最短\径可以通过边(<em>u</em>,<em>v</em>)d到s到u的尾部来拓展。这条\径的长度是d[u]+w(u,v)。如果这个值比目前已知?em>d[v]</em>的D,我们可以用新值来替代当前<em>d[v]</em>中的倹{拓展边的操作一直执行到所有的d[v]都代表从s到v最短\径的p。这个算法经q适当的组l因而当<em>d[u]</em>辑ֈ它最l的值的时候,每条?<em>u</em>,<em>v</em>)都只被拓展一ơ?/p> <p>法l护两个点集S和Q。集合S保留了我们已知的所有d[v]的值已l是最短\径的值顶点,而集合Q则保留其他所有顶炏V集合S初始状态ؓI,? 后每一步都有一个顶点从QUd到S。这个被选择的顶ҎQ中拥有最的d[u]值的点。当一个顶点u从Q中{Ud了S中,法Ҏ条外接边(u,v)q? 行拓展?/p> <br> <h3>法思想</h3> 设S为最短距d定的顶炚wQ看作红炚wQ,V-S是最短距d未确定的点集(看作蓝点集)?br> <strong>①初始化</strong><br>      初始化时Q只有源点s的最短距L已知?SD(s)=0)Q故U点集S={s}Q蓝炚w为空?br> <strong>②重复以下工作,按\径长度递增ơ序产生各顶Ҏ短\?/strong><br>      在当前蓝炚w中选择一个最短距L的蓝点来扩充红炚wQ以保证按\径权重递增的次序来产生各顶点的最短\径?br>      当蓝炚w中仅剩下最短距Mؓ∞的蓝点,或者所有蓝点已扩充到红炚wӞs到所有顶点的最短\径就求出来了?br>   <font color="#ff0000">注意Q?/font><br>      ①若从源点到蓝点的\径不存在Q则可假设该蓝点的最短\径是一条长度ؓ无穷大的虚拟路径?br>      ②从源点s到终点v的最短\径简UCؓv的最短\径;s到v的最短\径长度简UCؓv的最短距,q记为SD(v)?br><font color="#0000ff"> Q?Q在蓝点集中选择一个最短距L的蓝点k来扩充红炚w</font><br>      Ҏ按长度递增序生最短\径的思想Q当前最短距L的蓝点k的最短\径是Q?br>      源点Q红?Q红?Q?#8230;Q红点nQ蓝点k<br>  距离为:源点到红点n最短距?<U点n,蓝点k>辚w<br>      为求解方便,讄一个向量D[0Q.n-1]Q对于每个蓝点v∈ V-SQ用D[v]记录从源点s到达v且除v外中间不l过M蓝点(若有中间点,则必为红??最?路径长度Q简UC计距)?br>      若k是蓝炚w中估计距L的点Q则k的估计距d是最短距,卌D[k]=min{D[i] i∈V-S}Q则D[k]=SD(k)?br>      初始Ӟ每个蓝点v的D[c]值应为权w<sQv>Q且从s到v的\径上没有中间点,因ؓ该\径仅含一条边<sQv>?br>   <font color="#ff0000">注意Q?/font><br>      在蓝炚w中选择一个最短距L的蓝点k来扩充红炚w是Dijkstra法的关? <br> <font color="#0000ff"> <br> Q?Qk扩充U点集s后,蓝点集估计距ȝ修改</font><br>      k扩充到红点后Q剩余蓝炚w的估计距d能由于增加了新红点k而减,此时必须调整相应蓝点的估计距R?br>     对于L的蓝点jQ若kp变红后D[j]变小Q则必定是由于存在一条从s到j且包含新U点k的更短\径:P=<sQ?#8230;QkQj>。且D [j]减小的新路径P只可能是׃路径<sQ?#8230;Qk>和边<kQj>l成?br>      所以,当length(P)=D[k]+w<kQj>于D[j]Ӟ应该用P的长度来修改D[j]的倹{?br> <br> <font color="#0000ff"> Q?QDijkstra法</font><br> <br>  Dijkstra(GQDQs){<br>     //用Dijkstra法求有向网G的源点s到各点的最短\径长?br>     //以下是初始化操作<br>       S={s}QD[s]=0Q?//讄初始的红炚w及最短距?br>       for( all i∈ V-S )do //对蓝炚w中每个顶点i<br>           D[i]=G[s][i]Q?//讄i初始的估计距Mؓw<sQi><br>        //以下是扩充红炚w<br>       for(i=0;i<n-1;i++)do{//最多扩充n-1个蓝点到U点?br>            D[k]=min{D[i]Qall i V-S}Q?//在当前蓝炚w中选估计距L的点k<br>            if(D[k]{于∞)<br>                 returnQ?//蓝点集中所有蓝点的估计距离均ؓ∞Ӟ<br>                      //表示q些点的最短\径不存在?br>            S=S∪{k}Q?//蓝点k涂红后扩充到U点?br>            for( all j∈V-S )do //调整剩余蓝点的估计距?br>                if(D[j]>D[k]+G[k][j])<br>                 //新红点k使原D[j]值变时Q用新\径的长度修改D[j]Q?br>               //使js更近?br>                    D[j]=D[k]+G[k][j]Q?br>           }<br>    }<br><br> <p> </p> <div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;"></span><span style="color: #000000;"></span></div> <p> </p><img src ="http://www.aygfsteel.com/cherishchen/aggbug/127882.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/cherishchen/" target="_blank">凭栏观v</a> 2007-07-03 16:28 <a href="http://www.aygfsteel.com/cherishchen/archive/2007/07/03/127882.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring学习日志-事务理http://www.aygfsteel.com/cherishchen/archive/2007/07/03/127860.html凭栏观v凭栏观vTue, 03 Jul 2007 07:26:00 GMThttp://www.aygfsteel.com/cherishchen/archive/2007/07/03/127860.htmlhttp://www.aygfsteel.com/cherishchen/comments/127860.htmlhttp://www.aygfsteel.com/cherishchen/archive/2007/07/03/127860.html#Feedback0http://www.aygfsteel.com/cherishchen/comments/commentRss/127860.htmlhttp://www.aygfsteel.com/cherishchen/services/trackbacks/127860.html在service层控制事?br>

Spring推荐事务的控制在service层实玎ͼ而不是像单独使用hibernate那样Q在dao层实玎ͼq样的好处在于更好地支持declear方式的事务(service层通常提供接口Q这样可以针Ҏ口来定义事务{略Q而不是针对具体的service实现Q因此可以很方便地替换service的实玎ͼ而不需要修改事务的配置Q,更加灉|。同Ӟ可以更加斚w自然地实现全局事务的控制?/span>

举例如下Q?/p> service接口

package x.y.service;
public interface FooService {
    
    Foo getFoo(String fooName);

    Foo getFoo(String fooName, String barName);

    
void insertFoo(Foo foo);

    
void updateFoo(Foo foo);
}

 


一个service实现

package x.y.service;
public class DefaultFooService implements FooService {
    
public Foo getFoo(String fooName) {
        
throw new UnsupportedOperationException();
    }

    
public Foo getFoo(String fooName, String barName) {
        
throw new UnsupportedOperationException();
    }

    
public void insertFoo(Foo foo) {
        
throw new UnsupportedOperationException();
    }

    
public void updateFoo(Foo foo) {
        
throw new UnsupportedOperationException();
    }
}

 

spring.xmlQ注意在声明事务的时候,是针对service接口的,而不是针对service实现?br>

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop
="http://www.springframework.org/schema/aop"
    xmlns:tx
="http://www.springframework.org/schema/tx"
    xsi:schemaLocation
="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
>



    
<!-- this is the service object that we want to make transactional -->
    
<bean id="fooService" class="x.y.service.DefaultFooService" />

    
<!-- the transactional advice (i.e. what 'happens'; see the <aop:advisor/> bean below) -->
    
<tx:advice id="txAdvice" transaction-manager="txManager">
        
<!-- the transactional semantics -->
        
<tx:attributes>
            
<!-- all methods starting with 'get' are read-only -->
            
<tx:method name="get*" read-only="true" />

            
<!-- other methods use the default transaction settings (see below) -->
            
<tx:method name="*" />
        
</tx:attributes>
    
</tx:advice>

    
<!-- ensure that the above transactional advice runs for any execution
        of an operation defined by the FooService interface 
-->
    
<aop:config>
        
<aop:pointcut id="fooServiceOperation"
            expression
="execution(* x.y.service.FooService.*(..))" />
        
<aop:advisor advice-ref="txAdvice"
            pointcut-ref
="fooServiceOperation" />
    
</aop:config>

    
<!-- don't forget the DataSource -->
    
<bean id="dataSource"
        class
="org.apache.commons.dbcp.BasicDataSource"
        destroy-method
="close">
        
<property name="driverClassName" value="org.h2.Driver" />
        
<property name="url"
            value
="jdbc:h2:tcp://localhost/D:/try/data/sample;IFEXISTS=TRUE" />
        
<property name="username" value="sa" />
        
<property name="password" value="123456" />
    
</bean>

    
<!-- similarly, don't forget the PlatformTransactionManager -->
    
<bean id="txManager"
        class
="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        
<property name="dataSource" ref="dataSource" />
    
</bean>
    
<!-- other <bean/> definitions here -->
</beans>

 

使用service层方便了使用全局事务

对于横跨多个Hibernate SessionFacotry的分布式事务Q只需单地?/span> JtaTransactionManager 同多?/span> LocalSessionFactoryBean 的定义结合v来作Z务策略。你的每一?/span>DAO通过bean属性得到各自的 SessionFactory 引用。在需要进行跨多个数据库的事务操作Ӟ只需要定义一?/span>service层,使用 JtaTransactionManager 作ؓ事务{略Q横跨多?/span>DAO和多?/span>session factories来划分事务,而不需要特D的处理?/span>

CZ的配|文件如下:

<beans>
  
<bean id="mySessionFactory1" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    
<property name="dataSource" ref="myDataSource1"/>
   ..
  
</bean>
  
<bean id="mySessionFactory2" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    
<property name="dataSource" ref="myDataSource2"/>
 …
  
</bean>
  
<bean id="myTxManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
  
<bean id="myProductDao" class="product.ProductDaoImpl">
    
<property name="sessionFactory" ref="mySessionFactory1"/>
  
</bean>
  
<bean id="myInventoryDao" class="product.InventoryDaoImpl">
    
<property name="sessionFactory" ref="mySessionFactory2"/>
  
</bean>

<aop:config>
    
<aop:pointcut id="productServiceMethods" expression="execution(* product.ProductService.*(..))"/>
    
<aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/>
 
</aop:config>

  
<tx:advice id="txAdvice" transaction-manager="myTxManager">
    
<tx:attributes>
      
<tx:method name="increasePrice*" propagation="REQUIRED"/>
      
<tx:method name="someOtherBusinessMethod" propagation="REQUIRES_NEW"/>
      
<tx:method name="*" propagation="SUPPORTS" read-only="true"/>
    
</tx:attributes>
  
</tx:advice>

    
<bean class="product.ProductServiceImpl">
       
<property name="productDao" ref="myProductDao"/>
       
<property name="inventoryDao" ref="myInventoryDao"/>
    
</bean>
    
</beans>






凭栏观v 2007-07-03 15:26 发表评论
]]>
Jbpm学习loghttp://www.aygfsteel.com/cherishchen/archive/2007/07/02/127468.html凭栏观v凭栏观vMon, 02 Jul 2007 03:43:00 GMThttp://www.aygfsteel.com/cherishchen/archive/2007/07/02/127468.htmlhttp://www.aygfsteel.com/cherishchen/comments/127468.htmlhttp://www.aygfsteel.com/cherishchen/archive/2007/07/02/127468.html#Feedback0http://www.aygfsteel.com/cherishchen/comments/commentRss/127468.htmlhttp://www.aygfsteel.com/cherishchen/services/trackbacks/127468.htmlIntroduction

    jPDL是一U直观的程语言Q用以展现商业逻辑的处理过E。jPDL包含的概忉|及Q务、异步通讯状态、定时器、自动执行的动作{,为此Qؓ了整合上q行为,jPDL提供了强大、可扩展的控制流机制?/p>

graph based execution languages

implementation technique for graph based execution languagesQ?/p>

    • based on runtime interpretation of a graph. 
    • based on message queues
    • code generation.

The strategy on how graph execution can be implemented on top of an OO programming language. For those who are familiar with design patterns, it's a combination of the command pattern and the chain of responsibility pattern.

1、Transitions  可以理解入和d节点的箭_应该存在多个Transitions  q入一个节点和一个节Ҏ多个d?strong>Transitions  的情?/p>

the structure of the graph is represented with the classes Node and TransitionQ?tt>Transition是具有方向性的

image

 

transitions are able to pass the execution from a source node to a destination node with the method take.

transition.take.method

2、execution Q类似petri中的标记Q是变迁qA的前?/strong>

An execution (also known as a token) is represented with a class called Execution. An execution has a reference to the current node.

execution.class

3、Node

A node is a command and has an execute method. Subclasses of Node are supposed to override the execute method to implement some specific behaviour for that node type.

When an execution arrives in a node, that node is executed. The Node's execute method is also responsible for propagating the execution. Propagating the execution means that a node can pass the execution that arrived in the node over one of its leaving transitions to the next node.

When a node's execute method does not propagate the execution, it behaves as a wait state.

Also when a new execution is created, it is initialized in some start node and then waits for an event.

An event is given to an execution and it can trigger the execution to start moving. If the event given to an execution relates to a leaving transition of the current node, the execution takes that transition. The execution then will continue to propagate until it enters another node that behaves as a wait state.

node.execute.method

 

So now we can already see that the two main features are supported : wait states and a graphical representation. During wait states, an Execution just points to a node in the graph

4、Actions

An Action is a command with an execute method. Actions can be associated with events.

Synchronous execution

The default propagation of execution is synchronous.



凭栏观v 2007-07-02 11:43 发表评论
]]>
JGAP - Genetic Algorithms and Genetic Programminghttp://www.aygfsteel.com/cherishchen/archive/2007/06/27/126575.html凭栏观v凭栏观vWed, 27 Jun 2007 05:34:00 GMThttp://www.aygfsteel.com/cherishchen/archive/2007/06/27/126575.htmlhttp://www.aygfsteel.com/cherishchen/comments/126575.htmlhttp://www.aygfsteel.com/cherishchen/archive/2007/06/27/126575.html#Feedback0http://www.aygfsteel.com/cherishchen/comments/commentRss/126575.htmlhttp://www.aygfsteel.com/cherishchen/services/trackbacks/126575.htmlhttp://jgap.sourceforge.net/

 

WHAT IS JGAP?

JGAP (pronounced "jay-gap") is a Genetic Algorithms and Genetic Programming component provided as a Java framework. It provides basic genetic mechanisms that can be easily used to apply evolutionary principles to problem solutions. See the examples for a demonstration or watch out the graphical tree that can be created with JGAP for found solutions of genetically evolved programs.
JGAP was designed to be very easy to use "out of the box", while also designed to be highly modular so that more adventurous users can easily plug-in custom genetic operators and other sub-components.

Documentation,  quality and stability of code are the top concerns when developing JGAP. You find really many unit tests packaged with JGAP, extensive Javadocs, and quite a lot of examples. Compare JGAP with other projects! Feedback is always welcome.



凭栏观v 2007-06-27 13:34 发表评论
]]>
y好用的H2数据?/title><link>http://www.aygfsteel.com/cherishchen/archive/2007/06/27/126524.html</link><dc:creator>凭栏观v</dc:creator><author>凭栏观v</author><pubDate>Wed, 27 Jun 2007 03:20:00 GMT</pubDate><guid>http://www.aygfsteel.com/cherishchen/archive/2007/06/27/126524.html</guid><wfw:comment>http://www.aygfsteel.com/cherishchen/comments/126524.html</wfw:comment><comments>http://www.aygfsteel.com/cherishchen/archive/2007/06/27/126524.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.aygfsteel.com/cherishchen/comments/commentRss/126524.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/cherishchen/services/trackbacks/126524.html</trackback:ping><description><![CDATA[<p><a title="http://www.h2database.com/html/frame.html" >http://www.h2database.com/html/frame.html</a></p> <p> </p> <p>最q一个桌面的E序需要用嵌入式数据库,选择了很多不同的嵌入式数?最l选择了H2Q性能是一个很重要的原因,下图是h2提供的Performance的比较图</p> <p><a title="http://www.h2database.com/html/images/performance.png" >http://www.h2database.com/html/images/performance.png</a></p> <p> </p> <p>h2是Thomas Mueller提供的一个开源的、纯java实现的关pL据库Q在google上面有讨论组<a href="mailto:h2-database@googlegroups.com">h2-database@googlegroups.com</a>QThomas Mueller也非常热情,回答问题非常及时?/p> <p> </p> <p>下面说下我最l选择h2的原因:</p> <p>Q?Q性能、小?/p> <p>Q?Q同时支持网l版和嵌入式版本Q另外还提供了内存版</p> <p>Q?Q有比较好的兼容性,支持相当标准的sql标准Q实际上也不存在一个数据库能够100%W合标准Q?/p> <p>Q?Q提供了非常友好的基于web的数据库理界面</p> <p>Q?Q支持hibernate</p> <br> <p><br></p> 补充Q?br>支持的事务隔ȝ别:<br><br> <h2>Transaction <span id="firstFound" style="color: #000000; background-color: #ffff00;">Isolation</span></h2> <p> This database supports the following transaction <span id="firstFound" style="color: #000000; background-color: #ffff00;">isolation</span> <span style="color: #000000; background-color: #00ffff;">level</span>s: </p> <ul> <li><strong>Serializable</strong><br> This is the default <span style="color: #000000; background-color: #00ffff;">level</span>.<br> To enable, execute the SQL statement 'SET LOCK_MODE 0'<br> or append ;LOCK_MODE=1 to the database URL: jdbc:h2:~/test;LOCK_MODE=1 </li> <li><strong>Read Committed</strong><br> Read locks are released immediately. Higher concurrency is possible when using this <span style="color: #000000; background-color: #00ffff;">level</span>.<br> This is the <span id="firstFound" style="color: #000000; background-color: #ffff00;">isolation</span> <span style="color: #000000; background-color: #00ffff;">level</span> used for many database systems.<br> To enable, execute the SQL statement 'SET LOCK_MODE 0'<br> or append ;LOCK_MODE=3 to the database URL: jdbc:h2:~/test;LOCK_MODE=3 </li> <li><strong>Read Uncommitted</strong><br> This <span style="color: #000000; background-color: #00ffff;">level</span> means that transaction <span id="firstFound" style="color: #000000; background-color: #ffff00;">isolation</span> is disabled.<br> To enable, execute the SQL statement 'SET LOCK_MODE 0'<br> or append ;LOCK_MODE=0 to the database URL: jdbc:h2:~/test;LOCK_MODE=0 </li> </ul> <p> When using the <span id="firstFound" style="color: #000000; background-color: #ffff00;">isolation</span> <span style="color: #000000; background-color: #00ffff;">level</span> 'serializable', dirty reads, non-repeatable reads, and phantom reads are prohibited. </p> <ul> <li><strong>Dirty Reads</strong><br> Means a connection can read uncommitted changes made by another connection.<br> Possible with: read uncommitted </li> <li><strong>Non-Repeatable Reads</strong><br> A connection reads a row, another connection changes a row and commits, and the first connection re-reads the same row and gets the new result.<br> Possible with: read uncommitted, read committed </li> <li><strong>Phantom Reads</strong><br> A connection reads a set of rows using a condition, another connection inserts a row that falls in this condition and commits, then the first connection re-reads using the same condition and gets the new row.<br> Possible with: read uncommitted, read committed </li> </ul> <h3>Table <span style="color: #000000; background-color: #00ffff;">Level</span> Locking</h3> The database allows multiple concurrent connections to the same database. To make sure all connections only see consistent data, table <span style="color: #000000; background-color: #00ffff;">level</span> locking is used. This mechanism does not allow high concurrency, but is very fast. Shared locks and exclusive locks are supported. Before reading from a table, the database tries to add a shared lock to the table (this is only possible if there is no exclusive lock on the object by another connection). If the shared lock is added successfully, the table can be read. It is allowed that other connections also have a shared lock on the same object. If a connection wants to write to a table (update or delete a row), an exclusive lock is required. To get the exclusive lock, other connection must not have any locks on the object. After the connection commits, all locks are released. This database keeps all locks in memory.<br> <img src ="http://www.aygfsteel.com/cherishchen/aggbug/126524.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/cherishchen/" target="_blank">凭栏观v</a> 2007-06-27 11:20 <a href="http://www.aygfsteel.com/cherishchen/archive/2007/06/27/126524.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java异常处理的一ҎȝQ原创)http://www.aygfsteel.com/cherishchen/archive/2007/06/25/126132.html凭栏观v凭栏观vMon, 25 Jun 2007 08:11:00 GMThttp://www.aygfsteel.com/cherishchen/archive/2007/06/25/126132.htmlhttp://www.aygfsteel.com/cherishchen/comments/126132.htmlhttp://www.aygfsteel.com/cherishchen/archive/2007/06/25/126132.html#Feedback0http://www.aygfsteel.com/cherishchen/comments/commentRss/126132.htmlhttp://www.aygfsteel.com/cherishchen/services/trackbacks/126132.htmljava提供了很好的异常处理机制Q但是如何用好异常ƈ不容易,需要根据开发对象的不同采用的异常机Ӟ本文主要在eclipse rcp开发的时候ȝ的一个异常的处理机制Q个为适合于图形界面开发,ȝhQ归U_下:

Q?Q合理用checked exception和unchecked exceptionQ说明用这两种异常的原则的文章很多Q不多罗嗦了

  Q?Q异常的转换Q如果需要,可以底层的异常包装为包含更多含义的自定义异帔R新抛出(包括checked?/span>unchecked的自定义异常体系Q,自定义异怸仅仅需要包含原始的异常信息Q还要包含一些特定的含义和处理方法;

(3) 异常的抛出,量不要在中间层处理异常Q要么在异常发生的地方处理,要么抛出Q推q到由最l调用层来处理,比如?span style="font-size: 10pt;">与用L接打交道?span lang="EN-US">UI?/span>Q捕捉异常,q以错误信息框、对话框{信息蝲体反馈良好的信息l用?/span>

 q也只是我个人的一些观点,希望大家能给出更好的方式

范例Q?span lang="EN-US">

Q?span lang="EN-US">1Q定义自定义的异常:包括了两个构造函敎ͼ一个用于提供默认的异常信息Q一个供E序员添加更加详l的异常信息Q这个异常,可以用来装所有的底层异常Q但是一般在逻辑上更加清楚,可以增加不同的自定义异常Q比如数据库处理异常、文件处理异常、网l处理异常等

public class DataException extends RuntimeException {

    
public DataException(String str, Throwable cause) {

       
super(str, cause);

    }

    
public DataException(Throwable e) {

       
super("数据操作出错错误", e);

    }  

}

 

Q?/span>2Q用自定义的异常封装底层异常:
 

public static boolean exportToExcel(String desLocation,String templateName, List list, String beanName) hrows DataException {

boolean ok = false;

Map beans 
= new HashMap();

beans.put(beanName, list);

XLSTransformer transformer 
= new XLSTransformer();

try {

      transformer.transformXLS(templateName, beans, desLocation);

      ok 
= true;

     } 
catch (ParsePropertyException e) {

       
throw new DataException("导出excel出错Q解析excel文g出错",e);

     } 
catch (IOException e) {

       
throw new DataException("导出excel出错Q文件操作出?/span>",e);

    }

return ok;

}

 

Q?span lang="EN-US">3Q在用户界面部分的处理,通过MessageDialog反馈l用h的信息Q?/span>

try {

String templateName 
= BundlePathUtil.getRealPath(Activator.PLUGIN_ID, "excelTplts\\");

    templateName 
= templateName + "aaa.xls";

    
// 从tableviewer中获取数?/span>

    List list 
= (List) personTableViewer.getInput();

    ExcelUtil.exportToExcel(desLocation, templateName, list,
"aaa");

catch (DataException e) {

// q里我用了e.getMessage(),但是再更实际的环境中Q应该给最l用L到的是一个友好的、高层的出错信息Q详l的出错信息// 应该在日志文件中体现

      MessageDialog.openError(window.getShell(), 
"导出p|""p|原因Q?/span>"+ e.getMessage());

    
// 退?/span>

return;

    }

    
// 增加导出完成的提C,比如信息?/span>

MessageDialog.openInformation(window.getShell(), 
"导出成功""查询l果已导入到"+ desLocation);

ȝ

  Ҏjava异常使用最佛_践,使用unchecked exception的效率最高,管unchecked exception不会用户捕捉和处理异常,调用层的E序员也可以凭着个h责Q心来q行异常的捕获和处理Q但是如果你不捕捉处理异常,随之而来的是E序的健壮性就得不C证?/span>

参考资?br>Best Practices for Exception Handling
http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html





凭栏观v 2007-06-25 16:11 发表评论
]]>
使用h2的case函数实现交叉?/title><link>http://www.aygfsteel.com/cherishchen/archive/2007/06/25/126126.html</link><dc:creator>凭栏观v</dc:creator><author>凭栏观v</author><pubDate>Mon, 25 Jun 2007 07:52:00 GMT</pubDate><guid>http://www.aygfsteel.com/cherishchen/archive/2007/06/25/126126.html</guid><wfw:comment>http://www.aygfsteel.com/cherishchen/comments/126126.html</wfw:comment><comments>http://www.aygfsteel.com/cherishchen/archive/2007/06/25/126126.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/cherishchen/comments/commentRss/126126.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/cherishchen/services/trackbacks/126126.html</trackback:ping><description><![CDATA[数据?span style="font-size: 10pt; font-family: 宋体;" lang="EN-US">t的ddlQ?br>create table t(class char(1),callcount int,calldate date)<br></span><img src="http://www.aygfsteel.com/images/blogjava_net/cherishchen/a1.jpg" border="0"><br><span style="font-size: 10pt; font-family: 宋体;" lang="EN-US"><br>sql语句:</span> <p class="MsoNormal" style="margin: 6pt 0cm;"><span style="font-size: 10pt; font-family: 宋体;" lang="EN-US">select calldate,<o:p></o:p></span></p> <p class="MsoNormal" style="margin: 6pt 0cm;"><span style="font-size: 10pt; font-family: 宋体;" lang="EN-US">sum(case class when '1' then callcount else 0 end) as A</span><span style="font-size: 10pt; font-family: 宋体;">c?span lang="EN-US">,<o:p></o:p></span></span></p> <p class="MsoNormal" style="margin: 6pt 0cm;"><span style="font-size: 10pt; font-family: 宋体;" lang="EN-US">sum(case class when '2' then callcount else 0 end) as B</span><span style="font-size: 10pt; font-family: 宋体;">c?span lang="EN-US">,<o:p></o:p></span></span></p> <p class="MsoNormal" style="margin: 6pt 0cm;"><span style="font-size: 10pt; font-family: 宋体;" lang="EN-US">sum(case class when '3' then callcount else 0 end) as C</span><span style="font-size: 10pt; font-family: 宋体;">c?<span lang="EN-US"><o:p></o:p></span></span></p> <span style="font-size: 10pt; font-family: 宋体;" lang="EN-US">from t group by calldate<br><br>最后结果:<br><img src="http://www.aygfsteel.com/images/blogjava_net/cherishchen/a2.jpg" border="0"><br><br></span><span style="font-size: 10pt; font-family: 宋体;" lang="EN-US"><!--[if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter"/> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0"/> <v:f eqn="sum @0 1 0"/> <v:f eqn="sum 0 0 @1"/> <v:f eqn="prod @2 1 2"/> <v:f eqn="prod @3 21600 pixelWidth"/> <v:f eqn="prod @3 21600 pixelHeight"/> <v:f eqn="sum @0 0 1"/> <v:f eqn="prod @6 1 2"/> <v:f eqn="prod @7 21600 pixelWidth"/> <v:f eqn="sum @8 21600 0"/> <v:f eqn="prod @7 21600 pixelHeight"/> <v:f eqn="sum @10 21600 0"/> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/> <o:lock v:ext="edit" aspectratio="t"/> </v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" style="'width:120.75pt; height:96pt'"> <v:imagedata src="file:///C:\DOCUME~1\chen\LOCALS~1\Temp\msohtml1\01\clip_image001.png" o:title=""/> </v:shape><![endif]--><!--[if !vml]--><!--[endif]--></span><br> <img src ="http://www.aygfsteel.com/cherishchen/aggbug/126126.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/cherishchen/" target="_blank">凭栏观v</a> 2007-06-25 15:52 <a href="http://www.aygfsteel.com/cherishchen/archive/2007/06/25/126126.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>前段旉研究的jpos的文?/title><link>http://www.aygfsteel.com/cherishchen/archive/2007/06/25/126116.html</link><dc:creator>凭栏观v</dc:creator><author>凭栏观v</author><pubDate>Mon, 25 Jun 2007 07:18:00 GMT</pubDate><guid>http://www.aygfsteel.com/cherishchen/archive/2007/06/25/126116.html</guid><wfw:comment>http://www.aygfsteel.com/cherishchen/comments/126116.html</wfw:comment><comments>http://www.aygfsteel.com/cherishchen/archive/2007/06/25/126116.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.aygfsteel.com/cherishchen/comments/commentRss/126116.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/cherishchen/services/trackbacks/126116.html</trackback:ping><description><![CDATA[     摘要: Jpos体系l构 一?nbsp;  ISOComponet       q里ISOField和ISOBitMap都是实现了ISOComponent的叶子节点,ISOMsg则是包含了ISOField的Composite Q组合类Q:ISOMsgcȝ护了Hashtable fieldsQ维护了该报文的所有的位元?  参考:composite模式 ...  <a href='http://www.aygfsteel.com/cherishchen/archive/2007/06/25/126116.html'>阅读全文</a><img src ="http://www.aygfsteel.com/cherishchen/aggbug/126116.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/cherishchen/" target="_blank">凭栏观v</a> 2007-06-25 15:18 <a href="http://www.aygfsteel.com/cherishchen/archive/2007/06/25/126116.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">¹</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ԭ</a>| <a href="http://" target="_blank">̫</a>| <a href="http://" target="_blank">Ǭ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">°Ͷ</a>| <a href="http://" target="_blank">˳</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank">°Ͷ</a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ξ</a>| <a href="http://" target="_blank">α</a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ũ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ǿ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ָ</a>| <a href="http://" target="_blank">Զ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">żҽ</a>| <a href="http://" target="_blank">Դ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>