X-Spirit的陋室铭

生活有的时候面临许多选择,这些选择让人困惑。 生活有的时候没有任何选择,这个时候让人压抑。 但无论生活有没有给你选择,你只能做一件事情: 排除困难,勇往直前!

2008年12月24日星期三

Tomcat不能同步context.xml文件导致的数据源连接异常

由于项目需要,写了一个hibernate+datasource的CRUD程序。。。但是部署到测试环境后,修改了context.xml和hibernate.cfg.xml发现程序运行不正常。通过跟踪日志发现Hibernate链接正常,但是datasource连接数据库异常。。。

通过跟踪日志发现是由于配置的JNDI数据源不正常导致的。但是修改了META-INF/context.xml之后仍不能正常工作。在尝试了更换测试环境JDK、更换tomcat、更换jdbc驱动等一系列方法后,终于找到根源,是由于tomcat不能自动同步META-INF/context.xml到%CATALINA_HOME%/conf/Catalina/localhost/%appname%.xml导致的。。。。
经过修改%CATALINA_HOME%/conf/Catalina/localhost/%appname%.xml内的数据源连接,该应用现在正常工作。

结论:对于tomcat,看来以后要手工同步context.xml文件到%CATALINA_HOME%/conf/Catalina/localhost/%appname%.xml了。。。

2008年6月29日星期日

Didn't we almost have it all

一个闷热的下午,
一些老照片,
一个孤独的人,
一首伤感的歌……

曾经斑驳的墙壁,
曾经卡通式的衬布,
曾经杂乱的书架,
曾经淘气的笑脸……

或者一切都只是过去,
或者一切都刚刚开始,
或者还不确定的现在,
或者已确定的未来……

The sky is also pure blue,
'cause I'll be driving on my way,
The meteor is shining...

2008年6月6日星期五

(报复性)国家汉语六级考试试卷

 

【2008-02-17 12:15】

第一部分:听力理解(20分钟)

第一大题
说明向导:在这一大题中,你将听到10个短对话。每个短对话结束后,将有一个关于这个短对话的提问。每个短对话和它的问题都将只读一遍。每个问题提出后都将有短暂的停顿。在停顿的时间中,你必须阅读四个标有a),B),C)和D)的选项,并决定哪个选项是最佳答案。然后在答题卡上相应的选项中央划一条横线。

