??xml version="1.0" encoding="utf-8" standalone="yes"?>
weblogic安装参见 http://zhangstar.blogbus.com/logs/2004/09/413796.html
MyEclipse默认的应用服务器为JBoss3Q这里我们用WebLogic8.1。启动EclipseQ选择“窗口\首选项”菜单,打开首选项对话框。展开MyEclipse下的Application Serversl点Q点击JBoss 3Q选中右面的Disable单选按钮,停用JBoss 3。然后点击WebLogic 8Q选中双的Enable单选按钮,启用WebLogic服务器。同时下面的配置如下Q?
基本原理
要实现网l机器间的通讯Q首先得来看看计机pȝ|络通信的基本原理,在底层层面去看,|络通信需要做的就是将从一台计机传输到另外一台计机Q基于传输协议和|络IO来实玎ͼ其中传输协议比较出名的有http、tcp、udp{等Qhttp、tcp、udp都是在基于Socket概念上ؓ某类应用场景而扩展出的传输协议,|络IOQ主要有bio、nio、aio三种方式Q所有的分布式应用通讯都基于这个原理而实玎ͼ只是Z应用的易用,各种语言通常都会提供一些更q应用易用的应用层协议?br />
应用U协?/strong>
q程服务通讯Q需要达到的目标是在一台计机发vhQ另外一台机器在接收到请求后q行相应的处理ƈ结果返回给h端,q其中又会有诸如one way request、同步请求、异步请求等{请求方式,按照|络通信原理Q需要实现这个需要做的就是将h转换成流Q通过传输协议传输臌端,q端计算机在接收到请求的后q行处理Q处理完毕后结果{化ؓ,q过传输协议q回l调用端?br />
原理是这LQ但Z应用的方便,业界推出了很多基于此原理之上的应用的协议,使得大家可以不用ȝ接操作这么底层的东西Q通常应用U的q程通信协议会提供:
1、ؓ了避免直接做操作这么麻烦,提供一U更加易用或贴合语言的标准传输格式;
2、网l通信机制的实玎ͼ是替你完成了将传输格式转化为流Q通过某种传输协议传输臌端计机Q远端计机在接收到后转化Z输格式,q进行存储或以某U方式通知q端计算机?br />
所以在学习应用U的q程通信协议Ӟ我们可以带着q几个问题进行学习:
1、传输的标准格式是什么?
2、怎么样将h转化Z输的?
3、怎么接收和处理流Q?br />
4、传输协议是Q?br />
不过应用U的q程通信协议q不会在传输协议上做什么多大的改进Q主要是在流操作斚wQ让应用层生成流和处理流的这个过E更加的贴合所使用的语a或标准,至于传输协议则通常都是可选的Q在java领域中知名的有:RMI、XML-RPC、Binary-RPC、SOAP、CORBA、JMSQ来具体的看看这些远E通信的应用协议Q?br />
--------------------------------------------------------------------------------------------------------------------------------------------------
RMI
RMI是个典型的ؓjava定制的远E通信协议Q我们都知道Q在single vm中,我们可以通过直接调用java object instance来实现通信Q那么在q程通信Ӟ如果也能按照q种方式当然是最好了Q这U远E通信的机制成为RPCQRemote Procedure CallQ,RMI正是朝着q个目标而诞生的?br />
来看下基于RMI的一ơ完整的q程通信q程的原理:
1、客L发vhQ请求{交至RMI客户端的stubc;
2、stubcdh的接口、方法、参数等信息q行序列化;
3、基于socket序列化后的传输至服务器端Q?br />
4、服务器端接收到后转发至相应的skeltonc;
5、skeltoncdh的信息反序列化后调用实际的处理类Q?br />
6、处理类处理完毕后将l果q回lskeltonc;
7、Skeltoncdl果序列化,通过socket流传送给客户端的stubQ?br />
8、stub在接收到后反序列化Q将反序列化后的Java Objectq回l调用者?br />
来看jboss-remoting对于此过E的一个更好的囄Q?br />
Ҏ原理来回{下之前学习应用U协议带着的几个问题:
1、传输的标准格式是什么?
是Java ObjectStream?br />
2、怎么样将h转化Z输的?
ZJava串行化机制将h的java object信息转化为流?br />
3、怎么接收和处理流Q?br />
Ҏ采用的协议启动相应的监听端口Q当有流q入后基于Java串行化机制将进行反序列化,q根据RMI协议获取到相应的处理对象信息Q进行调用ƈ处理Q处理完毕后的结果同样基于java串行化机制进行返回?br />
4、传输协议是Q?br />
Socket?br />
--------------------------------------------------------------------------------------------------------------------------------------------------
XML-RPC
XML-RPC也是一U和RMIcM的远E调用的协议Q它和RMI的不同之处在于它以标准的xml格式来定义请求的信息(h的对象、方法、参数等)Q这L好处是什么呢Q就是在跨语a通讯的时候也可以使用?br />
来看下XML-RPC协议的一ơ远E通信q程Q?br />
1、客L发vhQ按照XML-RPC协议请求信息进行填充;
2、填充完毕后xml转化为流Q通过传输协议q行传输Q?br />
3、接收到在接收到后转换为xmlQ按照XML-RPC协议获取h的信息ƈq行处理Q?br />
4、处理完毕后结果按照XML-RPC协议写入xml中ƈq回?br />
囄以上q程Q?br />
同样来回{问题:
1、传输的标准格式是?
标准格式的XML?br />
2、怎么样将h转化Z输的?
XML转化为流?br />
3、怎么接收和处理流Q?br />
通过监听的端口获取到h的流Q{化ؓXMLQƈҎ协议获取h的信息,q行处理q将l果写入XML中返回?br />
4、传输协议是Q?br />
Http?br />
--------------------------------------------------------------------------------------------------------------------------------------------------
Binary-RPC
Binary-RPC看名字就知道和XML-RPC是差不多的了Q不同之处仅在于传输的标准格式由XML转ؓ了二q制的格式?br />
同样来回{问题:
1、传输的标准格式是?
标准格式的二q制文g?br />
2、怎么样将h转化Z输的?
二q制格式文g转化为流?br />
3、怎么接收和处理流Q?br />
通过监听的端口获取到h的流Q{化ؓ二进制文ӞҎ协议获取h的信息,q行处理q将l果写入XML中返回?br />
4、传输协议是Q?br />
Http?br />
--------------------------------------------------------------------------------------------------------------------------------------------------
SOAP
SOAP原意为Simple Object Access ProtocolQ是一个用于分布式环境的、轻量的、基于XMLq行信息交换的通信协议Q可以认为SOAP是XML RPC的高U版Q两者的原理完全相同Q都是http+XMLQ不同的仅在于两者定义的XML规范不同QSOAP也是Webservice采用的服务调用协议标准,因此在此׃多加阐述了?br />
--------------------------------------------------------------------------------------------------------------------------------------------------
CORBA
Common Object Request Broker ArchitectureQ公用对象请求代理[调度]E序体系l构Q,是一l用来定?#8220;分布式对象系l?#8221;的标准,由OMG(Object Menagement Group)作ؓ发v和标准制定单位。CORBA的目的是定义一套协议,W合q个协议的对象可以互怺互,不论它们是用什么样的语a写的Q不论它们运行于什么样的机器和操作pȝ?br />
CORBA在我看来是个cM于SOA的体pL构,늛可选的q程通信协议Q但其本w不能列入通信协议q里来讲Q而且CORBA基本淘汰Q再加上对CORBA也不怎么懂,在此׃q行阐述了?br />
--------------------------------------------------------------------------------------------------------------------------------------------------
JMS
JMS呢,是实现java领域q程通信的一U手D和ҎQ基于JMS实现q程通信时和RPC是不同的Q虽然可以做到RPC的效果,但因Z是从协议U别定义的,因此我们不认为JMS是个RPC协议Q但它确实是个远E通信协议Q在其他的语a体系中也存在着cMJMS的东西,可以l一的将q类机制UCؓ消息机制Q而消息机制呢Q通常是高q发、分布式领域推荐的一U通信机制Q这里的主要一个问题是定wQ详l见ErLang论文Q?br />
来看JMS中的一ơ远E通信的过E:
1、客L请求{化ؓW合JMS规定的MessageQ?br />
2、通过JMS APIMessage攑օJMS Queue或Topic中;
3、如为JMS QueueQ则发送中相应的目标Queue中,如ؓTopicQ则发送给订阅了此Topic的JMS Queue?br />
4、处理端则通过轮训JMS QueueQ来获取消息Q接收到消息后根据JMS协议来解析Messageq处理?br />
回答问题Q?br />
1、传输的标准格式是?
JMS规定的Message?br />
2、怎么样将h转化Z输的?
参C息放入Message中即可?br />
3、怎么接收和处理流Q?br />
轮训JMS Queue来接收MessageQ接收到后进行处理,处理完毕后仍然是以Message的方式放入Queue中发送或Multicast?br />
4、传输协议是Q?br />
不限?br />
ZJMS也是常用的实现远E异步调用的Ҏ之一?br />
可选实现技?/strong>
当然Q在上面的原理中q没有介l到所有的java领域可选的q程通信协议了,例如q有EJB采用的ORMI、Spring自己定义的一个简单的Http Invoker{等?br />
看完原理后我们再来看看目前java领域可用于实现远E通讯的框架或libraryQ知名的有:JBoss-Remoting、Spring-Remoting、Hessian、Burlap、XFire(Axis)、ActiveMQ、Mina、Mule、EJB3{等Q来ҎU做个简单的介绍和评P其实呢,要做分布式服务框Ӟq些东西都是要有非常深刻的了解的Q因为分布式服务框架其实是包含了解决分布式领域以及应用层面领域两斚w问题的?br />
当然Q你也可以自己根据远E网l通信原理(transport protocol+Net IO)d现自q通讯框架或library?br />
那么在了解这些远E通讯的框架或libraryӞ会带着什么问题去学习呢?
1、是Z什么协议实现的Q?br />
2、怎么发vhQ?br />
3、怎么请求{化ؓW合协议的格式的Q?br />
4、用什么传输协议传输?
5、响应端Z什么机制来接收hQ?br />
6、怎么流q原Z输格式的Q?br />
7、处理完毕后怎么回应Q?br />
--------------------------------------------------------------------------------------------------------------------------------------------------
JBoss-Remoting
Jboss-remoting是由jboss~写的一个java领域的远E通讯框架Q基于此框架Q可以很单的实现Z多种传输协议的java对象的RPC?br />
直接来回{问题:
1、是Z什么协议实现的Q?br />
JBoss-Remoting是个通讯框架Q因此它支持多种协议方式的通信Q例如纯_的socket+io方式、rmi方式、http+io方式{?br />
2、怎么发vhQ?br />
在JBoss-Remoting中,只需需要发Lh参数对象传入jboss-remoting的InvocationRequest对象卛_Q也可根据协议基于InvocationRequest装W合需求的InvocationRequest对象?br />
3、怎么请求{化ؓW合协议的格式的Q?br />
JBoss-RemotingZJava串行化机制或JBoss自己的串行化实现来将h转化为对象字节流?br />
4、用什么传输协议传输?
支持多种传输协议Q例如socket、http{?br />
5、响应端Z什么机制来接收hQ?br />
响应端只需自q处理对象注册到JBoss-Remoting提供的server端的Connector对象中即可?br />
6、怎么流q原Z输格式的Q?br />
JBoss-RemotingZjava串行化机制或jboss自己的串行化实现来将h信息q原为java对象?br />
7、处理完毕后怎么回应Q?br />
处理完毕后将l果对象直接q回卛_Qjboss-remoting会将此对象按照协议进行序列化Q返回至调用端?br />
另外Qjboss-remoting支持多种通信方式Q例如同?异步/单向通信{?br />
--------------------------------------------------------------------------------------------------------------------------------------------------
spring in action-Remoting
spring in action-remoting是Spring提供java领域的远E通讯框架Q基于此框架Q同样也可以很简单的普通的spring bean以某U远E协议的方式来发布,同样也可以配|spring beanE调用的bean?br />
1、是Z什么协议实现的Q?br />
和JBoss-Remoting一P作ؓ一个远E通讯的框ӞSpring通过集成多种q程通讯的libraryQ从而实C对多U协议的支持Q例如rmi、http+io、xml-rpc、binary-rpc{?br />
2、怎么发vhQ?br />
在Spring中,׃其对于远E调用的bean采用的是proxy实现Q发赯求完全是通过服务接口调用的方式?br />
3、怎么请求{化ؓW合协议的格式的Q?br />
Spring按照协议方式请求的对象信息转化为流Q例如Spring Http Invoker是基于Spring自己定义的一个协议来实现的,传输协议上采用的为httpQ请求信息是Zjava串行化机制{化ؓ进行传输?br />
4、用什么传输协议传输?
支持多种传输协议Q例如rmi、http{等?br />
5、响应端Z什么机制来接收hQ?br />
响应端遵循协议方式来接收hQ对于用者而言Q则只需通过spring的配|方式将普通的spring bean配置为响应端或者说提供服务端?br />
6、怎么流q原Z输格式的Q?br />
按照协议方式来进行还原?br />
7、处理完毕后怎么回应Q?br />
处理完毕后直接返回即可,spring-remoting根据协议方式来做相应的序列化?br />
--------------------------------------------------------------------------------------------------------------------------------------------------
Hessian
Hessian是由caucho提供的一个基于binary-RPC实现的远E通讯library?br />
1、是Z什么协议实现的Q?br />
ZBinary-RPC协议实现?br />
2、怎么发vhQ?br />
需通过Hessian本n提供的API来发赯求?br />
3、怎么请求{化ؓW合协议的格式的Q?br />
Hessian通过其自定义的串行化机制请求信息进行序列化Q生二q制?br />
4、用什么传输协议传输?
HessianZHttp协议q行传输?br />
5、响应端Z什么机制来接收hQ?br />
响应端根据Hessian提供的API来接收请求?br />
6、怎么流q原Z输格式的Q?br />
HessianҎ其私有的串行化机制来请求信息进行反序列化,传递给使用者时已是相应的请求信息对象了?br />
7、处理完毕后怎么回应Q?br />
处理完毕后直接返回,hessian结果对象进行序列化Q传输至调用端?br />
--------------------------------------------------------------------------------------------------------------------------------------------------
Burlap
Burlap也是有caucho提供Q它和hessian的不同在于,它是ZXML-RPC协议的?br />
1、是Z什么协议实现的Q?br />
ZXML-RPC协议实现?br />
2、怎么发vhQ?br />
ҎBurlap提供的API?br />
3、怎么请求{化ؓW合协议的格式的Q?br />
请求信息{化ؓW合协议的XML格式Q{化ؓ进行传输?br />
4、用什么传输协议传输?
Http协议?br />
5、响应端Z什么机制来接收hQ?br />
监听Httph?br />
6、怎么流q原Z输格式的Q?br />
ҎXML-RPC协议q行q原?br />
7、处理完毕后怎么回应Q?br />
q回l果写入XML中,由Burlapq回臌用端?br />
--------------------------------------------------------------------------------------------------------------------------------------------------
XFire、Axis
XFire、Axis是Webservice的实现框ӞWebService可算是一个完整的SOA架构实现标准了,因此采用XFire、Axisq些也就意味着是采用webservice方式了?br />
1、是Z什么协议实现的Q?br />
ZSOAP协议?br />
2、怎么发vhQ?br />
获取到远端service的proxy后直接调用?br />
3、怎么请求{化ؓW合协议的格式的Q?br />
请求信息{化ؓ遵@SOAP协议的XML格式Q由框架转化为流q行传输?br />
4、用什么传输协议传输?
Http协议?br />
5、响应端Z什么机制来接收hQ?br />
监听Httph?br />
6、怎么流q原Z输格式的Q?br />
ҎSOAP协议q行q原?br />
7、处理完毕后怎么回应Q?br />
q回l果写入XML中,由框架返回至调用端?br />
--------------------------------------------------------------------------------------------------------------------------------------------------
ActiveMQ
ActiveMQ是JMS的实玎ͼZJMSq类消息机制实现q程通讯是一U不错的选择Q毕竟消息机制本w的功能使得Z它可以很Ҏ的去实现同步/异步/单向调用{,而且消息机制从容错角度上来说也是个不错的选择Q这是Erlang能够做到定w的重要基?br />
1、是Z什么协议实现的Q?br />
ZJMS协议?br />
2、怎么发vhQ?br />
遵@JMS API发vh?br />
3、怎么请求{化ؓW合协议的格式的Q?br />
不太清楚Q猜惛_该是二进制流?br />
4、用什么传输协议传输?
支持多种传输协议Q例如socket、http{等?br />
5、响应端Z什么机制来接收hQ?br />
监听W合协议的端口?br />
6、怎么流q原Z输格式的Q?br />
同问??br />
7、处理完毕后怎么回应Q?br />
遵@JMS API生成消息Qƈ写入JMS Queue中?br />
ZJMS此类机制实现q程通讯的例子有Spring-Intergration、Mule、Lingo{等?br />
--------------------------------------------------------------------------------------------------------------------------------------------------
Mina
Mina是Apache提供的通讯框架Q在之前一直没有提到网lIOq块Q之前提及的框架或library基本都是ZBIO的,而Mina是采用NIO的,NIO在ƈ发量增长时对比BIO而言会有明显的性能提升Q而java性能的提升,与其NIOq块与OS的紧密结合是有不的关系的?br />
1、是Z什么协议实现的Q?br />
ZUa的Socket+NIO?br />
2、怎么发vhQ?br />
通过Mina提供的Client API?br />
3、怎么请求{化ؓW合协议的格式的Q?br />
Mina遵@java串行化机制对h对象q行序列化?br />
4、用什么传输协议传输?
支持多种传输协议Q例如socket、http{等?br />
5、响应端Z什么机制来接收hQ?br />
以NIO的方式监听协议端口?br />
6、怎么流q原Z输格式的Q?br />
遵@java串行化机制对h对象q行反序列化?br />
7、处理完毕后怎么回应Q?br />
遵@Mina APIq行q回?br />
MINA是NIO方式的,因此支持异步调用是毫无悬늚?br />
--------------------------------------------------------------------------------------------------------------------------------------------------
EJB
EJB最H出的在于其分布式,EJB采用的是ORMI协议Q和RMI协议是差不多的,但EJB在分布式通讯的安全控制、transport pool、smart proxy{方面的H出使得其在分布式领域是不可忽视的力量?br />
1、是Z什么协议实现的Q?br />
ZORMI协议?br />
2、怎么发vhQ?br />
EJB调用?br />
3、怎么请求{化ؓW合协议的格式的Q?br />
遵@java串行化机制对h对象q行序列化?br />
4、用什么传输协议传输?
Socket?br />
5、响应端Z什么机制来接收hQ?br />
监听协议端口?br />
6、怎么流q原Z输格式的Q?br />
遵@java串行化机制对h对象q行反序列化?br />
7、处理完毕后怎么回应Q?br />
直接q回处理对象卛_?br />
在之前的分布式服务框架系列的文章中对于jndi有误导的嫌疑Q在q篇blog中也带的提下jndi的机Ӟ׃JNDI取决于具体的实现Q在q里只能是讲解下jboss的jndi的实C?br />
在将对象实例l定到jboss jnp server后,当远E端采用context.lookup()方式获取q程对象实例q开始调用时Qjboss jndi的实现方法是从jnp server上获取对象实例,其序列化回本地Q然后在本地q行反序列化Q之后在本地q行c调用?br />
通过q个机制Q就可以知道了,本地其实是必Ll定到jboss上的对象实例的class的,否则反序列化的时候肯定就p|了,而远E通讯需要做到的是在q程执行某动作,q获取到相应的结果,可见UaZJNDI是无法实现远E通讯的?br />
但JNDI也是实现分布式服务框架一个很关键的技术点Q因为可以通过它来实现透明化的q端和本地调用,像ejbQ另外它也是个很好的隐藏实际部v机制(像datasource){的Ҏ?br />
ȝ
׃一pd的分析可知,在远E通讯领域中,涉及的知识点q是相当的多的,例如有:通信协议(Socket/tcp/http/udp/rmi/xml-rpc etc.)、消息机制、网lIOQBIO/NIO/AIOQ、MultiThread、本地调用与q程调用的透明化方案(涉及java classloader、Dynamic Proxy、Unit Test etc.Q、异步与同步调用、网l通信处理机制Q自动重q、广播、异常、池处理{等Q、Java Serialization (各种协议的私有序列化机制{?、各U框架的实现原理Q传输格式、如何将传输格式转化为流的、如何将h信息转化Z输格式的、如何接收流的、如何将还原ؓ传输格式的等{)Q要_N其中的哪些东西Q得Ҏ实际需求来军_了,只有在了解了原理的情况下才能很容易的做出选择Q甚臛_以根据需求做U有的远E通讯协议Q对于从事分布式服务q_或开发较大型的分布式应用的h而言Q我觉得臛_上面提及的知识点是需要比较了解的?br />
参考文档(感谢q些文章Q?/strong>
RMI原理及实玎ͼhttp://www.yesky.com/274/1625274.shtml
Java NIO原理和用:http://www.jdon.com/concurrent/nio%D4%AD%C0%ED%D3%A6%D3%C3.htm
XML RPC协议Q?a target="_blank">http://hedong.3322.org/archives/000470.html
http://www.mengyan.org/blog/archives/2005/07/12/30.html
Spring技术应用中的远E服务详解:http://www.builder.com.cn/2007/1027/583384.shtml
JAVA RPC通信机制之SOAPQ?/span>http://www.java114.com/content16/content3826.html
Java RemotingQProtocol BenchMarksQ?a target="_blank">http://q.sohu.com/forum/5/topic/1148909
Evalution of RMI AlternativeQ?a target="_blank">https://www.jfire.org/modules/phpwiki/index.php/Evaluation%20of%20RMI%20Alternative
Metaprotocol TaxonomyQ?a target="_blank">http://hessian.caucho.com/doc/metaprotocol-taxonomy.xtp
什么是WebserviceQ?a >http://www.vchome.net/dotnet/webservice/webservice15.htm
]]>
tomcat 5.0
mysql 5.0.16
apache-ant-1.6.5
jbpm-starters-kit-3.1.4
阅读全文
]]>
]]>
我们l常利用Struts的ActionForm提供的验证服?validate)来检查页面上输入的信息。当输入的信息不W合验标准时Q返回一个装载了错误信息的错误对象,如下Q?br />public class LoginForm extends ActionForm
{
private String name;
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
public ActionErrors validate(
ActionMapping mapping,
HttpServletRequest request)
{
// 生成错误对象
ActionErrors errs = new ActionErrors();
// 名称不可为空
if (this.name == null || "".equals(this.name))
{
errs.add("name", new ActionMessage("msg.name.empty"));
}
return errs;
}
}
只要在struts-config.xml action的配|中加入input="/login.jsp"Qƈ在页面上利用Struts 标签<html:errors property="name"/>可以将ApplicationResources.properties中所定义的错误信息显C出来。这是Struts的传l做法。那么在Velocity中该如何处理q种情况呢?Ҏ很简单,只要配置Velocity的toolbox.xmlq将相应?jar文g攑֜lib下面卛_。关于toolbox.xml的详l配|请参见?a id="viewpost1_TitleUrl" href="/shmily432685/archive/2006/08/07/62177.html">Velocity中用Struts的国际化文g》。通过该文我们知道了Velocity为Struts的错误信息提供了专用的类org.apache.velocity.tools.struts.ErrorsTool。还是上面的例子Q我们只要将面中的<html:errors property="name"/>改ؓ$!{errors.get("name")}卛_?
]]><?xml version="1.0"?>
<toolbox>
<tool>
<key>link</key>
<scope>request</scope>
<class>
org.apache.velocity.tools.struts.StrutsLinkTool
</class>
</tool>
<tool>
<key>msg</key>
<scope>request</scope>
<class>
org.apache.velocity.tools.struts.MessageTool
</class>
</tool>
<tool>
<key>actionMsg</key>
<scope>request</scope>
<class>
org.apache.velocity.tools.struts.ActionMessagesTool
</class>
</tool>
<tool>
<key>errors</key>
<scope>request</scope>
<class>
org.apache.velocity.tools.struts.ErrorsTool
</class>
</tool>
<tool>
<key>form</key>
<scope>request</scope>
<class>
org.apache.velocity.tools.struts.FormTool
</class>
</tool>
<tool>
<key>tiles</key>
<scope>request</scope>
<class>
org.apache.velocity.tools.struts.TilesTool
</class>
</tool>
<tool>
<key>validator</key>
<scope>request</scope>
<class>
org.apache.velocity.tools.struts.ValidatorTool
</class>
</tool>
</toolbox>
StrutsLinkToolQ针?Struts ?LinkTool 专用版本Q提供了 setAction() ?setForward() 讉K预先配置的活动映?br />MessageToolQ提供对 Struts 国际化支持的讉KQ尤为特别的是依赖于语言的消息资源?br />ErrorsToolQ处?Struts 错误消息Q包括对国际化的支持?br />FormToolQ访?Struts 的表?beans?br />TilesToolQ提供对 Struts 1.1 Tiles 扩展支持的访问?br />ValidatorToolQ提供对 Struts 1.1 Validator 扩展的访问,生成代码验证表单输入字段?br />
现在Q我们有一个编译好了的文gQApplicationResources_zh_CN.properties。它的内容如下:
name=六月?br />
?vm文g中,可以这样写Q?br />$!{msg.get(“name?}
]]>
(1)BEA home directoryQC:\BEA。假定WebLogic安装在D:\BEA文g夹中?
(2)WebLogic installation directoryQC:\BEA\weblogic81?
(3)Admin usernameQ用户名?
(4)Admin passwordQ密码?
(5)Execution domain rootQ安装后Q启动服务的路径?
(6)Execution domain nameQmydomain?
(7)Execution server nameQmyserver?
(8)Hostname:PortNumberQlocalhost:7001?
(9)Security policy fileQD:\BEA\weblogic81\server\lib\weblogic.policy?
(10)JAAS login configuration fileQ省略?
以上配置Ҏ安装情况不同而不同?BR>如图Q?BR>
接着展开WebLogic 8l点Q点击JDKQ在双的WLS JDK name处选择WebLogic 8的默认JDK。这里组合框中缺省ؓj2re1.4.2_03Q即之前单独安装的jre。单击Add按钮Q弹出WebLogic > Add JVM对话框,在JRE名称处随便输入一个名字,如jre1.4.1_02。然后在JREȝ录处选择WebLogic安装文g夹中的JDK文g夹,如D:\BEA\jdk141_02Q程序会自动填充Javadoc URL文本框和JREpȝ库列表框。单ȝ定按钮关闭对话框。这时候就可以在WLS JDK namel合框中选择jre1.4.1_02了。之后还要在下面的Optional Java VM argumentsQ如-ms64m -mx64m -Djava.library.path="D:/BEA/weblogic81/server/bin" -Dweblogic.management.discover=false -Dweblogic.ProductionModeEnabled=false
最后点击PathsQ在双的Prepend to classpath列表框中Q通过Add JAR/ZIP按钮Q加入D:\BEA\weblogic81\server\lib\weblogic.jar、D:\BEA\weblogic81\server\lib\webservices.jar。如果用到数据库Q还需把数据库的驱动类库加q来Q这里我们用WebLogic自带的SQL Server数据库驱动库D:\BEA\weblogic81\server\lib\mssqlserver4v65.jar?
xQMyEclipse中WebLogic8的配|工作就完成了。下面可以看看在Eclipse中能否启动WebLogic了?自从安装了MyEclipse之后QEclipse工具栏中׃有一个Run/Stop Servers下拉按钮。点击该按钮的下拉部分,选择“WebLogic 8\Start”菜单,卛_始启动WebLogic了。通过查看下面的控制台消息Q就可以知道启动是否成功Q或有什么异常发生。停止WebLogic可选择“WebLogic\Stop”菜?/P>
2、DOCYTPE声明必须立即出现在此头之后。这个声明告诉服务器适用?/SPAN>servlet规范的版本(?/SPAN>2.2?/SPAN>2.3Qƈ指定理此文件其余部分内容的语法?/SPAN>DTD(Document Type DefinitionQ文档类型定?/SPAN>)?/SPAN>
所有部|描q符文g的顶层(根)元素?/SPAN>web-app。请注意Q?/SPAN>XML元素不像HTMLQ他们是大小写敏感的。因此,web-App?/SPAN>WEB-APP都是不合法的Q?/SPAN>web-app必须用小写?/SPAN>
2?部v描述W文件内的元素次?/SPAN>
XML 元素不仅是大写敏感的,而且它们q对出现在其他元素中的次序敏感?/SPAN>
XML头必L文g中的W一,DOCTYPE声明必须是第二项Q?/SPAN>web- app元素必须是第三项。在web-app元素内,元素的次序也很重要。服务器不一定强制要求这U次序,但它们允许(实际上有些服务器是q样做的Q完全拒l执行含有次序不正确的元素的Web应用。这表示使用非标准元素次序的web.xml文g是不可移植的?/SPAN>
下面的列表给Z所有可直接出现?/SPAN>web-app元素内的合法元素所必需的次序?/SPAN>
此列表说?/SPAN>servlet元素必须出现在所?/SPAN>servlet-mapping元素之前。请注意Q所有这些元素都是可选的。因此,可以省略掉某一元素Q但不能把它放于不正的位置?/SPAN>
l icon icon元素指出IDE?/SPAN>GUI工具用来表示Web应用的一个和两个囑փ文g的位|?/SPAN>
l display-name display-name元素提供GUI工具可能会用来标记这个特定的Web应用的一个名U?/SPAN>
l description description元素l出与此有关的说明性文本?/SPAN>
l context-param context-param元素声明应用范围内的初始化参数?/SPAN>
l filter qo器元素将一个名字与一个实?/SPAN>javax.servlet.Filter接口的类相关联?/SPAN>
l filter-mapping 一旦命名了一个过滤器Q就要利?/SPAN>filter-mapping元素把它与一个或多个servlet?/SPAN>JSP面相关联?/SPAN>
l listener servlet API的版?/SPAN>2.3增加了对事g监听E序的支持,事g监听E序在徏立、修改和删除会话?/SPAN>servlet环境时得到通知?/SPAN>Listener元素指出事g监听E序cR?/SPAN>
l servlet 在向servlet?/SPAN>JSP面制定初始化参数或定制URLӞ必须首先命名servlet?/SPAN>JSP面?/SPAN>Servlet元素是用来完成此项d的?/SPAN>
l servlet-mapping 服务器一般ؓservlet提供一个缺省的URLQ?/SPAN>。但是,常常会更改这?/SPAN>URLQ以?/SPAN>servlet可以讉K初始化参数或更容易地处理相对URL。在更改~省URLӞ使用servlet-mapping元素?/SPAN>
l session-config 如果某个会话在一定时间内未被讉KQ服务器可以抛弃它以节省内存。可通过使用HttpSession?/SPAN>setMaxInactiveIntervalҎ明确讄单个会话对象的超时|或者可利用session-config元素制定~省时倹{?/SPAN>
l mime-mapping 如果Web应用h惛_Ҏ的文Ӟ希望能保证给他们分配特定?/SPAN>MIMEcdQ则mime-mapping元素提供q种保证?/SPAN>
l welcom-file-list welcome-file-list元素指示服务器在收到引用一个目录名而不是文件名?/SPAN>URLӞ使用哪个文g?/SPAN>
l error-page error-page元素使得在返回特?/SPAN>HTTP状态代码时Q或者特定类型的异常被抛出时Q能够制定将要显C的面?/SPAN>
l taglib taglib元素Ҏ记库描述W文ӞTag Libraryu Descriptor fileQ指定别名。此功能使你能够更改TLD文g的位|,而不用编辑用这些文件的JSP面?/SPAN>
l resource-env-ref resource-env-ref元素声明与资源相关的一个管理对象?/SPAN>
l resource-ref resource-ref元素声明一个资源工厂用的外部资源?/SPAN>
l security-constraint security-constraint元素制定应该保护?/SPAN>URL。它?/SPAN>login-config元素联合使用
l login-config ?/SPAN>login-config元素来指定服务器应该怎样l试图访问受保护面的用h权。它?/SPAN>sercurity-constraint元素联合使用?/SPAN>
l security-role security-role元素l出安全角色的一个列表,q些角色出现在servlet元素内的security-role-ref元素?/SPAN>role-name子元素中。分别地声明角色可高IDE处理安全信息更ؓҎ?/SPAN>
l env-entry env-entry元素声明Web应用的环境项?/SPAN>
l ejb-ref ejb-ref元素声明一?/SPAN>EJB的主目录的引用?/SPAN>
l ejb-local-ref ejb-local-ref元素声明一?/SPAN>EJB的本C目录的应用?BR>3?/SPAN>
?Web 应用E序开发中Q页面重载@环是最大的一个用障,对于 Java?开发h员来说也是一个严ȝ挑战。在q个pd中,作?Philip McCarthy 介绍了一U创建动态应用程序体验的开创性方式。AjaxQ异?JavaScript ?XMLQ是一U编E技术,它允ؓZ Java ?Web 应用E序?Java 技术、XML ?JavaScript l合hQ从而打破页面重载的范式?/BLOCKQUOTE>AjaxQ即异步 JavaScript ?XMLQ是一U?Web 应用E序开发的手段Q它采用客户端脚本与 Web 服务器交换数据。所以,不必采用会中断交互的完整面hQ就可以动态地更新 Web 面。?AjaxQ可以创建更加丰富、更加动态的 Web 应用E序用户界面Q其x性与可用性甚臌够接q本机桌面应用程序?/P>
Ajax 不是一Ҏ术,而更像是一?模式 —?一U识别和描述有用的设计技术的方式。Ajax 是新颖的Q因多开发h员才刚刚开始知道它Q但是所有实?Ajax 应用E序的组仉已经存在若干q了。它目前受到重视是因为在 2004 ?2005 q出C一些基?Ajax 技术的非常的动?Web UIQ最著名的就?Google ?GMail ?Maps 应用E序Q以及照片共享站?Flickr。这些用L面具有够的开创性,有些开发h员称之ؓ“Web 2.0”,因此?Ajax 应用E序的兴飞速上升?/P>
在这个系列中Q我提供?Ajax 开发应用程序需要的全部工具 。在W一文章中Q我解?Ajax 背后的概念,演示为基?Java ?Web 应用E序创徏 Ajax 界面的基本步骤。我用代码示例演C Ajax 应用E序如此动态的服务器端 Java 代码和客L JavaScript。最后,我将指出 Ajax 方式的一些不I以及在创?Ajax 应用E序时应当考虑的一些更q的可用性和讉K性问题?/P>
可以?Ajax 增强传统?Web 应用E序Q通过消除面装入从而简化交互。ؓ了演C一点,我采用一个简单的购物车示例,在向里面d目Ӟ它会动态更新。这Ҏ术如果整合到在线商店Q那么用户可以持l地览和向购物车中d目Q而不必在每次点击之后都等候完整的面更新。虽然这文章中的有些代码特定于购物车示例,但是演示的技术可以应用于M Ajax 应用E序。清?1 昄了购物RCZ使用的有?HTML 代码Q整文章中都会使用q个 HTML?/P>
<!-- Table of products from store's catalog, one row per item --> <th>Name</th> <th>Description</th> <th>Price</th> <th></th> ... <tr> <!-- Item details --> <td>Hat</td> <td>Stylish bowler hat</td> <td>$19.99</td> <td> <!-- Click button to add item to cart via Ajax request --> <button onclick="addToCart('hat001')">Add to Cart</button> </td> </tr> ... <!-- Representation of shopping cart, updated asynchronously --> <ul id="cart-contents"> <!-- List-items will be added here for each item in the cart --> </ul> <!-- Total cost of items in cart displayed inside span element --> Total cost: <span id="total">$0.00</span>
Ajax 往q过E?/FONT>Ajax 交互开始于叫作
?JavaScript 对象。顾名思义Q它允许客户端脚本执?HTTP hQƈ解析 XML 服务器响应。Ajax 往q过E的W一步是创徏
的实例。在
对象上设|请求用的 HTTP ҎQ?CODE> ?
Q以及目?URL?/P>
现在Q您q记?Ajax 的第一?a 是代?异步QasynchronousQ?/I> 吗?在发?HTTP hӞ不想让浏览器挂着{候服务器响应。相反,您想让浏览器l箋对用户与面的交互进行响应,q在服务器响应到达时再进行处理。ؓ了实现这个要求,可以?
上注册一个回调函敎ͼ然后异步地分z?
。然后控制就会返回浏览器Q当服务器响应到达时Q会调用回调函数?/P>
?Java Web 服务器上Q请求同其他
一样到达。在解析了请求参C后,servlet 调用必要的应用程序逻辑Q把响应序列化成 XMLQƈ?XML 写入
?/P>
回到客户端时Q现在调用注册在
上的回调函数Q处理服务器q回?XML 文档。最后,Ҏ服务器返回的数据Q用 JavaScript 操纵面?HTML DOMQ把用户界面更新。图 1 ?Ajax 往q过E的序图?/P>
现在您对 Ajax 往q过E有了一个高层面的认识。下面我放大其中的每一步骤Q进行更详细的观察。如果过E中q了路,请回头看?1 —?׃ Ajax 方式的异步性质Q所以顺序ƈ非十分简单?/P>
我将?Ajax 序列的v点开始:创徏和分z来自浏览器?
。不q的是,不同的浏览器创徏
的方法各不相同。清?2 ?JavaScript 函数消除了这些依赖于览器的技巧,它可以检当前浏览器要用的正确方式Qƈq回一个可以用的
。最好是把它当作辅助代码Q只要把它拷贝到 JavaScript 库,q在需?
的时候用它可以了?/P>
/* * Returns a new XMLHttpRequest object, or false if this browser * doesn't support it */ function newXMLHttpRequest() { var xmlreq = false; if (window.XMLHttpRequest) { // Create XMLHttpRequest object in non-Microsoft browsers xmlreq = new XMLHttpRequest(); } else if (window.ActiveXObject) { // Create XMLHttpRequest via MS ActiveX try { // Try to create XMLHttpRequest in later versions // of Internet Explorer xmlreq = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e1) { // Failed to create required ActiveXObject try { // Try version supported by older versions // of Internet Explorer xmlreq = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e2) { // Unable to create an XMLHttpRequest with ActiveX } } } return xmlreq; }
E后我将讨论处理那些不支?
的浏览器的技术。目前,CZ假设清单 2 ?
函数总能q回
实例?/P>
q回CZ的购物R场景Q我惌当用户在目录目上点?Add to Cart 时启?Ajax 交互。名?
?
处理函数负责通过 Ajax 调用来更新购物R的状态(请参?清单 1Q。正如清?3 所C,
需要做的第一件事是通过调用清单 2 ?
函数得到
对象。接下来Q它注册一个回调函敎ͼ用来接收服务器响应(我稍后再详细解释q一步;请参?清单 6Q?/P>
因ؓh会修Ҏ务器上的状态,所以我用 HTTP
做这个工作。通过
发送数据要求三个步骤。第一Q需要打开与要通信的服务器资源?
q接 —?在这个示例中Q服务器资源是一个映到 URL
?servlet。然后,我在
上设|一个头Q指明请求的内容是表?~码的数据。最后,我用表单~码的数据作求体发送请求?/P>
清单 3 把这些步骤放在了一赗?/P>
清单 3. 分派 Add to Cart XMLHttpRequest
/* * Adds an item, identified by its product code, to the shopping cart * itemCode - product code of the item to add. */ function addToCart(itemCode) { // Obtain an XMLHttpRequest instance var req = newXMLHttpRequest(); // Set the handler function to receive callback notifications // from the request object var handlerFunction = getReadyStateHandler(req, updateCart); req.onreadystatechange = handlerFunction; // Open an HTTP POST connection to the shopping cart servlet. // Third parameter specifies request is asynchronous. req.open("POST", "cart.do", true); // Specify that the body of the request contains form data req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); // Send form encoded data stating that I want to add the // specified item to the cart. req.send("action=add&item="+itemCode); }
q就是徏?Ajax 往q过E的W一部分Q即创徏和分z来自客h?HTTP h。接下来是用来处理请求的 Java servlet 代码?/P>
?servlet 处理
Q与处理普通的览?HTTP h一栗可以用
得到?POST h体中发送的表单~码数据。Ajax h被放q与来自应用E序的常?Web h一L
中。对于示例购物R场景来说Q这很有用,因ؓq让我可以把购物车状态封装在 JavaBean 中,q在h之间在会话中l持q个状态?/P>
清单 4 是处?Ajax h、更新购物R的简?servlet 的一部分?CODE> bean 是从用户会话中获得的QƈҎh参数更新它的状态。然?
被序列化?XMLQXML 又被写入
。重要的是把响应的内容类型设|ؓ
Q否?
不会把响应内容解析成 XML DOM?/P>
public void doPost(HttpServletRequest req, HttpServletResponse res) throws java.io.IOException { Cart cart = getCartFromSession(req); String action = req.getParameter("action"); String item = req.getParameter("item"); if ((action != null)&&(item != null)) { // Add or remove items from the Cart if ("add".equals(action)) { cart.addItem(item); } else if ("remove".equals(action)) { cart.removeItems(item); } } // Serialize the Cart's state to XML String cartXml = cart.toXml(); // Write XML to response. res.setContentType("application/xml"); res.getWriter().write(cartXml); }
清单 5 昄?
Ҏ生成的示?XML。它很简单。请注意
元素?
属性,它是
生成的一个时间戳?/P>
<?xml version="1.0"?> <cart generated="1123969988414" total="$171.95"> <item code="hat001"> <name>Hat</name> <quantity>2</quantity> </item> <item code="cha001"> <name>Chair</name> <quantity>1</quantity> </item> <item code="dog001"> <name>Dog</name> <quantity>1</quantity> </item> </cart>
如果查看应用E序源代码(可以?FONT color=#000000>下蝲一节得刎ͼ中的 Cart.javaQ可以看到生?XML 的方式只是把字符串添加在一赗虽然对q个CZ来说_了,但是对于?Java 代码生成 XML 来说则是最差的方式。我在q个pd的下一期中介绍一些更好的方式?/P>
现在您已l知道了
响应
的方式。下一件事是q回客户端,查看如何?XML 响应更新面状态?/P>
?
属性是一个数|它指求生命周期的状态。它?0Q代表“未初始化”)变化?4Q代表“完成”)。每?
变化Ӟ
事gp发,?
属性指定的事g处理函数p调用?/P>
?FONT color=#000000>清单 3中已l看C如何调用
函数创徏事g处理函数。然后把q个事g处理函数分配l?
属性?CODE> 利用了这样一个事实:函数?JavaScript 中的一U对象。这意味着函数可以是其他函数的参数Q也可以创徏和返回其他函数?CODE> 的工作是q回一个函敎ͼ?
是否已经完成Qƈ?XML 响应传递给调用者指定的事g处理函数。清?6 ?
的代码?/P>
清单 6. getReadyStateHandler() 函数
/* * Returns a function that waits for the specified XMLHttpRequest * to complete, then passes its XML response to the given handler function. * req - The XMLHttpRequest whose state is changing * responseXmlHandler - Function to pass the XML response to */ function getReadyStateHandler(req, responseXmlHandler) { // Return an anonymous function that listens to the // XMLHttpRequest instance return function () { // If the request's status is "complete" if (req.readyState == 4) { // Check that a successful server response was received if (req.status == 200) { // Pass the XML payload of the response to the // handler function responseXmlHandler(req.responseXML); } else { // An HTTP problem has occurred alert("HTTP error: "+req.status); } } } }
HTTP 状态码
在清?6 中,?
?
属性以查看h是否成功完成?CODE> 包含服务器响应的 HTTP 状态码。在执行单的
?
hӞ可以假设M大于 200 QOKQ的码都是错误。如果服务器发送重定向响应Q例?301 ?302Q,览器会透明地进行重定向q从新的位置获取资源Q?CODE> 看不到重定向状态码。而且Q浏览器会自动添?
头到所?
Q这样客户代码永q也不用处理 304Q未l修改)服务器响应?/P>
是段相对复杂的代码,特别是如果您不习惯阅?JavaScript 的话。但是通过把这个函数放?JavaScript 库中Q就可以处理 Ajax 服务器响应,而不必处?
的内部细节。重要的是要理解如何在自q代码中?
?/P>
?FONT color=#000033>清单 3中看C
像这栯调用Q?CODE>。在q个CZ中,
q回的函数将查在
变量中的
是否已经完成Q然后用响应?XML 调用名ؓ
的函数?/P>
清单 7 ?
本n的代码。函数用 DOM 调用查购物R?XML 文档Q然后更?Web 面Q请参阅 清单 1Q,反映新的购物车内宏V这里的重点是用来从 XML DOM 提取数据的调用?CODE> 元素?
属性是?
序列化ؓ XML 时生成的一个时间戳Q检查它可以保证新的购物车数据不会被旧的数据覆盖。Ajax h天生是异步的Q所以这个检查可以处理服务器响应未按ơ序到达的情c?/P>
function updateCart(cartXML) { // Get the root "cart" element from the document var cart = cartXML.getElementsByTagName("cart")[0]; // Check that a more recent cart document hasn't been processed // already var generated = cart.getAttribute("generated"); if (generated > lastCartUpdate) { lastCartUpdate = generated; // Clear the HTML list used to display the cart contents var contents = document.getElementById("cart-contents"); contents.innerHTML = ""; // Loop over the items in the cart var items = cart.getElementsByTagName("item"); for (var I = 0 ; I < items.length ; I++) { var item = items[I]; // Extract the text nodes from the name and quantity elements var name = item.getElementsByTagName("name")[0] .firstChild.nodeValue; var quantity = item.getElementsByTagName("quantity")[0] .firstChild.nodeValue; // Create and add a list item HTML element for this cart item var li = document.createElement("li"); li.appendChild(document.createTextNode(name+" x "+quantity)); contents.appendChild(li); } } // Update the cart's total using the value from the cart document document.getElementById("total").innerHTML = cart.getAttribute("total"); }
到此Q整?Ajax 往q过E完成了Q但是您可能惌 Web 应用E序q行一下查看实际效果(请参?下蝲 一节)。这个示例非常简单,有很多需要改q之处。例如,我包含了从购物R中清除项目的服务器端代码Q但是无法从 UI 讉K它。作Z个好的练习,误着在应用程序现有的 JavaScript 代码之上构徏够实现这个功能的代码?/P>
像M技术一P使用 Ajax 也有许多出错的可能性。我目前在这里讨论的问题q缺乏容易的解决ҎQ但是会随着 Ajax 的成熟而改q。随着开发h员社区增加开?Ajax 应用E序的经验,会记录下最佛_践和指南?/P>
Ajax 开发h员面临的一个最大问题是Q在没有
可用时该如何响应Q虽然主要的C览器都支持
Q但仍然有少数用L览器不支持Q或者浏览器的安全设|阻止?
。如果开发的 Web 应用E序要部|在企业内部|,那么可能拥有指定支持哪种览器的权力Q从而可以认?
总能使用。但是,如果要部|在公共 Web 上,那么必d心,如果假设
可用Q那么就可能会阻止那些用旧的浏览器、残疾h专用览器和手持讑֤上的轻量U浏览器的用户用您的应用程序?/P>
所以,您应当努力让应用E序“^E降U”,在没?
支持的浏览器中也能够工作。在购物车的CZ中,把应用程序降U的最好方式可能是?Add to Cart 按钮执行一个常规的表单提交Q刷新页面来反映购物车更新后的状态。Ajax 的行为应当在面装入的时候就通过 JavaScript d到页面,只有?
可用时才?JavaScript 事g处理函数附加到每?Add to Cart 按钮。另一U方式是在用L录时?
是否可用Q然后相应地提供应用E序?Ajax 版本或基于表单的普通版本?/P>
关于 Ajax 应用E序的某些可用性问题比较普遍。例如,让用L道他们的输入已经注册了可能是重要的,因ؓ沙漏光标?spinning 览器的常用反馈机制“throbber”对
不适用。一U技术是用“Now updating...”类型的信息替换 Submit 按钮Q这L户在{候响应期间就不会反复单击按钮了?/P>
另一个问题是Q用户可能没有注意到他们正在查看的页面的某一部分已经更新了。可以用不同的可视技术,把用L眼球带到面的更新区域,从而缓解这个问题。由 Ajax 更新面造成的其他问题还包括Q“破坏了”浏览器的后退按钮Q地址栏中?URL 也无法反映页面的整个状态,妨碍了设|书{。请参阅 参考资?/FONT> 一节,获得专门解决 Ajax 应用E序可用性问题的文章?/P>
?Ajax 实现代替普通的Z表单?UIQ会大大提高Ҏ务器发出的请求数量。例如,一个普通的 Google Web 搜烦Ҏ务器只有一个请求,是在用户提交搜烦表单时出现的。?Google Suggest 试图自动完成搜烦术语Q它要在用户输入时向服务器发送多个请求。在开?Ajax 应用E序Ӟ要注意将要发送给服务器的h数量以及由此造成的服务器负荷。降低服务器负蝲的办法是Q在客户Z对请求进行缓冲ƈ且缓存服务器响应Q如果可能的话)。还应该试?Ajax Web 应用E序设计为在客户Z执行可能多的逻辑Q而不必联l服务器?/P>
非常重要的是Q要理解无法保证
会按照分z֮们的序完成。实际上Q应当假讑֮们不会按序完成Qƈ且在设计应用E序时把q一点记在心上。在购物车的CZ中,使用最后更新的旉x保新的购物车数据不会被旧的数据覆盖Q请参阅清单 7Q。这个非常基本的方式可以用于购物车场景,但是可能不适合其他场景。所以在设计时请考虑如何处理异步的服务器响应?/P>
现在您对 Ajax 的基本原则应当有了很好的理解Q对参与 Ajax 交互的客L和服务器端组件也应当有了初步的知识。这些是Z Java ?Ajax Web 应用E序的构造块。另外,您应当理解了伴随 Ajax 方式的一些高U设计问题。创建成功的 Ajax 应用E序要求整体考虑Q从 UI 设计?JavaScript 设计Q再到服务器端架构;但是您现在应当已l武装了考虑其他q些斚w所需要的核心 Ajax 知识?/P>
如果使用q里演示的技术编写大?Ajax 应用E序的复杂性让您觉得恐慌,那么有好消息l您。由?Struts、Spring ?Hibernate q类框架的发展把 Web 应用E序开发从底层 Servlet API ?JDBC 的细节中抽象出来Q所以正在出现简?Ajax 开发的工具包。其中有些只侧重于客LQ提供了向页面添加可视效果的便方式,或者简化了?
的用。有些则走得更远Q提供了从服务器端代码自动生?Ajax 接口的方式。这些框架替您完成了J重的Q务,所以您可以采用更高U的方式q行 Ajax 开发。我在这个系列中研I其中的一些?/P>
Ajax C正在快速前q,所以会有大量有价值的信息涌现。在阅读q个pd的下一期之前,我徏议您参?参考资?/FONT> 一节中列出的文章,特别是如果您是刚接触 Ajax 或客L开发的话。您q应当花些时间研I示例源代码q考虑一些增强它的方式?/P>
在这个系列的下一文章中Q我深入讨?
APIQƈ推荐一些从 JavaBean 方便地创?XML 的方式。我q将介绍替代 XML q行 Ajax 数据传递的方式Q例?JSONQJavaScript Object NotationQ轻量数据交换格式?/P>
]]>