Sunday, September 28, 2008

让 Google Blog Search 收录文章

Google 除了网页搜索外,还有个专门搜索博客文章的引擎,叫做 Blogsearch。基于 Google Blogger 构建的博客里面,反向链接的数据就来源于此。每次打开 Blogger 文章页面,实际上都会通过 JavaScript 作一次 Blogsearch 搜索,并把返回结果作为反向链接显示。

你可能觉得既然 Google 网页搜索都收录了,那同是一家的 Blogsearch 一定也收录了。事实并非如此。

通过 Google 的 Webmaster 管理工具 向 Google 提交自己的 Sitemap,有利于让 Google 在第一时间收录网站更新的页面,但是,这仅限于网页搜索。

最近发现 Blogsearch 似乎没有收录我的文章,仔细查看发现居然已经有两个月之久了,而这些文章通常在发布后快则数小时慢则最多一天内就被网页搜索收录,很是诧异。Google 了一把,找到这篇文章分析原因,说是因为 Blogsearch 和 Feedsky 的自定义域名不兼容有关。

我确实是在 FeedBurner 被封后改在页面上使用 Feedsky 的服务,但对于 Google 的 Blogsearch,向来是由 FeedBurner 自动去 Ping 的,就算 FeedBurner 被封但这个机制应该是仍然在工作的。而且要出问题早该出了,也不至于是在最近这两个月发生吧。百思不得其解,打开 FeedBurner 仔细查看了一下设置,发现设置中“Publicize » PingShot » Google Blog Search Pinging Service”前面的复选框没有勾上!难怪 Blogsearch 不收录文章了,都没人通知它了啊…… 至于为什么 FeedBurner 上这个选项是关闭就不得而知了。如果你也使用 FeedBurner 的服务,也发现 Blogsearch 收录有问题,那么最好也去检查一下。

把这个选项打开后,为了以防万一,又到 Blogsearch 的网址提交页面重新提交了一下网站的 feed 地址。大约过了一小时后,最近两个月没有被收录的文章就立即能够被搜索到了。注意这是一次性的通知服务,如果没有自动 Ping 的机制,则每次网站更新后都要手动执行这个操作。

如果使用其它支持自动 Ping 的 BSP 的话,可以添加 Blogsearch 的 Ping 服务 API 地址:
http://blogsearch.google.com/ping/RPC2
如使用 WordPress 的话,在 Update Services 里面添加这个地址就可以了。更多详细内容可以参考 Blogsearch 的常见问题API 接口文档

Updated on 2008/10/29:

实践证明,使用 Google Blog Search 对 Google 文章的收录是有显著成效的。如下图,在文章发布后,立即 Ping 了 Google Blog Search,不多久就被收录;9 分钟后,Google 的网页搜索便也收录了这篇文章。

Google 网页搜索在 9 分钟内久收录了新文章

Wednesday, September 24, 2008

Google 手机地图 2.2.0 版

Google 黑板报消息称 Google 的手机地图升级到了 2.2 版本,和之前的版本相比,多了“我的位置”、“行车路线”和“公交换乘”功能。

这些功能在以往的 Google 地图英文版是有的,只是先前的英文版本中没有国内的地图信息,于是就造成了中文版有地图不能使用 GPS 辅助,英文版有 GPS 辅助没有国内地图数据的尴尬境地。

我使用的是 Symbian S60 v3 的版本。这次升级时,手机上中英文版本显示的版本号都是 2.02(0)。简单的试用了一下,在没有 GPS 功能的情况下,也能通过 GPRS 基站数据获得大概的当前位置,只不过精度范围 2500 米至 5000 米,似乎实用性并不大。行车路线和公交换乘倒是比较方便,只是后者的公交数据仍然相对滞后。例如搜索从“成都市游乐园”到“成都市九眼桥”,会显示出 60 路,而这条线路已经在几个月前就取消了。

比较奇怪的是,在仅安装 2.2 中文版的情况下,程序中并没有找到“GPS 辅助”的选项,而 2.2 的英文版中却有“Use GPS”的选项。匪夷所思的是,英文版安装好后,中文版的“GPS 辅助”选项又神秘的出现了。在 Nokia N95 8G(自带 GPS)和 Nokia N73(蓝牙连接外置 GPS)上测试,情况一样。

另外,在英文版中,国内的行车路线和公交换乘功能似乎不可用。所以,看来比较理想的解决办法,就是同时安装中文版和英文版,这样才能在中文版中使用所有的功能……

最后,SISX 文件的下载地址:中文版英文版

Tuesday, September 23, 2008

MIDlet 在 NOKIA 手机上安装失败

这两天发现一个奇怪的问题,就是 MIDlet 在 NOKIA 6680 上无法安装。在 Jar 下载完成后,会显示“Unable to install. Not enough memory!”而安装之前手机刚刚执行过出厂复位操作,机身空余存储空间约 7MB,因此,安装失败不可能是装不下 MIDlet 的内容而导致的。