举例:你将会听到:
男:我们什么时候开始工作呢,珍妮?
女:明天上午9点开始吧。但是我们必须抓紧时间,因为我们不得不在下午2点之前完成所有的工作。
问:他俩可以工作多长时间?
你将读到:a)2小时。 B)3小时。
C)4小时。 D)5小时。
从该对话中我们知道这两个人是在说他们将于上午9点开始工作并必须在下午2点完成。因此,D)“5小时”是最确切的答案。你应该在答题卡上选项D)的中央划一条横线。
1.女:回来了?今天车子挤吗?
男:还可以。第一站和我一起上来10个下去6个。第二站上来5个下去15个。
第三站上来17个下去20个。第四站上来24个和我一起下去7个。
问:这个男的一共坐了几站车?
a)10站。 B)4站。 C)3站。 D)5站。
2.男:来我老家开分基地吧,把农民都拉过来。
女:哎,只能这样了。
问:这个场景最可能发生在什么地方?
a)小村落。 B)网吧。 C)农田里。 D)基地组织里。
3.女:你知道吗?中国队昨天以6比0击败了韩国队!
男:啊?真的吗?万岁!
问:从这个对话中我们可以推断出什么?
a)韩国队退步了。 B)中国队进步了。 C)这个女的很兴奋。 D)这个男的很好骗。
4.男:对不起,我忘记做了。
女:你有没有长脑子啊?怎么不会忘记吃饭呀?
问:这个女的最可能是什么身份?
a)中学教师。 B)博士生导师。 C)精神病患者。 D)机器狂人。
5.女:这衣服好象太小了点啊?我还是去别处看看吧。
男:不会啊小姐,我还没见过有人穿这身衣裳比你更美的呢!
问:这个男的为何这样说?
a)他是个色狼。 B)想追求这个女的。 C)睁着眼说瞎话。 D)他在说梦话。
6.男:做我的女朋友吧,我会对你好的。
女:其实你是个很不错的男孩,和我在一起只会糟蹋了你。
问:这个女的这样说是什么意思?
a)她觉得自己配不上他。 B)谦虚几句。 C)答非所问。 D)拒绝他。
7.女:我这次英语6级答案对下来不算作文85分,不知道能不能过,担心死了。
男:你。。。。。。
问:为什么这个男的说不出话?
a)他也不知道她能不能过。 B)他不忍心告诉她结果。
C)他没听清楚她的话。 D)他准备扁她一顿。
8.男:你们老师有没有划过什么翎子啦?
女:没有啊,这次大家都死定了。
问:从对话中我们可以看出什么?
a)快考试了。 B)战争要爆发了。 C)地球要爆炸了。 D)老师不负责任。
9.女:明天要交论文了,能借用一下你的电脑吗?
男:你去问别人借吧,我的电脑连不上网。
问:男的为什么让女的去问别人借电脑?
a)他的Word是网络版的。 B)连不上网的电脑对写论文没有帮助。
B)他很小气。 D)他的电脑坏了。
10.男:待会儿你就坐在我边上,和我打手势就行了。
女:不好吧,这样会不会太危险了?
问:他们将要去做什么?
a)学习打手语。 B)做警察卧底。 C)参加考试。 D)培养感情。
(本大题共10分,一题1分)
第二大题:复式听写
曾经有一份(S1)____的感情(S2)____我面前,我没有(S3)____,等我(S4)____的时候我才(S5)____莫及,人世间最 (S6)____的事(S7)____于此,如果上天(S8)______________________________,我会对那个女孩子(S9)______________________________。如果非要(S10) ______________________________,我希望是……一万年!
(本大题共10分,前面七空0.5分一个,后面三空一共6.5分)
第二部分:阅读理解(35分钟)
说明向导:在这一部分有4篇文章。在每篇文章后面有若干问题。每个问题都有四个选项并标有a),B),C)和D)。你应当选择最恰当的一个答案并在答题卡上相应的选项中央划一条横线。
第一篇文章
第21到25题将建立在下面这段文章中:
中国有一种植物叫葳蕤。
从前有个人叫蔺芈。他想用一张罽子去捕一只鸩。不小心被葳蕤绊了一个跟头。他很踯蹰该不该再去捉。忽然他发现了一根扃,于是便用扃去打鸩,可是鸩飞走了。蔺芈气愤地说:“再抓到你就把你做成俎醢!”
虽然恨,但此时却没办法。于是蔺芈只好采了几根葳蕤回家了。
21.葳蕤为什么要绊蔺芈?
a)蔺芈犯贱。
B)这是自然规律。
C)蔺芈走路不小心。
D)文章中没有给出。
22.蔺芈为什么要捉鸩?
a)想烤了吃。
B)捉回来虐待。
C)他爱上了鸩。
D)文章中没有给出。
23.从上下文来看,“踯蹰”(第二段第一行)的意思是__________。
a)犹豫。
B)磨蹭。
C)故意拖延时间。
D)痴呆。
24.文章最后一段,为什么说蔺芈要“恨”?
a)他没有捉到鸩。
B)他被葳蕤绊了一个跟头。
C)他没有用扃打到鸠。
D)他怪自己不果断。
25.请给这篇文章拟一个合适的题目。
a)鸩的故事。
B)白痴蔺芈。
C)草本植物葳蕤。
D)得不偿失。
第二篇文章
第26到30题将建立在下面这段文章中:
一天早上,晴空万里,小明一个人走在大街上,这时,一阵风吹了过来,树倒了,把走在路上的小明压死了。
这是近年来发生的最惨痛的一次事故,足足有前年发生事故的6倍严重!但是这件事却一直没有得到有关方面的足够重视。一直到最近著名作家芭芭拉在她的新书中以一个女英雄设法救小明最终失败的方式记叙了这件惨案。
人们终于认识到可以开始正视这件事了,当然不是用它与过去发生的事故去比较,而只是客观地去讲述这件事。
26.小明是什么时候被压死的?
a)树压在他身上的时候
B)风吹过来的时候。
C)一阵风把树吹倒的时候。
D)天晴的时候。
27.为什么说这次事故有前年发生的事故6倍严重?
a)因为小明还只是个孩子。
B)因为小明是活活被压死的。
C)因为死伤人数最多。
D)文章中没有给出。
28.作家芭芭拉以怎样的方式记叙了这个故事?
a)以非常细致的描写。
B)以夸张的描写。
C)以一个女英雄救人的方式。
D)以传记的方式。
29.我们可以从这篇文章推断出__________。
a)人们感到拿这件事与以前的事比是不对的。
B)人们对这件事的发生感到愧疚。
C)人们开始正视这件事了。
D)人们开始向小明表示哀悼了。
30.从文章中来看,小明的真正死因是__________。
a)有关方面不重视。
B)被树压死。
C)女英雄水平太次。
D)小明太呆,这么大一棵树你不知道躲开呀?
第三篇文章
第31到35题将建立在下面这段文章中:
mm说:“我爱你。”
我脸红了,我不想害她:“我没钱,更没有房子和车。” mm盯着我的眼睛:“我知道。” “我的月薪只有一千五。” mm的目光仍然坚定无比:“以后会多的。” 我用颤抖的双手拿出一支烟叼在嘴上:“我每天要抽一包烟,一喝酒就闹事。” mm笑了,“以后有我在,你放心。” 我的脊梁上冒起一阵寒意,结结巴巴地对她说:“其实……其实我很流氓……幼儿园就喜欢去女厕所,小学就没了初吻,中学就……” mm没等我说完就软在了我的怀里,声音细若蚊鸣:“早知道你好色,你老偷偷瞄我胸脯… …” 一股鼻血喷涌而出,我抱紧了mm,温热娇小的身体让我热血沸腾。这时我忽然想到了一件很重要的事情,我决定把这事告诉mm...... 五秒钟后mm抬头问我:“真的?” 我悲愤地点点头。
mm沉默片刻挣开我的怀抱抬手给了我一个耳光,她愤怒地朝我喊道:“你丫竟然没有英语四级证书!”
31.文章中的“mm”是指什么东西?
a)老太婆。
B)猫科动物的一种。
C)女孩子。
D)疯子。
32.mm为什么要打人?
a)因为不打白不打。
B)因为她的男朋友没有四级证书。
C)因为这种动物性情暴烈。
D)因为她的男朋友欺骗她。
33.从这篇文章中,我们可以推断出__________。
a)见到mm这种东西应该离远点。
B)骗人是没有好下场的。
C)四级证书是非常重要的。
D)拿不到四级证书就拿不到学位证书了。
34.文中的男生为什么说那么贬低自己的话?
a)他变态。
B)他谦虚。
C)他痴呆。
D)他诚实。
35.综观全文,这段文章的体裁应该是__________。
a)小说。
B)散文。
C)诗歌。
D)幽默。
第四篇文章
第36到40题将建立在下面这段文章中:
首先我声明,我不是什么英迷,但是你的帖子让我恶心,让我甚至宁可看那些没水平的唾骂,那些也许肤浅,也许单纯,甚至不讲道理的唾骂!
你说你不希望那些人喜欢英格兰,请问你:你是什么东西?世界球迷协会理事?我还希望粱永祺不要嫁给小郑呢!你说什么“几年来我一直在讽刺英格兰,我等着有英迷能站出来对我进行反驳,然而到现在为止,对我的反驳除了粗话、骂娘以外,没有一个人能从足球的层面上分析与驳斥我”。天哪。。你在哪里等待?是在自己昏暗小屋的衣柜里等待呢?还是在遍布英格兰球迷甚至是英格兰足球流氓的街头等待?(我想你也没哪个胆量)
你居然用对法国两分钟连丢两球来做例,证明英格兰如何的无能。。。且不说英格兰现在是什么水平,单单看你能用这样一个偶然的结果来做例子,那么,你可以把全世界的球队都看成三流队伍!
其实装内行不是你的错,但是跑这里来丢人就是你的不对了!
36.从上下文看,“英迷”(第一段第一行)指的是__________。
a)喜欢英俊潇洒的人。
B)喜欢英格兰队的人。
C)英格兰足球流氓。
D)热爱英雄的人。
37.从文章中我们可以推断,作者__________。
a)是个“英迷”。
B)崇拜法国队。
C)喜欢粱永祺。
D)讨厌小郑。
38.文章第二段最后一句话是什么意思?
a)作者喜欢他能加入英格兰足球流氓的行列。
B)英格兰足球流氓善于等待。
C)作者很有胆量。
D)作者的一种挖苦和讽刺。
39.作者认为对方究竟错在哪里?
a)假装内行。
B)乱举例子。
C)跑出来丢人。
D)发没水平的帖子。
40.这段文章最有可能选自什么地方?
a)《人民日报》评论员文章。
B)金庸作品集。
C)新浪网的体育BBS。
D)白宫发言稿。
(本大题共40分,一题一分)
第三部分:词汇(20分钟)
说明向导:这部分有30句未完成的句子。每句句子后面有四个分别标有a),B),C)和D)的选项。请选择最佳的答案然后在答题卡上相应的选项中央划一条横线。
41.我们下课后一起去_____电脑。
a)打 B)操 C)干 D)搞
42.他打_____他一巴掌。
a) 上 B)过 C)了 D着
43.我去见了网友,然而令我失望的是,她却是个_____。
a)美女 B)恐龙 C)猩猩 D)长颈鹿
44.齐丹那_____又进球了。
a)秃子 B)胖子 C)猴子 D)呆子
45.你在干吗_____?
a)呼 B)呀 C)呵 D)了
46.这几天论坛上怎么没人来_____了?
a)灭火 B)浇花 C)种田 D)灌水
47.他说得太好了,大伙儿一起_____他啊!
a)宰了 B)解决 C)顶死 D)弄死
48.这篇文章写得很_____。
a)次 B)幽雅 C)硬朗 D)苦闷
49.这考试太难了,我们请个_____吧。
a)剑士 B)枪手 C)狙击手 D)CS高手
50.来我家,我俩_____FIFa。
a)玩弄 B)游戏 C)对殴 D)单挑
51.停车_____枫林晚,霜叶红于二月花。
a)做爱 B)坐爱 C)喝酒 D)品茶
52.他一天到晚就知道_____女人。
a)浸 B)泡 C)浸泡 D)烘干
53.他阅读居然得了40分,实在太_____了!
a)英俊 B)帅呆 C)牛B D)变态
54.你又被爆头了,真是个_____。
a)龙虾 B)带鱼 C)黄鳝 D)菜鸟
55.翠花,_____酸菜。
a)上 B)下 C)左 D)右
56.田野里到处都是_____。
a)旺财 B)小强 C)胖墩 D)皮蛋
57.60分万岁,多一分_____。
a)也好 B)浪费 C)奢侈 D)万岁
58.子曰:学而时习之,不亦_____乎。
a)说 B)悦 C兑 D)免
59.如果我有_____,我要叫他小叮当。
a)阿拉蕾 B)机器猫 C)呼呼猪 D)蓝皮鼠
60.我们都是_____球迷。
a)榔头 B)钉子 C)铁杆 D)竹竿
61.这么狡猾的人你还说他老实?他老实个_____!
a)鱼 B)鸟 C)虫 D)草
62.新东方的老师个个都是_____。
a)秃驴 B)** C)牛人 D)老头
63.女人是_____做的。
a)水 B)冰 C)馒头 D)面粉
64.我是一只来自北方的_____。
a)猪 B)狼 C)羊 D)狗熊
65.你_____什么呀?不就一次考得好吗?
a)激动 B)拽 C)喊 D)疯
66.用炮打他的_____。
a)马 B)牛 C)羊 D)炉
67.英语四、六级考试马上要_____啦。
a)取消 B)实行 C)崩溃 D)改革
68.更多选择更多欢笑,就在_____。
a)肯德基 B)必胜客 C)麦当劳 D)塔克贝
69.舒克舒克舒克舒克舒克舒克舒克舒克_____的舒克。
a)尿床 B)偷东西 C)开飞机 D)扔炸弹
70.将_____进行到底。
a)作弊 B)爱情 C)比赛 D)革命
(本大题共15分,一题0.5分)

