﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Paul之Coder日记-文章分类-1、Java</title><link>http://www.blogjava.net/llxiong/category/8433.html</link><description>收藏。</description><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 08:08:44 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 08:08:44 GMT</pubDate><ttl>60</ttl><item><title>Java 正则表达式详解</title><link>http://www.blogjava.net/llxiong/articles/62985.html</link><dc:creator>xnabx</dc:creator><author>xnabx</author><pubDate>Fri, 11 Aug 2006 05:57:00 GMT</pubDate><guid>http://www.blogjava.net/llxiong/articles/62985.html</guid><wfw:comment>http://www.blogjava.net/llxiong/comments/62985.html</wfw:comment><comments>http://www.blogjava.net/llxiong/articles/62985.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/llxiong/comments/commentRss/62985.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/llxiong/services/trackbacks/62985.html</trackback:ping><description><![CDATA[转……<br /><div class="con_sample"><p>如果你曾经用过Perl或任何其他内建正则表达式支持的语言，你一定知道用正则表达式处理文本和匹配模式是多么简单。如果你不熟悉这个术语，那么“正则表达式”（Regular Expression）就是一个字符构成的串，它定义了一个用来搜索匹配字符串的模式。 </p></div><div class="con_all"><p></p><table width="620" align="center"><tbody><tr><td class="a14">如果你曾经用过Perl或任何其他内建正则表达式支持的语言，你一定知道用正则表达式处理文本和匹配模式是多么简单。如果你不熟悉这个术语，那么“正则表达式”（Regular Expression）就是一个字符构成的串，它定义了一个用来搜索匹配字符串的模式。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">许多语言，包括Perl、PHP、Python、JavaScript和JScript，都支持用正则表达式处理文本，一些文本编辑器用正则表达式实现高级“搜索-替换”功能。那么Java又怎样呢？本文写作时，一个包含了用正则表达式进行文本处理的Java规范需求（Specification Request）已经得到认可，你可以期待在JDK的下一版本中看到它。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">然而，如果现在就需要使用正则表达式，又该怎么办呢？你可以从Apache.org下载源代码开放的Jakarta-ORO库。本文接下来的内容先简要地介绍正则表达式的入门知识，然后以Jakarta-ORO API为例介绍如何使用正则表达式。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><strong><font size="4">一、正则表达式基础知识</font></strong></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">我们先从简单的开始。假设你要搜索一个包含字符“cat”的字符串，搜索用的正则表达式就是“cat”。如果搜索对大小写不敏感，单词“catalog”、“Catherine”、“sophisticated”都可以匹配。也就是说： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_a.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><strong>1.1 句点符号</strong></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">假设你在玩英文拼字游戏，想要找出三个字母的单词，而且这些单词必须以“t”字母开头，以“n”字母结束。另外，假设有一本英文字典，你可以用正则表达式搜索它的全部内容。要构造出这个正则表达式，你可以使用一个通配符——句点符号“.”。这样，完整的表达式就是“t.n”，它匹配“tan”、 “ten”、“tin”和“ton”，还匹配“t#n”、“tpn”甚至“t n”，还有其他许多无意义的组合。这是因为句点符号匹配所有字符，包括空格、Tab字符甚至换行符： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_b.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><strong>1.2 方括号符号</strong></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">为了解决句点符号匹配范围过于广泛这一问题，你可以在方括号（“[]”）里面指定看来有意义的字符。此时，只有方括号里面指定的字符才参与匹配。也就是说，正则表达式“t[aeio]n”只匹配“tan”、“Ten”、“tin”和“ton”。但“Toon”不匹配，因为在方括号之内你只能匹配单个字符： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_c.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><strong>1.3 “或”符号</strong></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">如果除了上面匹配的所有单词之外，你还想要匹配“toon”，那么，你可以使用“|”操作符。“|”操作符的基本意义就是“或”运算。要匹配 “toon”，使用“t(a|e|i|o|oo)n”正则表达式。这里不能使用方扩号，因为方括号只允许匹配单个字符；这里必须使用圆括号“()”。圆括号还可以用来分组，具体请参见后面介绍。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_d.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><strong>1.4 表示匹配次数的符号</strong></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">表一显示了表示匹配次数的符号，这些符号用来确定紧靠该符号左边的符号出现的次数： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4n.jpg" border="0" /></p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">假设我们要在文本文件中搜索美国的社会安全号码。这个号码的格式是999-99-9999。用来匹配它的正则表达式如图一所示。在正则表达式中，连字符（“-”）有着特殊的意义，它表示一个范围，比如从0到9。因此，匹配社会安全号码中的连字符号时，它的前面要加上一个转义字符“\”。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4a.gif" border="0" /></p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center">图一：匹配所有123-12-1234形式的社会安全号码</p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">假设进行搜索的时候，你希望连字符号可以出现，也可以不出现——即，999-99-9999和999999999都属于正确的格式。这时，你可以在连字符号后面加上“？”数量限定符号，如图二所示： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4b.gif" border="0" /></p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center">图二：匹配所有123-12-1234和123121234形式的社会安全号码</p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">下面我们再来看另外一个例子。美国汽车牌照的一种格式是四个数字加上二个字母。它的正则表达式前面是数字部分“[0-9]{4}”，再加上字母部分“[A-Z]{2}”。图三显示了完整的正则表达式。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4c.gif" border="0" /></p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center">图三：匹配典型的美国汽车牌照号码，如8836KV</p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">1.5 “否”符号 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">“^”符号称为“否”符号。如果用在方括号内，“^”表示不想要匹配的字符。例如，图四的正则表达式匹配所有单词，但以“X”字母开头的单词除外。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4d.gif" border="0" /></p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center">图四：匹配所有单词，但“X”开头的除外</p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">1.6 圆括号和空白符号 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">假设要从格式为“June 26, 1951”的生日日期中提取出月份部分，用来匹配该日期的正则表达式可以如图五所示： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4e.gif" border="0" /></p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center">图五：匹配所有Moth DD,YYYY格式的日期</p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">新出现的“\s”符号是空白符号，匹配所有的空白字符，包括Tab字符。如果字符串正确匹配，接下来如何提取出月份部分呢？只需在月份周围加上一个圆括号创建一个组，然后用ORO API（本文后面详细讨论）提取出它的值。修改后的正则表达式如图六所示： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4f.gif" border="0" /></p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center">图六：匹配所有Month DD,YYYY格式的日期，定义月份值为第一个组</p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><strong>1.7 其它符号</strong></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">为简便起见，你可以使用一些为常见正则表达式创建的快捷符号。如表二所示： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">表二：常用符号 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4o.jpg" border="0" /></p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">例如，在前面社会安全号码的例子中，所有出现“[0-9]”的地方我们都可以使用“\d”。修改后的正则表达式如图七所示： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4g.gif" border="0" /></p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center">图七：匹配所有123-12-1234格式的社会安全号码</p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><strong><font size="4">二、Jakarta-ORO库</font></strong></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">有许多源代码开放的正则表达式库可供Java程序员使用，而且它们中的许多支持Perl 5兼容的正则表达式语法。我在这里选用的是Jakarta-ORO正则表达式库，它是最全面的正则表达式API之一，而且它与Perl 5正则表达式完全兼容。另外，它也是优化得最好的API之一。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">Jakarta-ORO库以前叫做OROMatcher，Daniel Savarese大方地把它赠送给了Jakarta Project。你可以按照本文最后参考资源的说明下载它。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">我首先将简要介绍使用Jakarta-ORO库时你必须创建和访问的对象，然后介绍如何使用Jakarta-ORO API。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><strong>▲ PatternCompiler对象</strong></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">首先，创建一个Perl5Compiler类的实例，并把它赋值给PatternCompiler接口对象。Perl5Compiler是PatternCompiler接口的一个实现，允许你把正则表达式编译成用来匹配的Pattern对象。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_e.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><strong>▲ Pattern对象</strong></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">要把正则表达式编译成Pattern对象，调用compiler对象的compile()方法，并在调用参数中指定正则表达式。例如，你可以按照下面这种方式编译正则表达式“t[aeio]n”： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_f.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">默认情况下，编译器创建一个大小写敏感的模式（pattern）。因此，上面代码编译得到的模式只匹配“tin”、“tan”、 “ten”和“ton”，但不匹配“Tin”和“taN”。要创建一个大小写不敏感的模式，你应该在调用编译器的时候指定一个额外的参数： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_g.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">创建好Pattern对象之后，你就可以通过PatternMatcher类用该Pattern对象进行模式匹配。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><strong>▲ PatternMatcher对象</strong></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">PatternMatcher对象根据Pattern对象和字符串进行匹配检查。你要实例化一个Perl5Matcher类并把结果赋值给 PatternMatcher接口。Perl5Matcher类是PatternMatcher接口的一个实现，它根据Perl 5正则表达式语法进行模式匹配： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_h.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">使用PatternMatcher对象，你可以用多个方法进行匹配操作，这些方法的第一个参数都是需要根据正则表达式进行匹配的字符串： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">· boolean matches(String input, Pattern pattern)：当输入字符串和正则表达式要精确匹配时使用。换句话说，正则表达式必须完整地描述输入字符串。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">· boolean matchesPrefix(String input, Pattern pattern)：当正则表达式匹配输入字符串起始部分时使用。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">· boolean contains(String input, Pattern pattern)：当正则表达式要匹配输入字符串的一部分时使用（即，它必须是一个子串）。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">另外，在上面三个方法调用中，你还可以用PatternMatcherInput对象作为参数替代String对象；这时，你可以从字符串中最后一次匹配的位置开始继续进行匹配。当字符串可能有多个子串匹配给定的正则表达式时，用PatternMatcherInput对象作为参数就很有用了。用 PatternMatcherInput对象作为参数替代String时，上述三个方法的语法如下： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">· boolean matches(PatternMatcherInput input, Pattern pattern) </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">· boolean matchesPrefix(PatternMatcherInput input, Pattern pattern) </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">· boolean contains(PatternMatcherInput input, Pattern pattern) </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><strong><font size="4">三、应用实例</font></strong></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">下面我们来看看Jakarta-ORO库的一些应用实例。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><strong>3.1 日志文件处理</strong></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">任务：分析一个Web服务器日志文件，确定每一个用户花在网站上的时间。在典型的BEA WebLogic日志文件中，日志记录的格式如下： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_i.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">分析这个日志记录，可以发现，要从这个日志文件提取的内容有两项：IP地址和页面访问时间。你可以用分组符号（圆括号）从日志记录提取出IP地址和时间标记。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">首先我们来看看IP地址。IP地址有4个字节构成，每一个字节的值在0到255之间，各个字节通过一个句点分隔。因此，IP地址中的每一个字节有至少一个、最多三个数字。图八显示了为IP地址编写的正则表达式： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4h.gif" border="0" /></p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center">图八：匹配IP地址</p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">IP地址中的句点字符必须进行转义处理（前面加上“\”），因为IP地址中的句点具有它本来的含义，而不是采用正则表达式语法中的特殊含义。句点在正则表达式中的特殊含义本文前面已经介绍。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">日志记录的时间部分由一对方括号包围。你可以按照如下思路提取出方括号里面的所有内容：首先搜索起始方括号字符（“[”），提取出所有不超过结束方括号字符（“]”）的内容，向前寻找直至找到结束方括号字符。图九显示了这部分的正则表达式。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4i.gif" border="0" /></p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center">图九：匹配至少一个字符，直至找到“]”</p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">现在，把上述两个正则表达式加上分组符号（圆括号）后合并成单个表达式，这样就可以从日志记录提取出IP地址和时间。注意，为了匹配“- -”（但不提取它），正则表达式中间加入了“\s-\s-\s”。完整的正则表达式如图十所示。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4j.gif" border="0" /></p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center">图十：匹配IP地址和时间标记</p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">现在正则表达式已经编写完毕，接下来可以编写使用正则表达式库的Java代码了。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">为使用Jakarta-ORO库，首先创建正则表达式字符串和待分析的日志记录字符串： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_j.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">这里使用的正则表达式与图十的正则表达式差不多完全相同，但有一点例外：在Java中，你必须对每一个向前的斜杠（“\”）进行转义处理。图十不是 Java的表示形式，所以我们要在每个“\”前面加上一个“\”以免出现编译错误。遗憾的是，转义处理过程很容易出现错误，所以应该小心谨慎。你可以首先输入未经转义处理的正则表达式，然后从左到右依次把每一个“\”替换成“\\”。如果要复检，你可以试着把它输出到屏幕上。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">初始化字符串之后，实例化PatternCompiler对象，用PatternCompiler编译正则表达式创建一个Pattern对象： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_k.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">现在，创建PatternMatcher对象，调用PatternMatcher接口的contain()方法检查匹配情况： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_l.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">接下来，利用PatternMatcher接口返回的MatchResult对象，输出匹配的组。由于logEntry字符串包含匹配的内容，你可以看到类如下面的输出： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_m.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><strong>3.2 HTML处理实例一</strong></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">下面一个任务是分析HTML页面内FONT标记的所有属性。HTML页面内典型的FONT标记如下所示： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><font face="Arial, Serif" color="#ff0000" size="+2"></font><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_n.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">程序将按照如下形式，输出每一个FONT标记的属性： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_o.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">在这种情况下，我建议你使用两个正则表达式。第一个如图十一所示，它从字体标记提取出“"face="Arial, Serif" size="+2" color="red"”。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4k.gif" border="0" /></p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center">图十一：匹配FONT标记的所有属性</p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">第二个正则表达式如图十二所示，它把各个属性分割成名字-值对。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4l.gif" border="0" /></p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center">图十二：匹配单个属性，并把它分割成名字-值对</p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">分割结果为： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_p.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">现在我们来看看完成这个任务的Java代码。首先创建两个正则表达式字符串，用Perl5Compiler把它们编译成Pattern对象。编译正则表达式的时候，指定Perl5Compiler.CASE_INSENSITIVE_MASK选项，使得匹配操作不区分大小写。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">接下来，创建一个执行匹配操作的Perl5Matcher对象。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_q.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">假设有一个String类型的变量html，它代表了HTML文件中的一行内容。如果html字符串包含FONT标记，匹配器将返回true。此时，你可以用匹配器对象返回的MatchResult对象获得第一个组，它包含了FONT的所有属性： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_r.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">接下来创建一个PatternMatcherInput对象。这个对象允许你从最后一次匹配的位置开始继续进行匹配操作，因此，它很适合于提取FONT标记内属性的名字-值对。创建PatternMatcherInput对象，以参数形式传入待匹配的字符串。然后，用匹配器实例提取出每一个FONT的属性。这通过指定PatternMatcherInput对象（而不是字符串对象）为参数，反复地调用PatternMatcher对象的contains ()方法完成。PatternMatcherInput对象之中的每一次迭代将把它内部的指针向前移动，下一次检测将从前一次匹配位置的后面开始。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">本例的输出结果如下： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_s.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><strong>3.3 HTML处理实例二</strong></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">下面我们来看看另一个处理HTML的例子。这一次，我们假定Web服务器从widgets.acme.com移到了newserver.acme.com。现在你要修改一些页面中的链接： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_t.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">执行这个搜索的正则表达式如图十三所示： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4m.gif" border="0" /></p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><p align="center">图十三：匹配修改前的链接</p></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">如果能够匹配这个正则表达式，你可以用下面的内容替换图十三的链接： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_u.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">注意#字符的后面加上了$1。Perl正则表达式语法用$1、$2等表示已经匹配且提取出来的组。图十三的表达式把所有作为一个组匹配和提取出来的内容附加到链接的后面。 </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">现在，返回Java。就象前面我们所做的那样，你必须创建测试字符串，创建把正则表达式编译到Pattern对象所必需的对象，以及创建一个PatternMatcher对象：<img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_v.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">接下来，用com.oroinc.text.regex包Util类的substitute()静态方法进行替换，输出结果字符串： </td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_w.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">Util.substitute()方法的语法如下： </td></tr></tbody></table><table height="17" width="620" align="center"><tbody><tr><td class="a14" height="13"><img alt="" src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_x.jpg" border="0" /></td></tr></tbody></table><table width="620" align="center"><tbody><tr><td class="a14">这个调用的前两个参数是以前创建的PatternMatcher和Pattern对象。第三个参数是一个Substiution对象，它决定了替换操作如何进行。本例使用的是Perl5Substitution对象，它能够进行Perl5风格的替换。第四个参数是想要进行替换操作的字符串，最后一个参数允许指定是否替换模式的所有匹配子串（Util.SUBSTITUTE_ALL），或只替换指定的次数。</td></tr></tbody></table></div><img src ="http://www.blogjava.net/llxiong/aggbug/62985.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/llxiong/" target="_blank">xnabx</a> 2006-08-11 13:57 <a href="http://www.blogjava.net/llxiong/articles/62985.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>throws 语句</title><link>http://www.blogjava.net/llxiong/articles/37112.html</link><dc:creator>xnabx</dc:creator><author>xnabx</author><pubDate>Thu, 23 Mar 2006 15:05:00 GMT</pubDate><guid>http://www.blogjava.net/llxiong/articles/37112.html</guid><wfw:comment>http://www.blogjava.net/llxiong/comments/37112.html</wfw:comment><comments>http://www.blogjava.net/llxiong/articles/37112.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/llxiong/comments/commentRss/37112.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/llxiong/services/trackbacks/37112.html</trackback:ping><description><![CDATA[
		<p>import java.io.*;</p>
		<p>class test_throws<br />{ <br /> public static  void main(String args[])  throws IOException // { //main方法内可能会抛出IOException异常<br />//main方法并没有处理该异常,而是把它丢出去由调用它的人来处理(也就是给jvm处理)<br />  ....<br /> }<br />}<br /><br />比喻：<br />程序是老板让你做的事, 异常就是做事过程中遇到的问题, 如果问题你能够处理, 那么你可以自己处理, 如果不能处理的问题, 定义出来, 抛给老板. throws就是抛给老板的问题了</p>
		<p>public void a() throws 丢给老板的Exception{<br />  try{<br />    //做老板给你的事情<br />  } catch(你能处理的Exception e){<br />    //处理你能解决的问题<br />  } finally {<br />    //不管问题有没有发生, 都要处理的工作<br />  }<br />}<br /><br /></p>
<img src ="http://www.blogjava.net/llxiong/aggbug/37112.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/llxiong/" target="_blank">xnabx</a> 2006-03-23 23:05 <a href="http://www.blogjava.net/llxiong/articles/37112.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网上看到华为java的面试题 </title><link>http://www.blogjava.net/llxiong/articles/37100.html</link><dc:creator>xnabx</dc:creator><author>xnabx</author><pubDate>Thu, 23 Mar 2006 14:36:00 GMT</pubDate><guid>http://www.blogjava.net/llxiong/articles/37100.html</guid><wfw:comment>http://www.blogjava.net/llxiong/comments/37100.html</wfw:comment><comments>http://www.blogjava.net/llxiong/articles/37100.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/llxiong/comments/commentRss/37100.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/llxiong/services/trackbacks/37100.html</trackback:ping><description><![CDATA[
		<p>在网上看到华为java的面试题 <br />JAVA方面<br />1 面向对象的特征有哪些方面   <br />2 String是最基本的数据类型吗?</p>
		<p>3 int 和 Integer 有什么区别</p>
		<p>4 String 和StringBuffer的区别</p>
		<p>5 运行时异常与一般异常有何异同？<br />异常表示程序运行过程中可能出现的非正常状态，运行时异常表示虚拟机的通常操作中可能遇到的异常，是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常，但是并不要求必须声明抛出未被捕获的运行时异常。</p>
		<p>6 说出一些常用的类，包,接口，请各举5个</p>
		<p>7 说出ArrayList,Vector, LinkedList的存储性能和特性<br />ArrayList和Vector都是使用数组方式存储数据，此数组元素数大于实际存储的数据以便增加和插入元素，它们都允许直接按序号索引元素，但是插入元素要涉及数组元素移动等内存操作，所以索引数据快而插入数据慢，Vector由于使用了synchronized方法（线程安全），通常性能上较ArrayList差，而LinkedList使用双向链表实现存储，按序号索引数据需要进行前向或后向遍历，但是插入数据时只需要记录本项的前后项即可，所以插入速度较快。<br />8设计4个线程，其中两个线程每次对j增加1，另外两个线程对j每次减少1。写出程序。<br />以下程序使用内部类实现线程，对j增减的时候没有考虑顺序问题。<br />public class ThreadTest1{<br />    private int j;<br />    public static void main(String args[]){<br />        ThreadTest1 tt=new ThreadTest1();<br />        Inc inc=tt.new Inc();<br />        Dec dec=tt.new Dec();<br />        for(int i=0;i&lt;2;i++){<br />            Thread t=new Thread(inc);<br />            t.start();<br />            t=new Thread(dec);<br />            t.start();<br />        }<br />    }<br />    private synchronized void inc(){<br />        j++;<br />        System.out.println(Thread.currentThread().getName()+"-inc:"+j);<br />    }<br />    private synchronized void dec(){<br />        j--;<br />        System.out.println(Thread.currentThread().getName()+"-dec:"+j);<br />    }<br />    <br />    class Inc implements Runnable{<br />        public void run(){<br />            for(int i=0;i&lt;100;i++){<br />                inc();<br />            }<br />        }<br />    }<br />    class Dec implements Runnable{<br />        public void run(){<br />            for(int i=0;i&lt;100;i++){<br />                dec();<br />            }<br />        }<br />    }<br />}</p>
		<p>9.JSP的内置对象及方法。<br />request request表示HttpServletRequest对象。它包含了有关浏览器请求的信息，并且提供了几个用于获取cookie, header, 和session数据的有用的方法。 </p>
		<p>response response表示HttpServletResponse对象，并提供了几个用于设置送回 浏览器的响应的方法（如cookies,头信息等） </p>
		<p>out out 对象是javax.jsp.JspWriter的一个实例，并提供了几个方法使你能用于向浏览器回送输出结果。 </p>
		<p>pageContext pageContext表示一个javax.servlet.jsp.PageContext对象。它是用于方便存取各种范围的名字空间、servlet相关的对象的API，并且包装了通用的servlet相关功能的方法。 </p>
		<p>session session表示一个请求的javax.servlet.http.HttpSession对象。Session可以存贮用户的状态信息 </p>
		<p>application applicaton 表示一个javax.servle.ServletContext对象。这有助于查找有关servlet引擎和servlet环境的信息 </p>
		<p>config config表示一个javax.servlet.ServletConfig对象。该对象用于存取servlet实例的初始化参数。 </p>
		<p>page page表示从该页面产生的一个servlet实例<br />10.用socket通讯写出客户端和服务器端的通讯，要求客户发送数据后能够回显相同的数据。<br />参见课程中socket通讯例子。</p>
		<p>11说出Servlet的生命周期，并说出Servlet和CGI的区别。<br />Servlet被服务器实例化后，容器运行其init方法，请求到达时运行其service方法，service方法自动派遣运行与请求对应的doXXX方法（doGet，doPost）等，当服务器决定将实例销毁的时候调用其destroy方法。<br />与cgi的区别在于servlet处于服务器进程中，它通过多线程方式运行其service方法，一个实例可以服务于多个请求，并且其实例一般不会销毁，而CGI对每个请求都产生新的进程，服务完成后就销毁，所以效率上低于servlet。<br />12.EJB是基于哪些技术实现的?并说出SessionBean和EntityBean的区别，StatefulBean和StatelessBean的区别。</p>
		<p>13．EJB包括（SessionBean,EntityBean）说出他们的生命周期，及如何管理事务的？</p>
		<p>14．说出数据连接池的工作机制是什么?</p>
		<p>15.同步和异步有和异同，在什么情况下分别使用他们？举例说明。</p>
		<p>16.应用服务器有那些？</p>
		<p>17你所知道的集合类都有哪些？主要方法？</p>
		<p>18给你一个:驱动程序A,数据源名称为B,用户名称为C,密码为D,数据库表为T，请用JDBC检索出表T的所有数据。</p>
		<p>19．说出在JSP页面里是怎么分页的?<br />页面需要保存以下参数：<br />总行数：根据sql语句得到总行数<br />每页显示行数：设定值<br />当前页数：请求参数<br />页面根据当前页数和每页行数计算出当前页第一行行数，定位结果集到此行，对结果集取出每页显示行数的行即可。</p>
		<p>
				<br />数据库方面：</p>
		<p>1.存储过程和函数的区别<br />存储过程是用户定义的一系列sql语句的集合，涉及特定表或其它对象的任务，用户可以调用存储过程，而函数通常是数据库已定义的方法，它接收参数并返回某种类型的值并且不涉及特定用户表。<br />2.事务是什么？<br />事务是作为一个逻辑单元执行的一系列操作，一个逻辑工作单元必须有四个属性，称为 ACID（原子性、一致性、隔离性和持久性）属性，只有这样才能成为一个事务：<br />原子性<br />事务必须是原子工作单元；对于其数据修改，要么全都执行，要么全都不执行。<br />一致性<br />事务在完成时，必须使所有的数据都保持一致状态。在相关数据库中，所有规则都必须应用于事务的修改，以保持所有数据的完整性。事务结束时，所有的内部数据结构（如 B 树索引或双向链表）都必须是正确的。<br />隔离性<br />由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。事务查看数据时数据所处的状态，要么是另一并发事务修改它之前的状态，要么是另一事务修改它之后的状态，事务不会查看中间状态的数据。这称为可串行性，因为它能够重新装载起始数据，并且重播一系列事务，以使数据结束时的状态与原始事务执行的状态相同。<br />持久性<br />事务完成之后，它对于系统的影响是永久性的。该修改即使出现系统故障也将一直保持。</p>
		<p>3.游标的作用？如何知道游标已经到了最后？<br />游标用于定位结果集的行，通过判断全局变量@@FETCH_STATUS可以判断是否到了最后，通常此变量不等于0表示出错或到了最后。<br />4.触发器分为事前触发和事后触发，这两种触发有和区别。语句级触发和行级触发有何区别。<br />事前触发器运行于触发事件发生之前，而事后触发器运行于触发事件发生之后。通常事前触发器可以获取事件之前和新的字段值。<br />语句级触发器可以在语句执行前或后执行，而行级触发在触发器所影响的每一行触发一次。</p>
<img src ="http://www.blogjava.net/llxiong/aggbug/37100.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/llxiong/" target="_blank">xnabx</a> 2006-03-23 22:36 <a href="http://www.blogjava.net/llxiong/articles/37100.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：JavaWebService客户端简明攻略 </title><link>http://www.blogjava.net/llxiong/articles/36028.html</link><dc:creator>xnabx</dc:creator><author>xnabx</author><pubDate>Sun, 19 Mar 2006 04:11:00 GMT</pubDate><guid>http://www.blogjava.net/llxiong/articles/36028.html</guid><wfw:comment>http://www.blogjava.net/llxiong/comments/36028.html</wfw:comment><comments>http://www.blogjava.net/llxiong/articles/36028.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/llxiong/comments/commentRss/36028.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/llxiong/services/trackbacks/36028.html</trackback:ping><description><![CDATA[
		<div class="postTitle">
				<a href="http://blog.csdn.net/zlyperson/archive/2003/08/05/12494.aspx">
						<img height="13" src="http://blog.csdn.net/images/authorship.gif" width="15" border="0" /> JavaWebService客户端简明攻略</a>
				<script language="javascript"><![CDATA[ocument.title="JavaWebService客户端简明攻略 - "+document.title]]&gt;</script>
		</div>
		<div class="postText">
				<p> 作为CSDN JavaWebService的小斑竹，很久就想写一些关于JWS的基础文章，苦于公私繁忙，一直无心下笔，所以一拖再拖，今日看了我斑块下有网友问及关于Java调用WebService之问题，遂下决心写下此文以资共勉。<br /> 装备：<br />  JDK1.4.1_02，关于这方面的问题，没必要说了吧。^_^<br />  Java Web Services Developer Pack 1.2 (<a href="http://java.sun.com/webservices/downloads/webservicespack.html">http://java.sun.com/webservices/downloads/webservicespack.html</a>)<br />  我的JWSDP安装路径为E:\miniTool\jwsdp-1.2\，文章中直接使用，就不重声。<br /> 平台：<br />  Microsoft Windows 2000 [Version 5.00.2195]</p>
				<p> 全文以Google的WebService为例，它提供了一个开发包，<a href="http://www.google.com/apis/download.html">http://www.google.com/apis/download.html</a>，但是很多的WebService不会这样的，只是告诉你一个他们的WSDL(WebService Description Language)文件。但是这都没有本质的区别的，在Google的开发包中也包含这么一个文件GoogleSearch.wsdl。大多数的WebService客户端开发，知道了WSDL文件就已经可以了，但是Google呢还需要一个LicenseKey，因为只是测试用，所以这个限制了同一个账号一天只能够查询1000还是2000次，我忘记了，我申请了两个，在我这个C#的演示站点(<a href="http://63.210.240.215/rookieport/">http://63.210.240.215/rookieport/</a>)就用到了这两个LicenseKey(随机使用)，关于这个C#演示站点的介绍及源文件见<a href="http://www10.brinkster.com/rookieport/default.aspx">http://www10.brinkster.com/rookieport/default.aspx</a>。非常遗憾的是，这两个站点我都不能够更新了，世界上从来没有免费的午餐！！！<br /> 好了，这篇文章的主题是JavaWebService而不是C#WebService，做好准备工作之后，我们稍微分析下WSDL文件，这个文件主要是描述WebService具体使用到了哪些数据结构(types中描述)，提供了哪些Web服务功能(operation中描述)，以及该服务的访问地址(service中描述)，关于WSDL这里不详述，找时间补上。在GoogleSearch.wsdl中，我们看到有一个doGoogleSearch的Operation，从名称上我们可以看出，这个方法应该是提供搜索服务的，前面有一段描述了doGoogleSearch调用的参数：<br />  &lt;message name="doGoogleSearch"&gt;<br />    &lt;part name="key"            type="xsd:string"/&gt;<br />    &lt;part name="q"              type="xsd:string"/&gt;<br />    &lt;part name="start"          type="xsd:int"/&gt;<br />    &lt;part name="maxResults"     type="xsd:int"/&gt;<br />    &lt;part name="filter"         type="xsd:boolean"/&gt;<br />    &lt;part name="restrict"       type="xsd:string"/&gt;<br />    &lt;part name="safeSearch"     type="xsd:boolean"/&gt;<br />    &lt;part name="lr"             type="xsd:string"/&gt;<br />    &lt;part name="ie"             type="xsd:string"/&gt;<br />    &lt;part name="oe"             type="xsd:string"/&gt;<br />  &lt;/message&gt;<br />第一个参数就是LicenseKey，第二个参数是要查询的内容，第三个参数是起始结果页，对于多页的结果集合起翻页作用，第四个参数是定义每页最大记录数，后面的参数不是很重要了，其中lr是定义查找的语言类型，假如查找简体中文可以为lang_zh-CN，ie/oe是输入和输出的编码类型，缺省都为UTF-8。<br /> 再往后面我们看到关于doGoogleSearch的返回类型的描述：<br />  &lt;message name="doGoogleSearchResponse"&gt;<br />    &lt;part name="return"         type="typens:GoogleSearchResult"/&gt;           <br />  &lt;/message&gt;<br />type="typens:GoogleSearchResult"说明了数据类型的命名空间，我们查找GoogleSearchResult，可以看到他是个复合类型，<br />      &lt;xsd:complexType name="GoogleSearchResult"&gt;<br />        &lt;xsd:all&gt;<br />          &lt;xsd:element name="documentFiltering"           type="xsd:boolean"/&gt;<br />          &lt;xsd:element name="searchComments"              type="xsd:string"/&gt;<br />          &lt;xsd:element name="estimatedTotalResultsCount"  type="xsd:int"/&gt;<br />          &lt;xsd:element name="estimateIsExact"             type="xsd:boolean"/&gt;<br />          &lt;xsd:element name="resultElements"              type="typens:ResultElementArray"/&gt;<br />          &lt;xsd:element name="searchQuery"                 type="xsd:string"/&gt;<br />          &lt;xsd:element name="startIndex"                  type="xsd:int"/&gt;<br />          &lt;xsd:element name="endIndex"                    type="xsd:int"/&gt;<br />          &lt;xsd:element name="searchTips"                  type="xsd:string"/&gt;<br />          &lt;xsd:element name="directoryCategories"         type="typens:DirectoryCategoryArray"/&gt;<br />          &lt;xsd:element name="searchTime"                  type="xsd:double"/&gt;<br />        &lt;/xsd:all&gt;<br />      &lt;/xsd:complexType&gt;</p>
				<p> 这里面用xml语言描述了GoogleSearchResult的数据结构，type="xsd:XXX"的属性都是简单数据类型，还用到了两个复合类型ResultElementArray, DirectoryCategoryArray读者可以继续分析，这些数据类型，都会被JWS的解释转换工具生成相应的Java类。两个Array结尾的复合类型，在JWSDP1.1以前也是生成了一个相应的ArrayOfXXXXX的类，现在1.2做得比较好了，，直接映射到java的数组。</p>
				<p> 好了我们可以进入客户端开发的实际性操作的第一步了，首先我们需要编辑一个xml格式的config文件，形式如下：<br />&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;configuration xmlns="<a href="http://java.sun.com/xml/ns/jax-rpc/ri/config">http://java.sun.com/xml/ns/jax-rpc/ri/config</a>"&gt;<br /> &lt;wsdl name="SearchService" location="GoogleSearch.wsdl" packageName="rook.searcher"/&gt;<br />&lt;/configuration&gt;<br />这里面指明了WebService描述文件的位置，可以是本地的也可以是远程的。后面packageName说明了生成WebService客户端文件的包名。把这个文件放到GoogleAPI的目录下。<br /> <br /> 第二步，启动控制台，进入GoogleAPI的目录<br />C:\googleapi&gt;dir/w<br /> Volume in drive C is WIN2K<br /> Volume Serial Number is 0B73-18E3</p>
				<p> Directory of C:\googleapi</p>
				<p>[.]                                [..]<br />README.txt                         GoogleAPIDemo.java<br />GoogleSearch.wsdl                  APIs_Reference.html<br />LICENSE.txt                        googleapi.jar<br />[javadoc]                          [dotnet]<br />[soap-samples]                     [licenses]<br />google.config<br />JavaWebService客户端简明攻略.txt<br /> 建立一个client的目录C:\&gt;mkdir client<br /> 执行WSCompile生成客户端文件C:\googleapi&gt;E:\miniTool\jwsdp-1.2\jaxrpc\bin\wscompile -gen -d client -keep google.config<br /> -gen参数告诉编译器生成WebService客户端文件，-d client将生成的文件保存的目录，-keep指示保留中间文件。执行之后，进入client\rook\searcher目录可以看到生成系列java和java类文件。</p>
				<p> 第三步，我们创建客户端调用文件。查找包含rookie的中文网页前十条记录，然后打印标题和Url。<br />import rook.searcher.*;<br />import java.rmi.*;</p>
				<p>public class Searcher{<br /> public static void main(String[] args){<br />  try {<br />   GoogleSearchPort sport = new GoogleSearchService_Impl().getGoogleSearchPort();<br />   GoogleSearchResult result = sport.doGoogleSearch("OyGtVqM5YRRS7hFXHLWEodMSEbiZlmc9", "rookie", 0, 10, true, "lang_zh-CN", true, "lang_zh-CN", "UTF-8", "UTF-8");//第一个参数是LicenseKey<br />   <br />   ResultElement[] results = result.getResultElements();<br />   for ( int idx = 0; idx &lt; results.length; idx ++) {<br />    System.out.println(idx + ": " + results[idx].getTitle() + "\r\n" + results[idx].getURL());<br />   } <br />  } catch (Exception e) {<br />   e.printStackTrace();<br />  }<br /> }<br />}</p>
				<p> 第四步，编译。这里面用到了jaxrpc-impl包。<br />C:\googleapi\client&gt;javac -classpath E:\miniTool\jwsdp-1.2\jaxrpc\lib\jaxrpc-impl.jar;. Searcher.java</p>
				<p> 第五步，执行。<br />C:\googleapi\client&gt;java -cp E:\miniTool\jwsdp-1.2\jaxrpc\lib\jaxrpc-impl.jar;E:\miniTool\jwsdp-1.2\jaxrpc\lib\jaxrpc-api.jar;E:\miniTool\jwsdp-1.2\jwsdp-shared\lib\jax-qname.jar;E:\miniTool\jwsdp-1.2\jwsdp-shared\lib\activation.jar;E:\miniTool\jwsdp-1.2\jwsdp-shared\lib\mail.jar;E:\miniTool\jwsdp-1.2\jwsdp-shared\lib\xsdlib.jar;E:\miniTool\jwsdp-1.2\saaj\lib\saaj-api.jar;E:\miniTool\jwsdp-1.2\saaj\lib\saaj-impl.jar;E:\miniTool\jwsdp-1.2\jwsdp-shared\lib\commons-logging.jar;E:\miniTool\jwsdp-1.2\jaxp\lib\endorsed\xercesImpl.jar;E:\miniTool\jwsdp-1.2\jaxp\lib\endorsed\dom.jar;. Searcher</p>
				<p> 全文到此结束，讲了作JavaWebService客户端开发的基本步骤，希望能够抛砖引玉！文中不详之处，敬请指教：<a href="mailto:zlyperson@163.net">zlyperson@163.net</a><br /></p>
		</div>
<img src ="http://www.blogjava.net/llxiong/aggbug/36028.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/llxiong/" target="_blank">xnabx</a> 2006-03-19 12:11 <a href="http://www.blogjava.net/llxiong/articles/36028.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>