经过反复研究,终于发现问题出在 Jad 文件属性 MIDlet-Data-Size 上。这个属性是 MIDlet 用来告诉手机,该应用程序将需要多少 RMS 存储空间。由于 NOKIA 6680 的 RMS 容量,实测有 7128 KB,和机身的空余存储空间相等,也就是说理论上手机能装多少,MIDlet 的 RMS 就能装多少,因此应用程序的 Jad 里头,MIDlet-Data-Size 设置的值是 133072,也就是 128KB。

经过反复修改 Jad 文件里 MIDlet-Data-Size 的值,发现允许的最大值为 65536,也就是 64KB。任何超过这个值的应用程序,在安装时手机都会拒绝。

同样的问题在 NOKIA 6131 上也同样存在。如果有其它手机也有类似问题,以后会随时更新。

Friday, September 05, 2008

测试手机的 User-Agent

由于最近工作中需要得到一些手机的 User-Agent 以及 X-Wap-Profile 两个 HTTP 头的值,于是写了个简单的 PHP 程序,检测 HTTP 头,输出到 Response,然后放到网站上,让手机用 WAP 浏览器打开查看。

开始这个程序只是简单的输出纯文本,结果是 NOKIA、Sony Ericsson 以及 Samsung 手机都能正确读出,而 Motorola 却不行(实际测试过程中用的是 Motorola RAZR V3i),仅显示白页。

后来把程序改成输出标准 WML 页面,HTTP 头的 Content-Type 设置成 application/vnd.wap.xhtml+xml,NOKIA、Sony Ericsson 以及 Samsung 仍然能够正确显示而 Motorola 还是不合作。

最后找到答案,Content-Type 要设置成“text/vnd.wap.wml”,这下 Motorola 终于老实了…… 可是结果中只有 User-Agent,没有 X-Wap-Profile。

另外,在用中国移动的 SIM 卡测试的时候,发现 HTTP 请求中并没有 User-Agent 和 X-Wap-Profile 这两个头,而有个奇怪的
VIA: HTTP/1.1 SCCD-PS-WAP-GW02 (infoX-WISG, Huawei Technologies)
开始以为是手机的问题,但看到“Huawei”字样,觉得很蹊跷,后来换成 Orange France 的 SIM 卡,则一切正常了。

看来拦截 HTTP 请求是中国运营商的“优良传统”啊!

Update 2009/08/03:

最近发现中国移动这个问题只存在于 cmwap,用 cmnet 则正常。

Wednesday, September 03, 2008

试用 Google Chrome 浏览器

Google 昨天发布了一款开源的浏览器,已经可以下载。目前还只有 Windows 的版本,据说以后还会推出 Linux 和 Mac 的版本。

Google Chrome

和目前主流的 Internet Explorer 和 FireFox 比起来,Chrome 的特点就是简洁轻便,Installer 的大小约为 22.8M,和通常的 Windows 应用程序相比,Chrome 窗口没有标题栏和菜单栏,也没有状态栏,界面上除了标签栏、按钮/地址栏和书签栏三行以外,剩下的空间全部留给打开的网页。在地址栏后面有连个按钮,分别是针对当前页面的操作菜单和浏览器的设置菜单,因此操作起来也比较简单,这算是秉承了 Google 一贯的风格。值得一提的是,在地址栏中,URL 的域名以外的部分会显示成灰色,而域名是黑色,这样使得域名看起来更加突出。

虽然界面简洁,操作简单,但功能上该有的也一点都不含糊。支持多页面浏览、内置多款搜索引擎、支持字体缩放。可以从 Internet Explorer 或者 FireFox 导入书签、搜索引擎设置、已经保存的密码以及浏览历史记录。另外,还有下载管理、密码保存、界面默认字体和编码设置、代理服务器、内容和弹出窗口过滤、网络欺诈和恶意软件保护、SSL 证书管理等,可谓应有尽有。同时浏览器以及预置了包含简体中文和繁体中文在内的 42 种界面语言以及拼写检查。从安装目录的文件夹设置上看,应该也支持第三方插件和换肤功能,只是在浏览器界面上还没有体现出来。

对于网页开发人员来讲,Chrome 也体贴的预先内置了源代码查看器(带语法高亮)以及 DOM 查看器以及 JavaScript 调试功能。 IE 和 Firefox 则需要安装第三方插件实现这一功能。

经过测试发现 Chrome 在我机器上的 User Agent 值为:
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13

用的可能是 Safari 内核。目前的版本为 0.2.149.27,还只是处在测试阶段,相信以后会更加完善。

Tuesday, September 02, 2008

修改 IE 默认 HTML 查看器

众所周知在 Internet Explorer 打开的网页中,点鼠标右键,选“查看源代码”,即可查看所打开的网页的HTML 源代码,但通常系统会用 Notepad 打开,如果要仔细查看源代码内容,Notepad 可能显得不那么方便。修改一下注册表键值,即可用自己顺手的文本编辑器打开。
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\View Source Editor\Editor Name]