第四部分:综合改错(15分钟)
说明向导:这部分中有一篇短文。在这篇短文中一共有10个错误,每个后面划横线的句子中有一个错误。你可以改一个词语,加一个词语或者删一个词语。如果你想改一个词语,把错误的那个词划去并把正确的写在横线上。如果你想加一个词语,在要加入处写一个插入记号(∧)并把要加的词语写在横线上。如果你想删去一个词语,划掉它并在横线上划一斜横即可。
举例:
电视正在很快地成为我们这个期间的文学。 1. 时期
许多有被用作文学这门学校的课程学习的观点 2. ----
也同样适用于电视∧门学科的研究。 3. 这__
近年来外国人学习汉语的热情不断增高,
但绝大多数人能够熟练掌握汉语。为了便于外 71. _____
国人检测自己的汉语水平,现成立国家大学汉
语四、六级考试委员会并设立着汉语四、六级 72. _____
考试。该考试将要参照英语四、六级考试的形 73. _____
式,各部分题型与其基本保持一致。考生报名
参加或通过者将授予证书,证书上贴有防伪标 74. _____
志,任何个人和单位不得仿冒,违者不究其法 75. _____
律责任。另外,考生报名需持本人无效证件, 76. _____
不得他人代报,更除此不得冒名顶替,发现有 77. _____
以上现象的,将取消其中考试成绩,并责令其 78. _____
回国,终身不得参加该项考试。该汉语考试将
于2005年开始,每年设立1月和6月两门考 79. _____
试,报名具体时间和注意事项请观赏我们的官 80. _____
方网站:www.cct4-6.com.cn请各位朋友互相
转告,谢谢。

(本大题共10分,一个1分)
第五部分:写作
说明向导:在这个部分,你将有三十分钟来写一篇题目为:汉语四、六级真好的作文。字数不可少于150字,你可以以下面的提示作为文章的主线:
1. The College Chinese Test is so good!
2. How nice the College Chinese Test is!

2008年5月14日星期三

【原创】2008,让我们燃起心中的圣火

2008,对中国是一个考验。

大雪无情,南方受灾,是什么让我们渡过难关?

举办奥运,圣火传递,是什么让圣火长传不灭?

反对**,维护统一,是什么让我们如此团结?

CNN辱华,国人奋慨,是什么支撑我们声讨起诉?

