通过weather.com.cn获取全国天气数据

获得天气数据:
访问http://m.weather.com.cn/data/101020100.html,其中1010200100是城市的id(上海),返回JSON格式的天气数据,示例如下:
{“weatherinfo”:{“city”:”上海”,”city_en”:”shanghai”,”date_y”:”2009年12月24日”,”date”:”十一月初九”,”week”:”星期四”, “fchh”:”08″,”cityid”:”101020100″,”temp1″:”14℃~6℃”,”temp2″:”9℃~3℃”,”temp3″:”6℃~2℃”, “temp4″:”5℃~1℃”,”temp5″:”7℃~4℃”,”tempF1″:”57.2℉~42.8℉”,”tempF2″:”48.2℉~37.4℉”,”tempF3″:”42.8℉~35.6℉”,”tempF4″:”41℉~33.8℉”,”tempF5″:”44.6℉~39.2℉”,”weather1″:”多云转小雨”,”weather2″:”小雨转多云”,”weather3″:”多云转小雨”,”weather4″:”阴转多云”,”weather5″:”多云”,”img1″:”1″,”img2″:”7″,”img3″:”7″,”img4″:”1″,”img5″:”1″,”img6″:”7″,”img7″:”2″,”img8″:”1″,”img9″:”1″,”img10″:”99″,”img_single”:”1″,”img_title1″:”多云”,”img_title2″:”小雨”,”img_title3″:”小雨”,”img_title4″:”多云”,”img_title5″:”多云”,”img_title6″:”小雨”,”img_title7″:”阴”,”img_title8″:”多云”,”img_title9″:”多云”,”img_title10″:”多云”,”img_title_single”:”多云”,”wind1″:”东北风转北风3-4级”,”wind2″:”北风4-5级”,”wind3″:”北风转东北风4-5级”,”wind4″:”东北风4-5级转北风3-4级”,”wind5″:”西南风3-4级”,”fl1″:”3-4级”,”fl2″:”4-5级”,”fl3″:”4-5级”,”fl4″:”4-5级转3-4级”,”fl5″:”3-4级”,”index”:”舒适”,”index_d”:”建议着薄型套装或牛仔衫裤等春秋过渡装。年老体弱者宜着套装、夹克衫等。”,”index48″:”凉”,”index48_d”:”天气凉,建议着厚外套加毛衣等春秋服装。年老体弱者宜着大衣、呢外套加羊毛衫。”,”index_uv”:”最弱”,”index48_uv”:”最弱”,”index_xc”:”不宜”,”index_tr”:”很适宜”,”index_co”:”较舒适”}}
城市id获取方式(一次性工作):
1. 访问http://m.weather.com.cn/data5/city.xml?level=0,(后面level参数可省略)得到一级列表(省、直辖市、自治区),结果用逗号隔开,id和城市名称使用竖线“|”隔开;结果示例如下:

01|北京,02|上海,03|天津,04|重庆,05|黑龙江,06|吉林,07|辽宁,08|内蒙古,09|河北,10|山西,11|陕西,12|山东,13|新疆,14|西藏,15|青海,16|甘肃,17|宁夏…(以下省略)

2. 访问http://m.weather.com.cn/data5/city02.xml?level=1,(后面level参数可省略)得到二级列表。其中02是一级省市的id,结果格式和上一层相同,示例如下(上海和黑龙江):
0201|上海
0501|哈尔滨,0502|齐齐哈尔,0503|牡丹江,0504|佳木斯,0505|绥化,0506|黑河,0507|大兴安岭,0508|伊春,0509|大庆,0510|七台河,0511|鸡西,0512|鹤岗,0513|双鸭山

3. 访问http://m.weather.com.cn/data5/city0201.xml?level=2,(后面level参数可省略)得到三级列表。0201是地级市的id,示例如下(上海):

020101|上海,020102|闵行,020103|宝山,020104|嘉定,020105|南汇,020106|金山,020107|青浦,020108|松江,020109|奉贤,020110|崇明,020111|徐家汇,020112|浦东

4. 访问http://m.weather.com.cn/data5/city020101.xml?level=3,(后面level参数可省略)得到最后一级的id,020101是区域的id,示例如下(上海市区):
020101|101020100
后面的数字就是获得天气数据需要的城市id,以http://m.weather.com.cn/data/{id}.html格式访问即可得出天气结果。
参考:
chrome天气插件:http://code.google.com/p/chinaweather/,使用Javascript编写

IE6设置Image.src的bug

