??xml version="1.0" encoding="utf-8" standalone="yes"?>
原文作者:tombkeeper[0x40]xfocus.org
创徏旉Q?005.06.01 21:00
[本文严禁转蝲]
Nokia 今年新出的机器中Q要数这?230w材比较好。苗条而不U细Q匀U又玲珑有致?600是因ؓw材差,而被人称之ؓ“肥6”,q也是我坚决不买 6600的原因?230出来之后Qh们很快就把原?650的“小3”这个昵U给?230。“从来只见新人笑”这个道理由此可见一斑?/font>
我周一Q就是北京下雹子砸死了牛的那个周一Q晚上跑到西单,C一部回来?/font>
下面本来是一份自己写l自q的备忘录性质的文档,没想到越写越多,p虑应该׃n出来Q也许对别h有用。这q不是一份Symbian手机入门教程Q所以里面不会涉及“如何安装Y件”这L知识。另外,如果你凑巧看Cq䆾文档Qƈ打算按照里面说的做,那么一定要明白Q这里面的内容可能给你带来帮助,也可能带来困扰和ȝQ痛苦和不幸。所以我q不鼓励或者暗CZ按照本文所q的内容q行M实际操作Q也不对q䆾文档可能D的Q何后果负责。如果你依照自己的意愿对手机q行了某些操作,D无法正常使用Q请致电Nokia客服Q?008800123?/font>
q䆾文档中大多数内容也适用?600/6670/7610{Nokia的Symbian 70机型?/font>
1、买水货q是买行货?
我从来就不反对买水货。不q要衡量的是Q买水货省下来的钱和增加的风险成本相比哪一个更高。我的IBM T30l修q两ơ,W一ơ是因ؓ我把USB鼠标插到|口里,D换了一块主板,W二ơ是换了个CPU风扇。如果要花钱l修的话Q估计不在少数。不q手机和W记本相比较更加不容易坏Q买水货而增加的风险成本也小一些。如果是一个对手机很了解的人,完全可以考虑买水货?/font>
买水货,主要是注意机器的外壳有无划痕Q屏q内部有无灰。水货机器大多是在没有包装的情况下夹带进来的Q这斚w很容易出问题?/font>
买行货,主要是注意机器按键的手感。有时候个别按键需要格外用力才能按下去Q或者感觉比较YQ但又不是失c因不属于故障,所以一旦开之后是不可能更换的?/font>
3230配了xQ买的时候一定要试好。xq类配g一般都是委托其他厂家生产的Q质量控制不会有Nokia自己那么严格?/font>
和其它基于S60的手ZP下面q些控制码对3230都有效:
*#7370# 重|系l(俗称“格机”)
A、把旉调整?003q?月之前,譬如?003q?月?br />B、删?C:SystemDataapplications.dat ?C:SystemDataNITZ.dat?br />C、注册?br />D、把pȝ旉调回正常?/font>
3230作ؓ新出的机型,在红外兼Ҏ上q有一些问题,只能{以后升U系l。作为替代的解决ҎQ可以用蓝牙来进行文件传输?230的蓝牙性能不错?/font>
3230只支持单声道播放音乐Q至内|的RealPlayer只能以单声道播放音乐Q而且韌q不好。那些认Z?230可以丢掉MP3的h要失望了?/font>
如果惌求更好的多媒体表玎ͼ推荐购买Moto e680i。h格比3230略高Q但是有320×240的屏q分辨率Q回N质不逊于专业MP3播放器,而且q支持立体声蓝牙xQMoto其UC为“n乐PDA”不是没道理的?/font>
3230的FM攉机是立体声的Q音质不错,臛_比大多数袖珍FM攉机都要好。可以用中文存储20个频道名Uͼ也就是说Q设定好之后Q只要点一下“北京文艺台”,׃自动收听87.6兆赫?/font>
3230 自带了一个音质不错的扬声器,在广播的时候可以选择用扬声器或者x。但是如果x不插在手ZQ是不能启动攉机功能的Q因借xU当天线用。信号好的时候,天线q不一定是必需的,所以我认ؓ来一定会有h写程序解除这一限制Q甚臛_能Nokia׃在下一版本中去除限制——如果限制是在Y仉做的话?/font>
下面是北京地区部分电台的频率Q?/font>
87.6 北京人民q播电台文艺?br />88.2 中国国际q播电台EasyFM
q个不好一概而论Q一个h一天能Ud多远Q得取决于他用什么交通工P手机甉|能用多长旉Q得取决于怎么用?230的电池是BL-5BQ比7650?BLB-2了60 mAHQ但是我个h感觉3230充满늚使用旉臛_要比7650?0%~30%——当然也可能是我的错觉?/font>
作ؓ一个手机来_拍照效果相当不错。镜头畸变不大,拍摄出的1280×960的图片如果羃至1024×768Q几乎可以拿来当桌面。事实上QNokia 手机的拍照效果一直都很好Q我曄用同?0万像素的7650和Dopod 535做比较。结?650的镜头畸变、色彩还原、白q都占了上风。尤其是白^衡和色彩q原Qdopod 535的表现只能用“惨”来形容?/font>
3230拍照功能比较大的毛病是gq比较长Q超q一U钟。也是_照片记录的是按下快门一U钟后的事情。可能是因ؓCPUq算能力不D的?/font>
自带的摄像Y件只能拍摄最大分辨率176×144的媄像。作Z个支持存储卡的机器来_q是很失败的。当Ӟ也可能是因ؓ3230的CPU处理不了更大q的视频?/font>
不错。系l自带游戏和存储卡中的几ƾ游戏画面和可玩性都很好。尤其是自带的Agent VQ一定要体验一下才知道什么叫新概c我曄用语a向几个朋友描qCq个游戏Q可是他们看到实际的情Ş时还是很震撼?/font>
Nokiaq没有把3230设计成能自己换壳的机器,自然也没有壳可换。但随着3230量的增加Q一定会有第三方厂家生相应的彩壛_来。不q你可能需要一把T5的内六角Z刀?/font>
可以?230支持POP和IMAP协议的邮。另外,3230q提供了对SSL/TLS/APOP加密协议的支持。我?230可以成功收发l过SSL加密的Gmail邮g?/font>
可以。但是和7650不同的是Q?230的红外口在机器的右侧面而不是顶端,所以ƈ不适合作ؓ遥控器来用?/font>
可以?230支持RS-MMC卡。RS-MMC是Nokia自己力推的一U标准。这U卡只有通常MMC卡的一半大,q且兼容MMC?/font>
3230支持热插拔RS-MMC。“存储卡”这个应用程序里有“取出存储卡”的按钮Q按下ƈ认后,像于在Windows的“安全删除硬件”里删除一个U盘一栗机器的后盖打开Q一个小按钮随之村ּQ会执行上述同样的操作?/font>
我致电Nokia客服Q问她们3230最多支持多大的卡,她们是这么说的:Nokia自己只生产最?28M的卡Qƈ且Nokia不推荐用第三方的卡。我又重复了我的问题Q说我想知道机器本n设计支持多大的卡。她们则又重复了刚才的回{。我W三ơ提出问题,q强调我问的是机器本w支持多大的卡,而不?Nokia生多大的卡Q她们则忠实地将刚才的回{又作了一侉K复?/font>
从第三方渠道得到的消息是3230最大支? G的RS-MMC卡。我?90C一张KingMax 256M的卡Q在3230上可以很正常C用。o我吃惊的是格式化非常快,只用了不?0U钟的时间。以前听别h_格式化一张卡臛_需要数分钟?/font>
C新卡之后Q原配的32M卡可以留着用来备䆾一些重要的个h信息?/font>
Ҏ我的实验Q超q三分之二的7650/3650软g可以?230上正常运行。通常来说Q和g没什么关pȝ——譬如说看图、看书的软gQ基本都可以q行Q而和g关系比较大的软gQ譬如拍照Y件、来电防火墙软gQ则通常都不能正常工作?/font>
不过很多软g已经推出了针?230{新ƾ手机的升版本。在未来三个月内Q我们想用的大部分Y件应该都可以扑ֈ?/font>
能在6600/6670/7610上运行的软g基本都可以正常工作于3230?/font>
很不错?230用了65535色的TFT屏,色彩和对比度都不错。屏q亮度也很高Q以至于我要把亮度调?0%才不觉得刺眼?/font>
腾讯在qq.com上提供了Symbian版本的QQ客户端,不过q没有针?230的,下面q个链接中的文g是针?650/3650的,l我试Q工作正常:
不过我觉得,针对6600/6670/7610的版本应该也可以使用Q而且应该更兼容一些,毕竟它们?230都是ZSymbian 7的机器,?650/3650是Symbian 6Q?br />
http://mgame.qq.com/mqq/qq_6600.SIS
以前版本的Agile Messenger{MSN客户端在3230上都不能正常使用Q最新的Turbo MSN 1.9已经可以很好地在3230上运行?/font>
是的。也许是Nokia想给写闹铃Y件的公司留点生存空_q个?650时代p病的问题一直保持了下来。不q现在可以自定义闚w所使用的铃C。另外,我发现World Clock Pro?230上不能调铃声大小Q好在默认的声音_响了?/font>
技巧:如果你不想仅仅ؓ了能多定义几个闹铃就额外安装一个闹铃Y件的话,可以?230的“日历”中建立带闹铃的U会提醒Q而且可以讑֮闚w音乐Q设定每天、每周、每月还是每q提醒一ơ?/font>
令h吃惊的是Q现在我们竟然可以在Symbian上运行PythonQ?br />
http://www.forum.nokia.com/main/0,,034-821,00.html
是的Q这是个p糕的问题。我仔细看了一下,应该是屏q下方的密封L不够厚导致的。我已经CT5的内六角Z刀Q准备自己来除尘q加厚这块vl了?/font>
可以Q你需要下载Nokia PC套gQ?br />
http://nds2.nokia.com/files/support/china/phones/software/Nokia_PC_Suite_641_zh_sc.exe
如果你很q运Q认识另一个有3230手机的hQ可以从他那里拷贝一份。要不然Q就得去找Nokia的客服,我想q个服务应该是免费的?/font>
比较奇怪的是,3230只提供了一些DEMO软g的下载,而没有正式的软g下蝲面Q不q这没关p,7610?681{S60机器的YӞ3230基本都可以用Q?/font>
http://www.nokia.com.cn/cn/support/phones/models/n7610/downloads/downloads_game.shtml
注意Q?681的那个“音乐播攑֙”虽好,但是3230用不了。因?681的MP3解码是硬件实现的?/font>
我个得下面这些Y件还不错Q?/font>
掌上图书Q?br />
http://nds2.nokia.com/files/support/china/phones/software/ebook_6600.SIS
掌上图书PC端YӞ
查号_Q?br />
http://nds2.nokia.com//files/support/china/phones/software/Vois_2011.sis
Quick WordQ?br />
http://nds2.nokia.com/files/support/china/phones/software/Lara_MMC_Quickword_China_china.SIS
Quick PointQ?br />
http://nds2.nokia.com/files/support/china/phones/software/Lara_MMC_Quickpoint_China_china.SIS
Quick SheetQ?br />
http://nds2.nokia.com/files/support/china/phones/software/Lara_MMC_Quicksheet_China_china.SIS
Quick OfficeQ包含上qC个YӞQ?br />
http://nds2.nokia.com/files/support/china/phones/software/Quickoffice.SIS
3230刚出来的时候,有h写文章论q?230的几大缺点,其中一个罪状就是没有“锁屏键”。Nokia的老用户都知道Q所有的Nokia直板手机都是先按认键再?锁屏,再次同样操作开锁?/font>
ARM4TQ主?23MHz。我认ؓ对于一个要处理1280×960大小囄的机器来_200MHz是比较恰当的——虽然会多耗费一些电力?/font>
q是一个误解。如果Nokia的研发h员会犯这U愚蠢错误,如果Nokia的QC部门q这U愚蠢错误都查不出来Q那我们׃会知道Nokiaq个名字了?/font>
很多为在情景模式中关铃声的方法就是将“铃声类型”设|ؓ“无声”。这都是被“铃声类型”这个中文翻译给误导的。这里的英文原文是“Ringing Type”。“Ringing”不应理解ؓ名词“铃声”,而应该是Ring的进行时或者是动名词。“Ringing Type”正的译是“响铃类型”。也是_讄的是来电提示Q包括铃声和震动Q按照什么方式工作?/font>
如果讄为“连l响铃”,意味着所讄的来甉|C(包括铃声和震动)都会被@环触发;如果讄为“无声”,自然是连铃声带震动都没有了?/font>
如果要设|一个没有铃C是有震动的情景模式,只需在“来电铃声”中选择“关”,“铃声类型”设|ؓ“连l响铃”即可?/font>
没事q多打客服电?008800123Q把那些问题反复向客服反映。最后这些意见会被统计,如果有很多hơ的反映Q那么就会优先被考虑解决?/font>
Nokia手机以型LW一个数字来划分pdQ?230是?”系列,代表h独特功能Q外观比较奇怪,有特别强化功能的机器。家族成员有3650?300?200{?/font>
S60 是Series60的羃写,不是Symbian 6.0的羃写。Series60指的是手机的操作界面。相应的q有Series40Q?230i{机型)、Series80 Q?210/9300/9500{?pd机型Q。除3230之外Q?650/3650/6600/6670/7610{机型用的也是Series60的界面?/font>
诺基亚客h务网Ҏ询:
http://www1.nokia.com.cn/carecenter
下面是北京的服务点:
名称 地址 电话
诺基亚专卖店客户服务?西城区后半壁?6P西直门商业大?层) 010-66110268 So far, we have looked at the JavaScript to do the AJAX call (listed above) and the Struts
By adding the above JavaScript code to our application, the following steps now happen on the server and on the browser. The JavaScript outlined above can cope with the way Struts is used in most applications, including those that are much more complex than our simple example. However, you may find that following the points below makes it easier to write and use your code: An updated version of this project, with AJAX enabled, can be downloaded here: struts-Ajax.zip AJAX techniques promise to completely revolutionize how we build and use web applications. This article showed a simple technique to add AJAX behavior to existing Struts applications. It allows us to reuse our existing investment, not only in code but also in developer skills. As a nice by-product, it also allows us to write cleaner, more reusable, Java Struts applications. Take a look at the Figures 3 and 4 below. At first glance, they seem similar to our previous ones. The difference is that after then screen loads (Figure 3) and the values in the textboxes are changed, the screen automatically updates without the screen going blank, giving the result as per Figure 4. The normal Submit button is also still there, should you choose to use it.
Adding this AJAX behavior is surprisingly easy. The server-side code is the same as usual: a Struts The JavaScript function We will look at each of these in more detail. To use, simply add the There are some interesting items going on in both methods. Within the The
原文链接Q?a >http://blog.xfocus.net/index.php?op=Default&postCategoryId=118&blogId=9
更新旉Q?005.07.11 22:20
2、买的时候要注意哪些Q?/font>
3?230有哪些控制码可以用?
*#7780# 恢复出厂默认讄
*#06# 昄IMEI?br />*#0000# 查询pȝ软g版本及更新日?br />*#2820# 查询蓝牙讑֤地址
4、Psilocpd软g安装q注册之后,用了一D|间又提示注册Q输入注册码之后Q显C“Application Expired”。如何解冻I
5、我无法?230的红外和某些其它U外讑֤互传文gQ这是怎么回事Q?/font>
6?230的MP3播放功能怎么P
7?230的FM攉机功能怎么P
88.7 中国国际q播电台
90.0 中央人民q播电台 W三套节目文?br />91.5 中国国际q播电台EasyFM
96.6 中央人民q播电台 W二套节目经频?br />97.4 北京人民q播电台音乐?br />99.6 中央人民q播电台W二套节?br />101.8 中央人民q播电台 W四套节目民族广?br />103.9 北京人民q播电台交通台
106.1 中央人民q播电台 W一套节目综合频?/font>
8?230的电池能用多长时_
9?230的拍照、摄像性能怎么P
10?230自带的游戏怎么P
11?230能不能更换各U彩壻I
12?230能收发电子邮件么Q?/font>
13?230可以安装U外遥控软g么?
14?230可以插扩展存储卡么?
15?650/3650?600/6670/7610上的软g可以?230上正常运行么Q?/font>
16?230的屏q怎么P
17、我能用3230上QQ和MSN么?
http://mgame.qq.com/mqq/qq.SIS
http://mgame.qq.com/mqq/qq_6670.SIS
http://mgame.qq.com/mqq/qq_7610.SIS
18?230的闹钟还是只能设定一个闹铃么Q?/font>
19、除了JavaQ还有别的运行在3230上的脚本语言么?
20?230是否?650那样Q屏q面杉KҎq灰?
21?230能和PC同步么?
22、我把随机带的RS-MMC卡中的程序删除了Q现在又想用q些E序了,该怎么办?
23、Nokia|站上提供了3230软g下蝲么?
http://www.nokia.com.cn/cn/support/phones/models/n6600/downloads/downloads_game.shtml
http://www.nokia.com.cn/cn/support/phones/models/n6681/downloads/downloads_game.shtml
http://www.nokia.com.cn/cn/support/phones/models/n6670/downloads/downloads_game.shtml
http://www.nokia.com.cn/cn/support/phones/models/n3650/downloads/downloads_game.shtml
http://nds2.nokia.com/files/support/china/phones/software/ebook_pc_sw.zip
24?230怎么锁屏Q?/font>
25?230的CPU是什么?
26、听?230的情景模式中Q如果把铃声关了Q也׃能用震动了Q是q样么?
27、我希望Nokia在下一个升URom中修Ҏ一些讨厌的BugQ该怎么做?
28?230q个型号代表什么意思?
29、我听h?230的操作系l是Symbian 70Q可是又看到有h?230是S60的机器,S60不就是Symbian 6.0吗?
30、我怎么才能扑ֈL最q的Nokia服务点?
诺基亚专卖店客户服务?东城Z四隆广Z区D102?010-84033330
诺基亚专卖店客户服务?h区白x路友谊宾馆东门北侧中复电?010-68948258
北京诺基亚客h务中?牡丹?h区北土城西\147?010-82021811
北京诺基亚客h务中?崇文?崇文区崇文门西大?h 010-65286529
北京诺基亚(N时代Q特U服务中?西城区北三环中\27号宜家家居首层西?010-62002278
北京电信发展d司维修中?蒲黄?丰台区永外刘家窑路蒲安西?5?010-67679696
北京诺基亚(长远Q特U服务中?通州 通州区新华大?22?010-69531248
北京诺基亚(凯达隆)特约服务中心-古城 x山区古城大街5??010-88929560
北京诺基亚(凯达隆)特约服务中心-怀?怀柔县青春?h3?010-69695110
北京Ud通信有限责Q公司l修中心 朝阳区霞光里2号B?06?010-64687588
北京诺基亚(京邮通)特约服务中心-王府?东城区王府井大街45?010-65262207
北京市通信产品质量监督验站特约服务中心 朝阳区大黄庄苗圃35?010-85778210
北京市诺ZQ中邮通)特约服务中心-公主?h区城乡N易中心五楼通信q场 010-68159837
北京诺基亚(凯达信)特约服务中心-Z Z区新南大街路东Q顺中商城北市场1-12P 010-69469662
北京诺基亚(中邮通)特约服务中心-木樨?台区南木樨园84?010-67214638
北京诺基亚(中复电讯Q特U服务中?丰台四环南\88?010-63817529
北京诺基亚(凯达信)特约服务中心-昌^ 昌^区政府街13号二?010-89742294
北京诺基亚(中邮通)特约服务中心-真武?西城区真武庙2??010-68012943
北京诺基亚(先L志远Q特U服务中?东城Z直门内大?h 010-84073301-11
北京诺基亚(凯达信)特约服务中心-公主?h区复兴\?4P公主坟华鹰大厦一层) 010-63969698
北京电信发展d司维修中?西单 西城单北大街118可单商Z楼北?010-66089696
北京电信发展d司维修中?西直?西城直门内葱店胡?号中宇通讯市场一?010-66136877
北京电信发展d司维修中?五棵?h区复兴\?5?010-68214046
注:文章原作者声明该文严{载,个h保存只是处于需要了解Nokia 3230特点的目的,文章q不会发表在blogjava上,了解之后会立即从FlyingisI间里删去该文章?/font>
]]>Action
, ActionForm
, and JSP
(mostly the same, with the addition of <span>
tags). To complete our understanding of the Struts-AJAX project, we need to look at the three JavaScript functions that are responsible for updating the current web page when the results from the server are received.
processStateChange()
: The method name that we set before making the AJAX call. This method is called by the XMLHttpRequest
/Microsoft.XMLHTTP
object once the server has completed sending back its response.
splitTextIntoSpan()
: Loops through the response, picking out an array of <span id="someName">NewContent</span>
elements.
replaceExistingWithNewHtml()
: Loops through this array of span elements, searching for
elements in the existing page with <span>
'someName'
and replacing them with the new content from the server. Note that we get the returned content via req.responseText
for robustness (since it allows us to manipulate any text response), rather than req.responseXml
(which is more powerful, but requires that you return valid XHTML or XML). function processStateChange() {
if (req.readyState == 4) { // Complete
if (req.status == 200) { // OK response
//Split the text response into Span elements
spanElements =
splitTextIntoSpan(req.responseText);
//Use these span elements to update the page
replaceExistingWithNewHtml(spanElements);
} else {
alert("Problem with server response:\n "
+ req.statusText);
}
}
}
replaceExistingWithNewHtml()
is a "private" method used by the processStateChange()
method.
function replaceExistingWithNewHtml
(newTextElements){
//loop through newTextElements
for(var i=newTextElements.length-1;i>=0;--i){
//check that this begins with <span
if(newTextElements[i].
indexOf("<span")>-1){
//get the span name - sits
// between the 1st and 2nd quote mark
//Make sure your spans are in the format
//<span id="someName">NewContent</span>
startNamePos=newTextElements[i].
indexOf('"')+1;
endNamePos=newTextElements[i].
indexOf('"',startNamePos);
name=newTextElements[i].
substring(startNamePos,endNamePos);
//get the content - everything
// after the first > mark
startContentPos=newTextElements[i].
indexOf('>')+1;
content=newTextElements[i].
substring(startContentPos);
//Now update the existing Document
// with this element, checking that
// this element exists in the document
if(document.getElementById(name)){
document.getElementById(name).
innerHTML = content;
}
}
}
splitTextIntoSpan()
is a "private" method used by the processStateChange()
method.function splitTextIntoSpan(textToSplit){
//Split the document
returnElements=textToSplit.
split("</span>")
//Process each of the elements
for(var i=returnElements.length-1;i>=0;--i){
//Remove everything before the 1st span
spanPos = returnElements[i].
indexOf("<span");
//if we find a match, take out
//everything before the span
if(spanPos>0){
subString=returnElements[i].
substring(spanPos);
returnElements[i]=subString;
}
}
return returnElements;
}
New Flow of Control
onChange()
event, which calls the retrieveURL()
JavaScript function.
Action
on the server, passing in all of the form variables in a way that Struts will understand.
processStateChange()
method.
processStateChange()
method is called.
<span>
elements in the (new) server response. Where it finds a <span>
in the existing page with the same name, it updates it with the new content.
Designing AJAX into Your Application
Action
and JSP for the initial request (i.e., show full page) and the AJAX (update part of page) requests.
Action
(controller) class, decide which sections of the JSP page (all of the JSP or only part of it) need to be sent to the browser. By setting flags in either the web server session
or ActionForm
, the JSP page knows which sections need to be rendered.
<logic:equal>
or JSTL tags to decide if we need to render a section of HTML or not.
Conclusion
]]>
Figure 3. AJAX sample after page load
Figure 4. AJAX sample after AJAX call
ActionForm
to hold the data, and a Struts Action
that performs the tasks required (e.g., database access) and then forwards to the appropriate JSP to display the result.
Don't Just Sit There
If you wish to stop reading here (and skip the explanation of how this works) then here is all you need to do to convert your Struts application to a Struts-AJAX application in a similar manner:
<span>
tags, giving each an id
.
onchange()
method of a textbox), call the retrieveURL()
function, passing in the URL to the Struts Action
that will do the necessary server-side processing.
Action
to forward back to the same JSP. In our sample, we trigger the AJAX call in the onchange()
method of the showGreen
/showBlue
textboxes. retrieveURL()
calls Struts on the server (via the URL provided), takes the JSP response, and updates the web page being displayed, where the <span>
tags on the existing web page match those on the newly returned JSP. Simple!The AJAX Solution in More Detail
When we converted the previous sample into an AJAX-Struts application we made three changes:
<span>
tags to the JSP page, which mark sections that will be updated during AJAX calls. Making the AJAX Call to the Server
There are two functions (listed below) that are used to call the server.
retrieveURL()
function takes a parameter of the URL of the server and the name of the Struts form. The URL will be called using AJAX and the values of the form passed to the server.
getFormAsString()
is a function that converts the values on the form named in retrieveURL()
into a query string suitable for posting to Struts on the server. retrieveURL()
function to the onclick()
/onChange()
method of the event you wish to trigger the screen update.retrieveURL()
method, the line req.onreadystatechange = processStateChange
(note: no brackets) tells the browser to call the processStateChange()
method (which we talk through later in this article) once the server sends back its response. This method (now standard in AJAX) also determines whether it should use the Internet Explorer (ActiveX) or Netscape/Mozilla (XmlHttpRequest
) object to ensure cross-browser compatibility.getFormAsString()
method converts the HTML form into a string to be appended to the URL (which allows us to do a HTTP GET
request). This string is escaped (spaces are converted to %20
, etc.) and is in a format that Struts can use to populate an ActionForm
(without Struts being aware of the special AJAX nature of the request). Note that while we use a HTTP GET
in this sample, it would be equally possible to use a HTTP POST
by looping in a similar manner and adding the form fields to the request.
function retrieveURL(url,nameOfFormToPost) {
//convert the url to a string
url=url+getFormAsString(nameOfFormToPost);
//Do the AJAX call
if (window.XMLHttpRequest) {
// Non-IE browsers
req = new XMLHttpRequest();
req.onreadystatechange = processStateChange;
try {
req.open("GET", url, true);
} catch (e) {
alert("Server Communication Problem\n"+e);
}
req.send(null);
} else if (window.ActiveXObject) {
// IE
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange=processStateChange;
req.open("GET", url, true);
req.send();
}
}
}
getFormAsString()
is a "private" method used by the retrieveURL()
method.
function getFormAsString(formName){
//Setup the return String
returnString ="";
//Get the form values
formElements=document.forms[formName].elements;
//loop through the array, building up the url
//in the format '/strutsaction.do&name=value'
for(var i=formElements.length-1;i>=0; --i ){
//we escape (encode) each value
returnString+="&"
+escape(formElements[i].name)+"="
+escape(formElements[i].value);
}
//return the values
return returnString;
}
]]>
This article shows a simple and elegant way to do this by including a couple of lines of JavaScript on your JavaServer Pages (JSPs). While we show how to reuse existing Struts actions, the techniques are equally applicable to the Java-Web framework of your choice. The method proposed will also allow a move to the next version of Struts (Shale) or JavaServer Faces (JSF) in the future.
AJAX stands for "Asynchronous JavaScript and XML." It is a technique, rather than a framework (such as Struts). The reason for the buzz around it is that it allows web pages to behave less like flat documents and more like dynamic GUI apps that users might expect from their desktop environments. AJAX techniques can be used for all recent browsers (including Internet Explorer and Netscape/Mozilla). It is already used by (among others) Microsoft (for its Outlook web client) and Google (for Google Maps and Gmail).
Most current Struts applications follow the standard "web page as a flat document" structure. If you wanted to mimic the behavior of GUI desktop apps (such as those built using Java Swing, Visual Basic, or Delphi) you had two choices: you could either send all of the information that might possibly required as part the web page with (a lot of) JavaScript to handle the dynamic behavior (a slow and not very enterprise-Java way to do things), or you could do constant form submits back to the server (an effective, if somewhat clunky, method). AJAX gives you the best of both worlds: dynamic web pages, but with most of the application running in Java on your web server.
AJAX is similar to existing Dynamic HTML techniques, with the addition of a "background" call to the server to get new/updated information as required. The mechanics of AJAX have already been covered in detail elsewhere--take a look at the Resources section at the end of this article for some good examples. The minimum you need to know is:
XMLHttpRequest
(or Microsoft.XMLHTTP
ActiveX object if you are using Internet Explorer). These objects can be called from the JavaScript on your web page. They allow you to request content from your web server as a background call (i.e., the screen does not "go blank" as usually happens during a form submit).
XMLHttpRequest
and Microsoft.XMLHTTP
objects return can be treated as either XML or plain text. JavaScript (on your web page) can then update the page with this new content as required.
onclick
, onchange
, onblur
, etc. The chances are that if you are reading this article, then you are interested in AJAX's ability to create dynamic web interfaces and would like to know how to add it to a Struts application. What are your options if you want to do this?
Some other advantages of our preferred option are:
How do we actually implement our chosen solution? We start by reminding ourselves how a "standard" (non-AJAX) Struts application works. In this application, the normal flow of events is as follows:
Action
, generating the web page.
ActionForm
class containing the posted data.
Action
that then processes the request (e.g., saves the data to a database).
A simple Struts application demonstrating this flow of events can be downloaded here: struts-non-ajax.zip. This application, based on the sample applications provided with Struts, either hides or displays blue and green tables depending on the values entered by the user. Figure 1 shows the screen on initial page load. Figure 2 shows the screen after the user has entered values and pressed Submit. Although simple, it is enough to demonstrate a Struts application at work.
Figure 1. Non-AJAX sample: Initial screen
Figure 2. Non-AJAX sample: Values entered, Submit pressed
The server-side code is as you would expect: a Struts Action
that forwards to the (same) JSP using the values defined in struts-config.xml. Some other points to note in this code sample are:
http://localhost:8080/struts-non-ajax/
(or the equivalent in your web server) to index.jsp.
showBlue
and showGreen
). The page also contains
tags, but as the values for these text boxes are initially blank, the content within them is not displayed.
SampleAction
class.
SampleAction
logs the values, and then forwards back to index.jsp. A more sophisticated Struts application would do more, such as saving to or retrieving from a database.
showBlue
or showGreen
are true
, the tables will be displayed. There is nothing "wrong" with this application. After all, similar Struts projects have been deployed for years. But how do we to add dynamic behavior to this application, without adding complex JavaScript or continual form submits?