铁路事故,损失惨重,是什么让伤员找回生存的信心?

携着圣火,登顶朱峰,是什么让圣火闪耀在世界之巅?

是的,是排除万难的信念融化了冰雪,是保护圣火的信念驱走了传递途中的障碍,是维护统一的信念将我们拧在一起,是爱我中华的信念支撑起我们的尊严,是顽强生存的信念支撑铁路线上的伤员,是挑战极限的信念让圣火燃在世界之巅!

面对困难的纠缠,我们从不低头!

面对命运的挑战,我们拒绝失败!

面对如今的地震,我们怀着必胜的信念,将爱的信念一同点燃!

让这许许多多的信念,汇成中华民族一致的信念,让世界看到我们的信念之火在奥运精神的感召下,闪耀在人类文明之巅!

生命恒久远,信念永流传。

2008,让信念之圣火在每个人心中----点燃!

2008年5月4日星期日

[转]js frame 框架编程

1 框架编程概述
一个Html 页面可以有一个或多个子框架,这些子框架以<iframe>来标记,用来显示一
个独立的Html 页面。这里所讲的框架编程包括框架的自我控制以及框架之间的互相访问,
例如从一个框架中引用另一个框架中的JavaScript变量、调用其他框架内的函数、控制另一
个框架中表单的行为等。
2 框架间的互相引用
一个页面中的所有框架以集合的形式作为window 对象的属性提供,例如:
window.frames 就表示该页面内所有框架的集合,这和表单对象、链接对象、图片对象等是
类似的,不同的是,这些集合是document 的属性。因此,要引用一个子框架,可以使用如
下语法:
window.frames[“frameName”];
window.frames.frameName
window.frames[index]
其中,window字样也可以用self代替或省略,假设frameName 为页面中第一个框架,
则以下的写法是等价的:
self.frames[“frameName”]
self.frames[0]
frames[0]
frameName
了解了如何引用一个框架,那么引用的这个框架到底是什么呢?其实,每个框架都对应
一个HTML 页面,所以这个框架也是一个独立的浏览器窗口,它具有窗口的所有性质,所
谓对框架的引用也就是对window 对象的引用。有了这个window 对象,就可以很方便地对
其中的页面进行操作,例如使用window.document对象向页面写入数据、使用window.location
属性来改变框架内的页面等。
下面分别介绍不同层次框架间的互相引用:
2.1.父框架到子框架的引用
知道了上述原理,从父框架引用子框架变的非常容易,即:
window.frames[“frameName”];
这样就引用了页面内名为frameName 的子框架。如果要引用子框架内的子框架,根据
引用的框架实际就是window对象的性质,可以这样实现:
window.frames[“frameName”].frames[“frameName2”];
这样就很引用到了二级子框架,以此类推,可以实现多层框架的引用。
2.2.子框架到父框架的引用
每个window对象都有一个parent属性,表示它的父框架。如果该框架已经是顶层框架,
则window.parent 还表示该框架本身。
2.3.兄弟框架间的引用
如果两个框架同为一个框架的子框架,它们称为兄弟框架,可以通过父框架来实现互相
引用,例如一个页面包括2 个子框架:
<frameset rows="50%,50%">
<frame src="1.html" name="frame1" />
<frame src="2.html" name="frame2" />
</frameset>
在frame1 中可以使用如下语句来引用frame2:
self.parent.frames[“frame2”];
2.4.不同层次框架间的互相引用
框架的层次是针对顶层框架而言的。当层次不同时,只要知道自己所在的层次以及另一
个框架所在的层次和名字,利用框架引用的window对象性质,可以很容易地实现互相访问,
例如:
self.parent.frames[“childName”].frames[“targetFrameName”];
2.5.对顶层框架的引用
和parent 属性类似,window 对象还有一个top 属性。它表示对顶层框架的引用,这可
以用来判断一个框架自身是否为顶层框架,例如:
//判断本框架是否为顶层框架
if(self==top){
//dosomething
}
3 改变框架的载入页面
前面已经讲到,对框架的引用就是对window对象的引用,利用window对象的location
属性,可以改变框架的导航,例如:
window.frames[0].location=”1.html”;
这就将页面中第一个框架的页面重定向到1.html,利用这个性质,甚至可以使用一条链
接来更新多个框架。
<frameset rows="50%,50%">
<frame src="1.html" name="frame1" />
<frame src="2.html" name="frame2" />
</frameset>
<!--somecode-->
<a href=”frame1.location=’3.html;frame2.location=’4.html’” onclick=””>link</a>
<!--somecode-->
4 引用其他框架内的JavaScript变量和函数
在介绍引用其他框架内JavaScript变量和函数的技术之前,先来看以下代码:
<script language="JavaScript" type="text/javascript">
<!--
function hello(){
alert("hello,ajax!");
}
window.hello();
//-->
</script>
如果运行了这段代码,会弹出“hello,ajax!”的窗口,这正是执行hello()函数的结果。
那为什么hello()变成了window对象的方法呢?事实上,在一个页面内定义的所有全局变量
和全局函数都是作为window对象的成员。例如:
var a=1;
alert(window.a);
就会弹出对话框显示为1。同样的原理,在不同框架之间共享变量和函数,就是要通过
window对象来调用。
为了方便大家的理解,下面举例说明。一个商品浏览页面由两个子框架组成,左侧表示
商品分类的链接;当用户单击分类链接时,右侧显示相应的商品列表;用户可以单击商品旁
的【购买】链接将商品加入购物车。
在这个例子中,可以利用左侧导航页面来存储用户希望购买的商品,因为当用户单击导
航链接时,变化的是另外一个页面,即商品展示页面,而导航页面本身是不变的,因此其中
的JavaScript变量不会丢失,可以用来存储全局数据。其实现原理如下:
假设左侧页面为links.html,右侧页面为show.html,页面结构如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> New Document </title>
</head>
<frameset cols="20%,80%">
<frame src="link.html" name="link" />
<frame src="show.html" name="show" />
</frameset>
</html>
在show.html 中展示的商品旁边可以加入这样一条语句:
<a href=”void(0)” onclick=”self.parent.link.addToOrders(32068)”>加入购物车</a>
其中link表示导航框架,在link.html 页面中定义了arrOrders数组来存储商品的id,函
数addToOrders()用来响应商品旁边【购买】链接的单击事件,它接收的参数id 表示商品的
id,例子中是一个id为32068 的商品:
<script language="JavaScript" type="text/javascript">
<!--
var arrOrders=new Array();
function addToOrders(id){
arrOrders.push(id);
}
//-->
</script>
这样,在结帐页面或是购物车浏览页面就可以用arrOrders来获取所有准备购买的商品。
框架可以使一个页面划分为功能独立的多个模块,每个模块之间彼此独立,但又可以通
过window 对象的引用来建立联系,是web 开发中的一个重要机制。在Ajax 开发中,还可
以利用隐藏框架实现各种技巧,在后面介绍Ajax 实例编程时可以发现,无刷新上传文件以
及解决Ajax的前进后退问题都会用到这种技术。
以上内容来自《征服AJAX》