将 (default) 的值改成编辑器的路径即可,例如用 UltraeEdit,可以写:
"C:\Program Files\UltraEdit\uedit32.exe"

如果没有这个键,按照路径创建即可。

我一直用 EditPlus,要将 EditPlus 关联到 IE,可以直接在设置里打开这个选项。具体的:

Tools / Preference... / General / Use EditPlus in Internet Explorer 5

这个方法应该适用于 Windows 所有的版本,已知在 Windows 98 / Me / 2000 / XP 上有效。

Monday, September 01, 2008

用 Cobertura 测量测试覆盖率

单元测试相信大家都不陌生,测试先行编程(Test-First Programming)和测试驱动也不是什么新概念了。测试改进了代码质量,但这也只是针对实际测试到的那部分代码而言的。您需要有一个工具告诉您程序的哪些部分没有测试到,这样就可以针对这些部分编写测试代码并找出更多 bug。

现在,有 Cobertura (cobertura 在西班牙语是“覆盖”的意思)这个免费的 GPL 工具在 Java 领域来完成这个任务。Cobertura 通过在执行测试时,用额外的语句记录哪些行被测试到、哪些行没有被测试到,通过这种方式来度量字节码,以便对测试进行监视。然后它生成一个 HTML 或者 XML 格式的报告,指出代码中的哪些包、哪些类、哪些方法和哪些行没有测试到。可以针对这些特定的区域编写更多的测试代码,以发现所有隐藏的 bug。

先来看看生成报告的样子吧:

Cobertura 报告示例(点击放大)


可以看到报告列出了每个包的行覆盖率、分支覆盖率以及复杂度。点击进去,可以看到针对这个包里头每个类的报告,进而每行代码的测试情况,以及被测试到的次数。这里是 Cobertura 官方网站上给出的一个报告的 Sample。

在使用上,Cobertura 支持命令行操作,也可以结合到 Ant 任务。当然首先要定义任务:
<property name="cobertura.dir" value="C:/javastuff/cobertura" />

<path id="cobertura.classpath">
<fileset dir="${cobertura.dir}">
<include name="cobertura.jar" />
<include name="lib/**/*.jar" />
</fileset>
</path>

<taskdef classpathref="cobertura.classpath" resource="tasks.properties" />

然后,就可以用 cobertura-instrument 任务来统计测试目标:
<delete file="cobertura.ser" />

<cobertura-instrument todir="${instrumented.dir}">
<ignore regex="org.apache.log4j.*" />
<fileset dir="${classes.dir}">
<include name="**/*.class" />
<exclude name="**/*Test.class" />
</fileset>
<fileset dir="${guiclasses.dir}">
<include name="**/*.class" />
<exclude name="**/*Test.class" />
</fileset>
<fileset dir="${jars.dir}">
<include name="my-simple-plugin.jar" />
</fileset>
</cobertura-instrument>

之后,运行 Junit 测试(重要的部分用蓝色标出):
<junit fork="yes" dir="${basedir}" failureProperty="test.failed">
<!--
指定覆盖率统计的数据文件名,以下为默认值
-->
<sysproperty key="net.sourceforge.cobertura.datafile"
file="${basedir}/cobertura.ser" />


<!--
注意 classpath 的顺序:被处理过的 class 路径在为处理的
class 路径之前。这很重要!
-->
<classpath location="${instrumented.dir}" />
<classpath location="${classes.dir}" />

<!--
被处理过的 class 会在 Cobertura 运行时引用 Cobertura
的类库,因此这些类也必须在我们的 classpath 中。
-->
<classpath refid="cobertura_classpath" />

<formatter type="xml" />
<test name="${testcase}" todir="${reports.xml.dir}" if="testcase" />
<batchtest todir="${reports.xml.dir}" unless="testcase">
<fileset dir="${src.dir}">
<include name="**/*Test.java" />
</fileset>
</batchtest>
</junit>

最后,我们可以用 cobertura-report 任务来输出 HTML 格式或者 XML 格式的报告:
<cobertura-report format="html" destdir="${coveragereport.dir}"
srcdir="${src.dir}" />

也可以有更复杂的要求:
<cobertura-report format="html" destdir="${coveragereport.dir}" >
<fileset dir="${src.dir}">
<include name="**/*.java" />
<exclude name="**/*Stub.java" />
</fileset>
<fileset dir="${guisrc.dir}">
<include name="**/*.java" />
<exclude name="**/*RB.java" />
</fileset>
</cobertura-report>

另外,还可以用 cobertura-check 任务来检查统计出来的覆盖率是否达到预先的期望,如果没有达到则使得整个 Ant 任务失败;以及 cobertura-merge 任务用来合并多个测试的统计数据文件。

要特别注意的是,在这个 Ant 任务中,一定要保证数据文件 cobertura.ser 每次都被更新,并且在 instrument 的任务和后面做 Junit 的过程中,两者的路径一致,否则可能导致在输出的报告中,所有的测试结果都是 100% 或者 0%。

参考资料