这个问题我现在也没彻底搞懂。网站有一块需要建立一个Image对象,设置好src属性,onerror和onload属性,然后把Image添加为div的子元素,交给浏览器去请求图片并渲染(请看p.s.)。用其他浏览器都很正常,但用IE6浏览器访问,虽然能得到图片,但服务器的日志里会报错,第一个Exception是Connection reset by peer,第二个是多次调用response.getOutputStream()或getJspWriter()。
上了调试器,发现一次图片的调用,服务器会在入口函数的断点停留两次,说明浏览器发出了两次请求。用Fiddler看各次请求的内容,居然再也无法重现错误了。换用HttpWatch,终于重现了错误。每次图片的调用都会有两个请求,第一个请求发出后马上被掐掉(Aborted),然后接着发出第二个请求。这解释了为什么会抛Connection reset by peer的异常。第二个异常的原因,估计是当浏览器的reset请求到达服务器时,服务器的代码已经完成了生成图片的工作,并把图片塞进了response,这个时候抛来一个异常,被forward到error.jsp,于是乎二次调用了getJspWriter,报错。
网上搜了搜这个问题,有少许提到这个bug。我的解决方法很简单,就是在image append到div之后,再设置src属性。经测试解决了IE6的Aborted问题,其他浏览器,如IE7,FF3和Chrome都没什么影响。
p.s. 后来看到玉伯的博客,发现Image对象在设置了src对象以后就马上请求图片,并不等到被添加到DOM上再请求,因为Image本来就是用来做图像预加载的。所以原本的代码就有一些错误,应该先设置onerror和onload属性后,再设置src才有意义。
p.s.2 这里是一篇描述了IE中Aborted的文章,推翻了不少本文的无妄猜测。
p.s.3 经我第三次的测试,发现IE6中如果先设置image.src在appendChild,会出现Aborted问题,相反顺序则没有问题。

“Internet Explorer 无法打开 Internet站点已终止操作”问题

    以前偶尔被这个问题困扰,总是不知不觉就解决了,这次留个记录。

    先贴个Reference

    症状:打开页面,渲染到一半,弹出对话框,内容如题。点击确定后转到IE自己的错误页面,一点错误信息都没有。Google一番后,得出几个可能性:1、Debugger插件作怪;2、Javascript引号没匹配好;3、在页面渲染期间进行了insertChild操作。

    首先禁用所有调试插件,并设置禁用调试。无效。调出Multiple IE用IE6访问,问题依旧,排除第一条。

    第二人肉扫描代码,没发现问题。Firefox和Chrome页面均正常,基本排除第二条。

    第三条就看Ext.onReady()的位置了,发现了问题。在代码的最后用Ext.onReady()包裹了grid的render调用,但这不够。需要把整个grid的创建过程给embrace(不知道中文用啥好)起来,因为在GridPanel的constructor里就开始渲染了(没有设置lazy-render)。

Firefox实现text-overflow:ellipsis

用ExtJS做UI层的确很好看,在IE7(我们抛弃了IE6), Chrome,
Safari下运行都挺好,但Firefox总有点问题,都是关于Grid的。昨天碰到的问题是GridPanel(就是表格),当某列的内容超出了预设的宽度的时候,会把这一行撑爆,结果列就无法对齐,很难看。用Firebug+IEDevBar看了半天(IE是好的,Chrome还没有可用的调试器),才发现问题在于Firefox对text-overflow:ellipsis这个CSS3的属性不支持。Google了一番,这里推荐了两个方法,第一个方法更优雅一些,使用了mozilla的扩展属性-moz-binding,直接用上了XUL和XBL。第二种牵涉到了Javascript,感觉不是很好。这里有一个代码的下载,一开始我自己拷贝代码下来捣持了半天也没搞定,直接下代码就OK。
今天又碰到一个ExtJS在Firefox下显示的问题。有关于GroupingView的GridPanel的。不改了,应该没人会注意到吧。

Velocity的扩展

之前一直找不到velocity的扩展接口,导致工作一直做不下去。今天看了一个下午+一个晚上的文档,终于找到了突破口(看来我是挺笨的)。就在VelocityTools这一块。
在IBM实习时养成的很好的习惯--看源码--真是受用终身啊。通过不断的对比VelocityTools的文档,javadoc和源码,发现原来在那个toolbox.xml里大有文章。
首先,要指定toolbox.xml的位置,在web.xml里

<servlet>
<servlet-name>velocity</servlet-name>
<servlet-class>org.apache.velocity.tools.view.servlet.VelocityViewServlet</servlet-class>
<load-on-startup>10</load-on-startup>
<init-param>
<param-name>org.apache.velocity.toolbox</param-name>
<param-value>/WEB-INF/toolbox.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>velocity</servlet-name>
<url-pattern>*.vm</url-pattern>
</servlet-mapping>

这是toolbox.xml的一部份:

<toolbox>

<tool>
<key>math</key>
<scope>application</scope>
<class>org.apache.velocity.tools.generic.MathTool</class>
<request-path>/catalog/*</request-path>
</tool>

</toolbox>

<key>里就是在VTL里写的$math,这样就算引入一个对象了。
<scope>是生命周期,有关init()方法的调用。
其它两个的作用从字面上和表达就可以猜出来了。
对于扩展的类,与web容器相关的主要是一个public void init(java.lang.Object object)的方法,传入的参数是org.apache.velocity.tools.view.context.ViewContext接口,但需要手动转换。从这个接口,可以得到request, session, response, servletContext等对象,同时根据scope的不同在调用次数上也会有不同。application的只初始化一次,request每次请求都会重新初始化,session就是在session建立时初始化。
看过这些以后,对那些VelocityStruts工具的原理就一目了然咯~~

Web文件上传的草案

转自张博的blog。想到写以前的项目,要做到Ajax,可是在文件上传这一步,始终没办法逾越。只能用
<form target=”…” enctype=”multi-part/form-data” method=”post” >

</form>
<iframe name=”..”/>
这种提交到一个内部iframe的办法搞。而且上传结束的event只能通过服务器端返回的javascript调用,可以说要多难看有多难看。这个draft定义的API虽然简单,可是也够用咯~~
张博的blog。想到写以前的项目,要做到Ajax,可是在文件上传这一步,始终没办法逾越。只能用