2008年4月30日星期三

解决Ajax与数据库数据变动同步问题

[以下是转文]
Ajax从数据库里读取数据不能及时更新,这是因为浏览器的缓存机制。本文提出了四种解决办法。

以下是引用片段:

  在电信做的小灵通短信订餐系统中,有几个页面要用到三级联动下拉框,为了使用户体验更好,使服务器缓解一定压力,我决定使用AJAX来完成这个功能,可是我却粗心大意,漏掉了一个环节,使得ajax从数据库里读取数据不能及时更新.这是因为浏览器的缓存机制.

  有4种方法可以解决这个问题:

  1.在请求的URL后面加一个时间参数,如:

time=new date()

        当然也可以添加其他性质参数,只要是随机参数就可以,

open("GET",url+"?t="+Math.random(),false)

       或者

url+"?timeStamp="+new Date().getTime();

  2.

  js 代码

function ajaxRead(file){

var xmlObj = null;

if(window.XMLHttpRequest){

xmlObj = new XMLHttpRequest();

} else if(window.ActiveXObject){

xmlObj = new ActiveXObject("Microsoft.XMLHTTP");

} else {

return;

} 

xmlObj.onreadystatechange = function(){

if(xmlObj.readyState == 4){

processXML(xmlObj.responseXML);

}

else{

document.getElementById ('playernews').innerHTML='采用AJAX来实现数据的读取,正在加载...';

}

}

xmlObj.open ('GET', file, true);

xmlObj.send ('');

}

function show() {

ajaxRead('*.jsp');

setInterval("ajaxRead('new.php')",30000); //自动更新

}

  3.加上

xmlhttp.setRequestHeader("Cache-Control","no-cache");

  4.在XmlHttpRequest发送请求之前加上

XmlHttpRequest.setRequestHeader("If-Modified-Since","0"),

       如:在

XXXXX.send(YYYYYY).

[以下是本人注释]

在使用prototype.js的时候,如果想使用方法3和4,需要这样写:

var myAjax = new Ajax.Request(
        request_url,
        {
            method:'get',
            requestHeaders: ['Cache-Control','no-cache','If-Modified-Since','0'],
            parameters:request_pars,
            asynchronous:true,       //true---异步;false---同步.默认为true
            onComplete:processRequest
        }    
    );

注意红色的代码部分,你可能注意到这是把3、4两种方法结合起来使用的。。。

好了,如果你是使用json的话,这个方法一样好用。

2008年4月29日星期二

在Java中解析与构造JSON[转]

www.json.org上公布了很多Java下的json解析工具,其中org.json和json-lib比较简单,两者使用上差不多。下面两段源代码是分别使用这两个工具解析和构造JSON的演示程序。

http://nchc.dl.sourceforge.net/sourceforge/json-lib/json-lib-2.2.1-jdk15.jar
(Needs libs below:)
[

  • jakarta commons-lang 2.3
  • jakarta commons-beanutils 1.7.0
  • jakarta commons-collections 3.2
  • jakarta commons-logging 1.1
  • ezmorph 1.0.4

]
这是使用json-lib的程序:
import java.util.HashMap;
import java.util.Map;
import net.sf.json.JSONObject;
public class Test {
     public static void main(String[] args) {
         String json = "{\"name\":\"reiz\"}";
         JSONObject jsonObj = JSONObject.fromObject(json);
         String name = jsonObj.getString("name");
         jsonObj.put("initial", name.substring(0, 1).toUpperCase());
         String[] likes = new String[] { "JavaScript", "Skiing", "Apple Pie" };
         jsonObj.put("likes", likes);
         Map <String, String> ingredients = new HashMap <String, String>();
         ingredients.put("apples", "3kg");
         ingredients.put("sugar", "1kg");
         ingredients.put("pastry", "2.4kg");
         ingredients.put("bestEaten", "outdoors");
         jsonObj.put("ingredients",ingredients);
         System.out.println(jsonObj);
     }
}

http://www.json.org/java/json.zip
这是使用org.json的程序:
import java.util.HashMap;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
public class Test {
     public static void main(String[] args) throws JSONException {
         String json = "{\"name\":\"reiz\"}";
         JSONObject jsonObj = new JSONObject(json);
         String name = jsonObj.getString("name");
         jsonObj.put("initial", name.substring(0, 1).toUpperCase());
         String[] likes = new String[] { "JavaScript", "Skiing", "Apple Pie" };
         jsonObj.put("likes", likes);
         Map <String, String> ingredients = new HashMap <String, String>();
         ingredients.put("apples", "3kg");
         ingredients.put("sugar", "1kg");
         ingredients.put("pastry", "2.4kg");
         ingredients.put("bestEaten", "outdoors");
         jsonObj.put("ingredients", ingredients);
         System.out.println(jsonObj);
         System.out.println(jsonObj);
     }
}
两者的使用几乎是相同的,但org.json比json-lib要轻量得多,前者没有任何依赖,而后者要依赖ezmorph和commons的lang、logging、beanutils、collections等组件。

javascript解析json[转]

JSON (JavaScript Object Notation)一种简单的数据格式,比xml更轻巧。 JSON 是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON 数据不需要任何特殊的 API 或工具包。

JSON的规则很简单: 对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。具体细节参考http://www.json.org/json-zh.html

举个简单的例子:

js 代码

  1. function showJSON() {   
  2. var user =   
  3.      {   
  4. "username":"andy",   
  5. "age":20,   
  6. "info": { "tel": "123456", "cellphone": "98765"},   
  7. "address":   
  8.              [   
  9.                  {"city":"beijing","postcode":"222333"},   
  10.                  {"city":"newyork","postcode":"555666"}   
  11.              ]   
  12.      }   
  13.      alert(user.username);   
  14.      alert(user.age);   
  15.      alert(user.info.cellphone);   
  16.      alert(user.address[0].city);   
  17.      alert(user.address[0].postcode);   
  18. }  

这表示一个user对象,拥有username, age, info, address 等属性。

同样也可以用JSON来简单的修改数据,修改上面的例子

js 代码

  1. function showJSON() {   
  2. var user =   
  3.      {   
  4. "username":"andy",   
  5. "age":20,   
  6. "info": { "tel": "123456", "cellphone": "98765"},   
  7. "address":   
  8.              [   
  9.                  {"city":"beijing","postcode":"222333"},   
  10.                  {"city":"newyork","postcode":"555666"}   
  11.              ]   
  12.      }   
  13.      alert(user.username);   
  14.      alert(user.age);   
  15.      alert(user.info.cellphone);   
  16.      alert(user.address[0].city);   
  17.      alert(user.address[0].postcode);   
  18.      user.username = "Tom";   
  19.      alert(user.username);   
  20. }  

JSON提供了json.js包,下载http://www.json.org/json.js 后,将其引入然后就可以简单的使用object.toJSONString()转换成JSON数据。

js 代码

  1. function showCar() {   
  2. var carr = new Car("Dodge", "Coronet R/T", 1968, "yellow");   
  3.      alert(carr.toJSONString());   
  4. }   
  5. function Car(make, model, year, color)        {   
  6. this.make   =   make;   
  7. this.model   =   model;   
  8. this.year   =   year;   
  9. this.color   =   color;   
  10. }  

可以使用eval来转换JSON字符到Object

js 代码

  1. function myEval() {   
  2. var str = '{ "name": "Violet", "occupation": "character" }';   
  3. var obj = eval('(' + str + ')');   
  4.      alert(obj.toJSONString());   
  5. }  

或者使用parseJSON()方法

js 代码

  1. function myEval() {   
  2. var str = '{ "name": "Violet", "occupation": "character" }';   
  3. var obj = str.parseJSON();   
  4.      alert(obj.toJSONString());   
  5. }  

下面使用prototype写一个JSON的ajax例子。

先写一个servlet (我的是servlet.ajax.JSONTest1.java)就写一句话

java 代码

  1. response.getWriter().print("{ \"name\": \"Violet\", \"occupation\": \"character\" }"); 

再在页面中写一个ajax的请求

js 代码

  1. function sendRequest() {   
  2. var url = "/MyWebApp/JSONTest1";   
  3. var mailAjax = new Ajax.Request(   
  4.          url,   
  5.          {   
  6.              method: 'get',   
  7.              onComplete: jsonResponse   
  8.          }   
  9.      );   
  10. }   
  11. function jsonResponse(originalRequest) {   
  12.      alert(originalRequest.responseText);   
  13. var myobj = originalRequest.responseText.parseJSON();   
  14.      alert(myobj.name);   
  15. }  

prototype-1.5.1.js中提供了JSON的方法,String.evalJSON(), 可以不使用json.js, 修改上面的方法

js 代码

  1. function jsonResponse(originalRequest) {   
  2.      alert(originalRequest.responseText);   
  3. var myobj = originalRequest.responseText.evalJSON(true);   
  4.      alert(myobj.name);   
  5. }  

JSON还提供了java的jar包 http://www.json.org/java/index.html API也很简单,下面举个例子

在javascript中填加请求参数

js 代码

  1. function sendRequest() {   
  2. var carr = new Car("Dodge", "Coronet R/T", 1968, "yellow");   
  3. var pars = "car=" + carr.toJSONString();   
  4. var url = "/MyWebApp/JSONTest1";   
  5. var mailAjax = new Ajax.Request(   
  6.          url,   
  7.          {   
  8.              method: 'get',   
  9.              parameters: pars,   
  10.              onComplete: jsonResponse   
  11.          }   
  12.      );   
  13. }  

使用JSON请求字符串就可以简单的生成JSONObject并进行解析,修改servlet添加JSON的处理(要使用json.jar)

java 代码

  1. private void doService(HttpServletRequest request, HttpServletResponse response) throws IOException {   
  2.          String s3 = request.getParameter("car");   
  3. try {   
  4. JSONObject jsonObj = new JSONObject(s3);   
  5.              System.out.println(jsonObj.getString("model"));   
  6.              System.out.println(jsonObj.getInt("year"));   
  7.          } catch (JSONException e) {   
  8.              e.printStackTrace();   
  9.          }   
  10.          response.getWriter().print("{ \"name\": \"Violet\", \"occupation\": \"character\" }");   
  11.      }  

同样可以使用JSONObject生成JSON字符串,修改servlet

java 代码

  1. private void doService(HttpServletRequest request, HttpServletResponse response) throws IOException {   
  2.          String s3 = request.getParameter("car");   
  3. try {   
  4. JSONObject jsonObj = new JSONObject(s3);   
  5.              System.out.println(jsonObj.getString("model"));   
  6.              System.out.println(jsonObj.getInt("year"));   
  7.          } catch (JSONException e) {   
  8.              e.printStackTrace();   
  9.          }   
  10. JSONObject resultJSON = new JSONObject();   
  11. try {   
  12.              resultJSON.append("name", "Violet")   
  13.                        .append("occupation", "developer")   
  14.                        .append("age", new Integer(22));   
  15.              System.out.println(resultJSON.toString());   
  16.          } catch (JSONException e) {   
  17.              e.printStackTrace();   
  18.          }   
  19.          response.getWriter().print(resultJSON.toString());   
  20.      }  

js 代码

  1. function jsonResponse(originalRequest) {   
  2.      alert(originalRequest.responseText);   
  3. var myobj = originalRequest.responseText.evalJSON(true);   
  4.      alert(myobj.name);   
  5.      alert(myobj.age);   

参考

http://www.json.org/js.html

http://www.blogjava.net/Jkallen/archive/2006/03/28/37905.html

http://www.json.org/

http://www.prototypejs.org/learn/json

http://www.json.org/java/index.html

http://www.ibm.com/developerworks/cn/web/wa-ajaxintro10/index.html

使用JSON
JSON也就是JavaScript Object Notation,是一个描述数据的轻量级语法。JSON的优雅是因为它是JavaScript语言的一个子集。接下来你将看到它为什么如此重要。首先,来比较一下JSON和XML语法。

JSON和XML都使用结构化方法描述数据。例如一个地址簿应用程序可以提供用来产生XML格式的地址卡的web服务:
<?xml version='1.0' encoding='UTF-8'?>
<card>
   <fullname>Sean Kelly</fullname>
   <org>SK Consulting</org>
   <emailaddrs>
      <address type='work'>kelly@seankelly.biz</address>
      <address type='home' pref='1'>kelly@seankelly.tv</address>
   </emailaddrs>
   <telephones>
      <tel type='work' pref='1'>+1 214 555 1212</tel>
      <tel type='fax'>+1 214 555 1213</tel>
      <tel type='mobile'>+1 214 555 1214</tel>
   </telephones>
   <addresses>
      <address type='work' format='us'>1234 Main St
         Springfield, TX 78080-1216</address>
      <address type='home' format='us'>5678 Main St
         Springfield, TX 78080-1316</address>
   </addresses>
   <urls>
      <address type='work'>http://seankelly.biz/</address>
      <address type='home'>http://seankelly.tv/</address>
   </urls>
</card>

使用JSON, 形式如下:

{
   "fullname": "Sean Kelly",
   "org": "SK Consulting",
   "emailaddrs": [
      {"type": "work", "value": "kelly@seankelly.biz"},
      {"type": "home", "pref": 1, "value": "kelly@seankelly.tv"}
   ],
    "telephones": [
      {"type": "work", "pref": 1, "value": "+1 214 555 1212"},
      {"type": "fax", "value": "+1 214 555 1213"},
      {"type": "mobile", "value": "+1 214 555 1214"}
   ],
   "addresses": [
      {"type": "work", "format": "us",
       "value": "1234 Main StnSpringfield, TX 78080-1216"},
      {"type": "home", "format": "us",
       "value": "5678 Main StnSpringfield, TX 78080-1316"}
   ],
    "urls": [
      {"type": "work", "value": "http://seankelly.biz/"},
      {"type": "home", "value": "http://seankelly.tv/"}
   ]
}

如你所看到的,JSON有结构化的嵌套数据元素,这一点和XML相似。JSON也是基于文本的,XML也是如此。两者都使用Unicode。JSON和XML都很容易阅读。主观上,JSON更清晰,冗余更少。JSON WEB站点严格地描述了JSON语法,目前就是这样的。它确实是一个简单的小语言! XML确实适合标记文档,但是JSON是数据交互的理想格式。每个JSON文档描述了一个这样一个对象,该对象包含有:嵌套对象、数组、字符串、数字、布尔值或空值。

在这些地址卡例子代码中,JSON版本是更轻量级的,只占用了682字节的空间,而XML版本需要744字节空间。尽管这不是一个可观的节省。而实际的好处则来自解析过程。

XML对比JSON:地位丧失
通过使用XMLHttpRequest对象,可以从你的基于AJAX的应用程序取得XML和JSON文件。典型的,交互代码如下:

var req = new XMLHttpRequest();
req.open("GET", "http://localhost/addr?cardID=32", /*async*/true);
req.onreadystatechange = myHandler;
req.send(/*no params*/null);
作为WEB服务器响应,你提供的处理器函数(myHandler函数)被多次调用,为你提供提前终止事务,更新进度条等机会。通常的,只有在web请求完成以后才起作用:那时,你就可以使用返回的数据了。

为了处理XML版本的地址卡数据,myHandler的代码如下:

function myHandler() {
   if (req.readyState == 4 /*complete*/) {
       // Update address field in a form with first street address
       var addrField   = document.getElementById('addr');
       var root        = req.responseXML;
       var addrsElem   = root.getElementsByTagName('addresses')[0];
       var firstAddr   = addrsElem.getElementsByTagName('address')[0];
       var addrText    = fistAddr.firstChild;
       var addrValue   = addrText.nodeValue;
       addrField.value = addrValue;
   }
}
值得注意的是你不必解析XML文档:XMLHttpRequest对象自动地解析了,并使responseXML中的DOM树可用。通过使用responseXML属性,可以调用getElementsByTagName方法查找文档的地址部分,你还可以使用第一个去找到它。然后,可以再次调用getElementsByTagName在地址部分查找第一个地址元素。这就取得了文档的第一个DOM子节点,就是一个文本节点,并取得节点的值,这就是你想要的街道地址。最后,可以在表单域中显示结果。

确实不是一个简单的工作,现在,使用JSON再试一下:
function myHandler() {
   if (req.readyState == 4 /*complete*/) {
       var addrField = document.getElementById('addr');
       var card = eval('(' + req.responseText + ')');
       addrField.value = card.addresses[0].value;
   }
}
你所做的第一件事情就是解析JSON响应。但是,因为JSON是JavaScript的一个子集,你可以使用JavaScript自己的编译器来解析它,通过调用eval函数。解析JSON仅需要一行!此外,操纵JSON中的对象就像操纵其他JavaScript对象一样。这显然要比通过DOM树来操纵简单,例如:
card.addresses[0].value 是第一个街道地址, "1234 Main Stb &"
card.addresses[0].type 是地址类型, "work"
card.addresses[1] 是家庭地址对象
card.fullname 是card的名称, "Sean Kelly"
如果更仔细观察,你可能会发现XML格式中文档至少有一个跟元素,card。这在JSON里是不存在的,为什么? 大概就是,如果你正在开发JavaScript来访问Web服务,你已经知道你想要得到的。然而,你可以在JSON中这么使用:
{"card": {"fullname": ...}}
使用这个技术,你的JSON文件总是以一个带有单一命名属性的对象开始,该属性标识了对象的种类。

JSON是快速可靠的吗?
JSON提供轻量的小文档,并且JSON在JavaScript更容易使用。XMLHttpRequest自动为你解析了XML文档,而你还要手工解析JSON文件,但是解析JSON比解析XML更慢么?作者通过几千次的反复测试,使用XMLHttpRequest解析XML和解析JSON,结果是解析JSON比XML要快10倍!当把AJAX当作桌面应用看待时,速度是最重要的因素,很明显,JSON更优秀。

当然,你不能总是控制服务器端来为AJAX程序产生数据。你还可以使用第三方服务器代替服务器提供XML格式的输出。并且,如果服务器恰好提供JSON,你可以确定你真的想使用它吗?

代码中值得注意的是,你将响应文本直接传入到eval中。如果你控制着服务器,就可以这么做。如果不是,一个恶意服务器可以使你的浏览器执行危险操作。在这样的情况下,你最好使用写在JavaScript中的代码来解析JSON。幸运地,这已经有了。

说到解析,Python爱好者可能注意到JSON不只是JavaScript的子集,它还是Python的一个子集。你可以在Python中直接执行JSON,或者使用安全JSON解析代替。JSON.org网站列举了许多常用JSON解析器。

服务器端的JSON
到现在为止,你或许将焦点注意在运行在客户浏览器中的基于AJAX的web应用程序使用JSON。自然地,首先,JSON格式的数据必须在服务器端产生。幸运地是,创建JSON或将其他存在的数据转换成JSON是相当简单的。一些WEB应用程序框架,例如TurboGears,自动包括对JSON输出的支持。

此外商业WEB服务提供商也注意到了JSON。Yahoo最近创建了许多基于JSON的web服务。Yahoo的多种搜索服务,履行计划,del.icio.us,还有高速公路交通服务也都支持JSON输出。毫无疑问,其他主要WEB服务提供商也将加入到对JSON的支持中。

总结
JSON的聪明在于它是JavaScript和Python的子集,使得它更易用,为AJAX提供高效的数据交互。它解析更快,比XML更易使用。JSON正成为现在“Web 2.0”的最强音。每个开发者,无论是标准桌面应用程序或Web应用程序,越来越注意到了它的简单和便捷。我希望你能体会到在buzzword-compliant, Web-2.0-based, AJAX-enabled, 敏捷开发中应用到JSON的乐趣。

2008年4月24日星期四

Struts2教程1-6 & Java6 Update10

感谢原作者的努力,struts1.x用的熟练的朋友可以很快上手Struts2

下面只粘贴六篇的链接地址。

第一篇|第二篇|第三篇|第四篇|第五篇|第六篇

另外,听说JDK1.6要出Update10了,通常这种Update Release是不会对核心的公共API做出修改的。这次Update虽然也没有修改公共API,但是新增了许多细节,并且更改了JRE的分发方式,支持按需获取不同大小的JRE,从而使得Java程序更轻快的运行在各种系统中。

有关此次更新的官网链接:

Introducing Java SE 6 update 10 Beta

看来JavaFX有望成为Java技术带来的下一个经济增长点。

各类开源协议介绍

Mozilla Public License


  MPL License,允许免费重发布、免费修改,但要求修改后的代码版权归软件的发起者。这种授权维护了商业软件的利益,,它要求基于这种软件得修改无偿贡献版权给该软件。这样,围绕该软件得所有代码得版权都集中在发起开发人得手中。但MPL是允许修改,无偿使用得。MPL软件对链接没有要求。


  BSD开源协议


  BSD开源协议是一个给于使用者很大自由的协议。可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布。 当你发布使用了BSD协议的代码,或则以BSD协议代码为基础做二次开发自己的产品时,需要满足三个条件:
  1. 如果再发布的产品中包含源代码,则在源代码中必须带有原来代码中的BSD协议。
  2. 如果再发布的只是二进制类库/软件,则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。
  3. 不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。
  BSD代码鼓励代码共享,但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码,也允许使用或在BSD代码上开发商业软件发布和销售,因此是对商业集成很友好的协议。而很多的公司企业在选用开源产品的时候都首选BSD协议,因为可以完全控制这些第三方的代码,在必要的时候可以修改或者二次开发。


  Apache Licence 2.0


  Apache Licence是著名的非盈利开源组织Apache采用的协议。该协议和BSD类似,同样鼓励代码共享和尊重原作者的著作权,同样允许代码修改,再发布(作为开源或商业软件)。需要满足的条件:
  1. 需要给代码的用户一份Apache Licence
  2. 如果你修改了代码,需要再被修改的文件中说明。
  3. 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议,商标,专利声明和其他原来作者规定需要包含的说明。
  4. 如果再发布的产品中包含一个Notice文件,则在Notice文件中需要带有Apache Licence。你可以在Notice中增加自己的许可,但不可以表现为对Apache Licence构成更改。
  Apache Licence也是对商业应用友好的许可。使用者也可以在需要的时候修改代码来满足需要并作为开源或商业产品发布/销售。

GPL


  GPL许可证是自由软件的应用最广泛的软件许可证,人们可以修改程式的一个或几个副本或程式的任何部分,以此形成基於这些程式的衍生作品。必须在修改过的档案中附有明显的说明:您修改了此一档案及任何修改的日期。您必须让您发布或出版的作品,包括本程式的全部或一部分,或内含本程式的全部或部分所衍生的作品,允许第三方在此许可证条款下使用,并且不得因为此项授权行为而收费。


  LGPL


  Linux就是采用了GPL。GPL协议和BSD, Apache Licence等鼓励代码重用的许可很不一样。GPL的出发点是代码的开源/免费使用和引用/修改/衍生代码的开源/免费使用,但不允许修改后和衍生的代码做为闭源的商业软件发布和销售。这也就是为什么我们能用免费的各种linux,包括商业公司的linux和linux上各种各样的由个人,组织,以及商业软件公司开发的免费软件了。
  GPL协议的主要内容是只要在一个软件中使用(“使用”指类库引用,修改后的代码或者衍生代码)GPL协议的产品,则该软件产品必须也采用 GPL协议,既必须也是开源和免费。这就是所谓的”传染性”。GPL协议的产品作为一个单独的产品使用没有任何问题,还可以享受免费的优势。
  由于GPL严格要求使用了GPL类库的软件产品必须使用GPL协议,对于使用GPL协议的开源代码,商业软件或者对代码有保密要求的部门就不适合集成/采用作为类库和二次开发的基础。
  其它细节如再发布的时候需要伴随GPL协议等和BSD/Apache等类似


  Public Domain


  公共域授权。将软件授权为公共域,这些软件包没有授权协议,任何人都可以随意使用它。


  Artistic许可


  使作者保持对进一步开发的控制。