Java Votary

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  48 随笔 :: 1 文章 :: 80 评论 :: 0 Trackbacks

#

原文:http://www.blogjava.net/eamoi/archive/2005/11/01/17639.html

有网友反映说《AJAX开发简略》配文代码不全。其实应该是全的,只是要把包括框架和两个示例的程序都整合起来看。这里把全部的代码贴出来,需要的朋友可以看看。
sample1_1.jsp:
<%@ page contentType="text/html; charset=gb2312" language="java" errorPage="" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>无标题文档</title>
<script language="javascript">
 var http_request = false;
 function send_request(url) {//初始化、指定处理函数、发送请求的函数
  http_request = false;
  //开始初始化XMLHttpRequest对象
  if(window.XMLHttpRequest) { //Mozilla 浏览器
   http_request = new XMLHttpRequest();
   if (http_request.overrideMimeType) {//设置MiME类别
    http_request.overrideMimeType('text/xml');
   }
  }
  else if (window.ActiveXObject) { // IE浏览器
   try {
    http_request = new ActiveXObject("Msxml2.XMLHTTP");
   } catch (e) {
    try {
     http_request = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) {}
   }
  }
  if (!http_request) { // 异常,创建对象实例失败
   window.alert("不能创建XMLHttpRequest对象实例.");
   return false;
  }
  http_request.onreadystatechange = processRequest;
  // 确定发送请求的方式和URL以及是否同步执行下段代码
  http_request.open("GET", url, true);
  http_request.send(null);
 }
 // 处理返回信息的函数
    function processRequest() {
        if (http_request.readyState == 4) { // 判断对象状态
            if (http_request.status == 200) { // 信息已经成功返回,开始处理信息
                alert(http_request.responseText);
            } else { //页面不正常
                alert("您所请求的页面有异常。");
            }
        }
    }
 function userCheck() {
  var f = document.form1;
  var username = f.username.value;
  if(username=="") {
   window.alert("用户名不能为空。");
   f.username.focus();
   return false;
  }
  else {
   send_request('sample1_2.jsp?username='+username);
  }
 }
</script>
<link href="css/style.css" rel="stylesheet" type="text/css">
</head>

<body>
<form name="form1" action="" method="post">
用户名:<input type="text" name="username" value="">&nbsp;
<input type="button" name="check" value="唯一性检查" onClick="userCheck()">
<input type="submit" name="submit" value="提交">
</form>
<!--span style="cursor: pointer; text-decoration: underline" onclick="send_request('2.jsp?username=educhina')">Send a request</span-->
</body>
</html>

sample1_2.jsp:
<%@ page contentType="text/html; charset=gb2312" language="java" errorPage="" %>
<%
String playPos = request.getParameter("playPos");
if("pos_1".equals(playPos)) out.print("用户名已经被注册,请更换一个用户名。");
else out.print("用户名尚未被使用,您可以继续。");
%>

sample2_1.jsp:
<%@ page contentType="text/html; charset=gb2312" language="java" errorPage="" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>无标题文档</title>
<script language="javascript">
 var http_request = false;
 var currentPos = null;
 function send_request(url) {//初始化、指定处理函数、发送请求的函数
  http_request = false;
  //开始初始化XMLHttpRequest对象
  if(window.XMLHttpRequest) { //Mozilla 浏览器
   http_request = new XMLHttpRequest();
   if (http_request.overrideMimeType) {//设置MiME类别
    http_request.overrideMimeType('text/xml');
   }
  }
  else if (window.ActiveXObject) { // IE浏览器
   try {
    http_request = new ActiveXObject("Msxml2.XMLHTTP");
   } catch (e) {
    try {
     http_request = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) {}
   }
  }
  if (!http_request) { // 异常,创建对象实例失败
   window.alert("不能创建XMLHttpRequest对象实例.");
   return false;
  }
  http_request.onreadystatechange = processRequest;
  // 确定发送请求的方式和URL以及是否同步执行下段代码
  http_request.open("GET", url, true);
  http_request.send(null);
 }
 // 处理返回信息的函数
    function processRequest() {
        if (http_request.readyState == 4) { // 判断对象状态
            if (http_request.status == 200) { // 信息已经成功返回,开始处理信息
                //alert(http_request.responseText);
    document.getElementById(currentPos).innerHTML = http_request.responseText;
            } else { //页面不正常
                alert("您所请求的页面有异常。");
            }
        }
    }
 //显示部门下的岗位
 function showRoles(obj) {
  document.getElementById(obj).parentNode.style.display = "";
  document.getElementById(obj).innerHTML = "正在读取数据..."
  currentPos = obj;
  send_request("sample2_2.jsp?playPos="+obj);
 }
</script>
<link href="css/style.css" rel="stylesheet" type="text/css">
</head>

<body>
<table width="200" border="0" cellspacing="0" cellpadding="0">
    <tr>
        <td height="20"><a href="javascript:void(0)" onClick="showRoles('pos_1')">经理室</a></td>
    </tr>
    <tr style="display:none">
        <td height="20" id="pos_1">&nbsp;</td>
    </tr>
    <tr>
        <td height="20"><a href="javascript:void(0)" onClick="showRoles('pos_2')">开发部</a></td>
    </tr>
    <tr style="display:none ">
        <td id="pos_2" height="20">&nbsp;</td>
    </tr>
</table>
<!--a href="javascript:void(0)" onClick="showRoles('pos_1')">测试</a-->
<!--span style="cursor: pointer; text-decoration: underline" onclick="send_request('2.jsp?username=educhina')">Send a request</span-->
</body>
</html>

sample2_2.jsp:
<%@ page contentType="text/html; charset=gb2312" language="java" errorPage="" %>
<%
String playPos = request.getParameter("playPos");
if("pos_1".equals(playPos)) out.print("&nbsp;&nbsp;总经理<br>&nbsp;&nbsp;副总经理");
else if("pos_2".equals(playPos)) out.println("&nbsp;&nbsp;总工程师<br>&nbsp;&nbsp;软件工程师");
%>

posted @ 2005-11-23 20:26 Dion 阅读(772) | 评论 (0)编辑 收藏

     摘要: http://www.blogjava.net/eamoi/archive/2005/10/31/17489.html AJAX开发简略   文档说明   参与人员:   作者 网名 联络 柯自聪 eamoi   educhina ...  阅读全文
posted @ 2005-11-23 20:25 Dion 阅读(556) | 评论 (0)编辑 收藏

     摘要: ASP服务 ASP是英文Application Service Provider的缩写,通常中文译为应用服务提供商,它是指配置、租赁和管理应用解决方案,为商业、个人提供服务的专业化服务公司。通俗地说,ASP是一种业务租赁模式,企业用户可以直接租用ASP的计算机及软件系统进行自己的业务管理,从而节省一大笔用于IT产品技术购买和运行的资金。 在国外,ASP最早出现于1998年,是伴随着互联...  阅读全文
posted @ 2005-11-23 20:23 Dion 阅读(612) | 评论 (0)编辑 收藏

     摘要: (转)ASP的行业介绍   一、ASP的概念     1、 几个比喻    想吃鸡蛋,用不着买只母鸡回家,想喝牛奶,也不需要牵一头奶牛回家。同理,在互联网时代,通过互联网,企业日常的生产、经营、管理过程中使用的应用服务都可以让别人帮你打点,你可以节省时间和人力,他们向你收取租金,他们就是ASP...  阅读全文
posted @ 2005-11-23 20:22 Dion 阅读(671) | 评论 (0)编辑 收藏

ASP英文全称为Application Service Provider,中文译为应用服务供应商。 这是随着Internet革命将人类从工业经济时代推向电子商务时代,并重塑信息技术(Information Technology,简称IT)产业的未来发展方向所应运而生的一种崭新的产品及服务模式。

ASP的本质在于:这种应用,从所需的硬件平台到应用软件、企业内部资源管理和业务流程的处理,不是发生在企业本地的实施上,而是由特定的供应商提供,并由供应商进行维护、管理及更新,企业(ASP的用户)通过租赁、承包等方式获得服务。

因此,ASP产生和发展的前提条件主要基于以下IT技术的成熟:
 
Internet
的普及:Internet逐步深入人们生活,大量的基于Web的解决方案不断涌现,这些都使得远程的基于主机的应用方案成为可能。
 
带宽不断增大和价格不断下降:增长的通信性能和持续减少的带宽费用,使主机上的应用程序可以通过Internet和瘦客户机来访问。
 
客户机/服务器环境下的可共享应用:在ASP概念中的远程访问,用户早已经在客户机/服务器环境下习以为常,这使得远程访问和共享应用成为可接受的一种业务模式
 
浏览器成为广泛接受的图形界面应用程序:浏览器技术的的广泛应用及开发为基于Web的计算和瘦客户机的计算聚集了足够的技术及人力资源,以及良好的用户基础。
 
电子商务解决方案的潜力:先进的电子商务解决方案,与ASP的概念一起分享了许多棘手的业务和技术问题,例如系统的安全性和可靠性。所以,电子商务的巨大动力也在推动ASP的前进。

几年前,当应用服务提供商(ASP)刚刚出现时,它似乎是帮助企业投身数字时代的最佳选择:ASP们开发、运行和维护商用软件,企业只需按月或按年缴纳租费,就可以获得需要的应用软件。然而,互联网泡沫的破裂使ASP的成功如昙花一现,当大多数Start-up公司倒下后,ASP们似乎也偃旗息鼓了。

究其原因,技术不成熟是关键因素。Yankee Group的分析家认为,“5年前,ASP技术还不成熟,它不能定制、不具备离线能力、不能与其他系统集成、缺少这样或那样的功能,因此ASP们难以逃生也就成为必然。”但现在情况不同了,一方面是技术的进步使客户通过Internet访问商用软件变得更安全和容易;另一方面是全球经济的不景气促使企业再次把目光投向ASP,毕竟,与购买许可证和高昂的维护费用相比,按月或按年付费的软件使用方式更能节省成本,至少在短时间内是如此。通常情况下,诸如OracleSAP等公司的大型软件系统都需要有相当大的初期投资,用于软件的购买、安装和培训,一旦投入使用,还必须支付维护和软件升级费用。与此相反,如果向ASP租用软件,所有这些投资都可以节省下来,企业所需要付出的不过是每月数百美元的租金而已,况且这笔钱完全可以纳入企业的日常开支。

目前的ASP主要针对企业市场,采用远程租用的方式,所提供的服务可以是集成硬件、软件和网络技术来为大中小各类企业提供应用解决方案;也可以是安装、配置、定做和管理定制的封装应用软件;有些ASP甚至可以提供商务处理咨询和外包服务。  
ASP
不再试图通过Internet提供为企业网设计的传统客户机/服务器应用,而是创建适合Internet传送的应用。因此它能够更好地提供可伸缩和定制的应用,更容易与其他系统集成。除了最初的标准软件以一对多的方式租赁使用之外,新的ASP应用模式还增加了个性化的服务。个性化服务从某种意义上说更接近于传统的应用软件系统开发,用户仍然要为软件开发支付一笔可观的开发费用,所不同的是系统赖以传输数据的载体是开放的Internet。目前国外有观点认为,ASP最适合的应用领域是财务、电子商务和客户关系管理;国内专家则认为,在人力资源管理上ASP也可以有所发挥。此外,新的信息传输技术的应用也为ASP弥补了Internet带来的一些不足,比如VPN可以保证数据的安全性,有利于吸引一些对安全性有更高要求的用户;宽带技术则使更快的速度和更丰富的功能成为可能。
从未来发展来看,影响ASP发展的主要有以下几个因素
   
1
)通讯频宽的限制
   
ASP
商业模式需要有充足的带宽资源支持,目前我国的通讯基础设施有了很大的发展,但是带宽资源还没到富余的程度,因此,频宽资源可能会成为制约ASP发展的一个重要因素。
   
2
)网络安全性
   
网络的安全性包括了两层含义:一是技术上能够抵御黑客的非法侵入,另一层更重要的含义是ASP商本身的职业操守达到一定的层次,顾客的商业秘密不会因ASP自身的原因而泄露。
   
3
)社会信用体系
   
我们看到美国的ASP业发展迅速,应该看到他们多年积累的信用体系其实是ASP发展的关键动力。然而,反观国内的企业,普遍缺乏信用观念,这极大地增加了ASP用户的交易成本和投资风险。
   
4
)品牌因素
  
由于ASP这一商业模式本身需要很高的技术要求、安全要求和信用要求,ASP商的品牌因素也特别重要。 

虽然技术是ASP成功的原动力之一,但是ASP的成功关键不仅在于先进技术和人力资源的掌握,也依赖于对相关业务流程和信息管理的行业经验,因此目前的少数ASP所提供的功能远不能满足企业用户的需要,无法达到真正的ASP所提供的功能。

从市场前景来看,ASP已经占有了一席之地,它从根本上降低了客户的TCO。对客户来说,向ASP租用软件的风险很小,按照Enterprise Applications Consulting公司的分析家的话来说“你不必购买永久许可而只在某些时候才使用软件,你所买的就是你所需要的”。除此之外,租用软件可以减少企业内部对IT人员的需求,甚至有可能取消企业的IT部门,因为有ASP替您维护和升级应用程序。尽管如此,仍然有相当的潜在客户会担心租用软件可能面临的问题:诸如无法让第三方来替它处理有价值的数据;或者是担心托管系统的安全问题以及被托管的系统能否与来自其他厂商的应用系统协同工作。这些技术上的问题都需要被妥善解决,同时也会成ASP技术继续发展的原动力。但无论怎样,随着商用软件复杂度的增加以及企业降低成本的需求,ASP模式将成为企业IT应用发展的大趋势。

以下是软件公司为某电器有限公司定制的分销体系解决方案,也许可以从中更深的了解到基于ASP的解决方案的魅力。  

(1)信息化动因分析  
   
公司成立于1994年,现有员工近千名,目前的产品主要有食品搅拌机、榨汁机、全自动豆浆机等,2000年其销售额达1亿元。作为一家制造型的企业,产品技术和研发是基础,产品销售则是最终目标,所以企业信息化的核心目标是:理顺企业管理流程为销售服务。  
   
目前公司在全国有近1000个 销售网点。以前在销售环节上出的问题比较多,给公司造成了很大的损失。因此,公司制订出一套规范的业务流程,来监督管理下属的各地办事处。改进流程的结果 是实行“两级管理一级核算”的体制,总公司进行独立核算。在各地的办事处只负责销售,记录销售费用,客户与总公司直接结算。  
   
这 种方式堵住了管理上漏洞,只是手工重复的劳动比较多。总公司和办事处之间的信息交流,以前是通过电话、传真、电子邮件方式实现的,各办事处手工录入的大量 数据传到总公司后,汇总处理时仍然需要再次重复录入,工作量极其繁重,处理效率非常低。同时,由于人工汇总存在较大的计算出错可能性,因此上报给企业管理 层的销售汇总数据的可靠性和及时性都比较差。而且在手工管理模式下,每周只能进行12次销售汇总数据的统计和报告,无法实现对办事处存货、客户应收帐款等明细数据的实时额度控制。  
 
(2)
分销管理系统解决方案  
   
针对目前存在的问题,软件公司提出分销系统的ASP模 式,即所有数据都集中在总公司的数据库中,而办事处只需要登录进系统,在客户端将所发生的数据按照系统模块的要求输入进去,系统将自动生成各种数据,并允 许相应级别的人实时查询其相应权限下的所有相关数据。这种模式正好满足其对众多分子公司和办事处的管理要求。同时在实施整个系统时,先将数据存放在软件公 司的服务器上。在实施完成后,可以选择两种方式:一是自己建服务器和数据中心并承担系统维护工作;二是租用软件公司提供的网站和数据库维护增值服务,完全 不再投入硬件和人员。  
  
实 施系统管理之后,该公司的整体业务流程系统由业务管理子系统和财务管理子系统两部分构成。业务管理子系统主要功能包括:客户端电子商务功能、销售过程管 理、库存管理、应收帐款管理、各类计划管理、商品档案管理、客户档案管理、统计查询、系统管理等;财务管理子系统主要功能为日常费用管理。该分销管理系统 在 “用友伟库企业分销管理软件”的基础上进行了适量的二次开发。  
 
(3)
分销管理系统效果评析  
  
实 施了这套系统以后,以往许多无法解决的问题就迎刃而解。各地办事处只要正确输入货物出入库数据,系统平台的总数据累计自动生成,与以往用手工合计的速度相 比有了很大的提升。各办事处可以进入公司网站,在分销系统平台中本办事处的界面进行操作,减少了运营费用。各地分公司和办事处均可通过系统提供的业务处理 平台将每日订单、销售、存货等数据输入系统,自动处理/生成各类销售统计报表;管理层可根据不同的权限随时了解销售、产品库存及资金情况,浏览系统提供的部分数据分析报告,为管理决策层提供更准确和及时的量化依据。  
   
由于采用ASP运行模式,实现了异地商务集中管理。海菱公司不需要单独构建昂贵的数据处理中心;分支机构无需安装专用的客户端软件,采用标准浏览器上网即可使用该系统的全部功能,数据处理全部在数据中心完成和存储,数据安全性高,操作简单,系统维护成本低。

posted @ 2005-11-23 20:22 Dion 阅读(588) | 评论 (0)编辑 收藏

转自http://dev2dev.bea.com.cn/techdoc/2005110103.html


Ajax简介

时间:2005-11-01
作者:David Teare
浏览次数: 1786
本文关键字:ajaxdhtmldwr javascript
文章工具
推荐给朋友 推荐给朋友
打印文章 打印文章

  作为J2EE开发人员,我们似乎经常关注“后端机制(backend mechanics)”。我们通常会忘记,J2EE的主要成功之处在Web应用程序方面;许多原因使得人们喜欢利用Web开发应用程序,但主要还是因为其 易于部署的特点允许站点以尽可能低的成本拥有上百万的用户。遗憾的是,在过去几年中,我们在后端投入了太多的时间,而在使我们的Web用户界面对用户自然 和响应灵敏方面却投入不足。

  本文介绍一种方法,Ajax,使用它可以构建更为动态和响应更灵敏的Web应用程序。该方法的关键在于对浏览器端的JavaScript、 DHTML和与服务器异步通信的组合。本文也演示了启用这种方法是多么简单:利用一个Ajax框架(指DWR)构造一个应用程序,它直接从浏览器与后端服 务进行通信。如果使用得当,这种强大的力量可以使应用程序更加自然和响应灵敏,从而提升用户的浏览体验。

  该应用程序中所使用的示例代码已打包为单独的WAR文件,可供下载。

简介

  术语Ajax用来描述一组技术,它使浏览器可以为用户提供更为自然的浏览体验。在Ajax之前,Web站点强制用户进入提交/等待/重新显示范 例,用户的动作总是与服务器的“思考时间”同步。Ajax提供与服务器异步通信的能力,从而使用户从请求/响应的循环中解脱出来。借助于Ajax,可以在 用户单击按钮时,使用JavaScript和DHTML立即更新UI,并向服务器发出异步请求,以执行更新或查询数据库。当请求返回时,就可以使用 JavaScript和CSS来相应地更新UI,而不是刷新整个页面。最重要的是,用户甚至不知道浏览器正在与服务器通信:Web站点看起来是即时响应 的。

  虽然Ajax所需的基础架构已经出现了一段时间,但直到最近异步请求的真正威力才得到利用。能够拥有一个响应极其灵敏的Web站点确实激动人 心,因为它最终允许开发人员和设计人员使用标准的HTML/CSS/JavaScript堆栈创建“桌面风格的(desktop-like)”可用性。

  通常,在J2EE中,开发人员过于关注服务和持久性层的开发,以至于用户界面的可用性已经落后。在一个典型的J2EE开发周期中,常常会听到这样的话,“我们没有可投入UI的时间”或“不能用HTML实现”。但是,以下Web站点证明,这些理由再也站不住脚了:

  所有这些Web站点都告诉我们,Web应用程序不必完全依赖于从服务器重新载入页面来向用户呈现更改。一切似乎就在瞬间发生。简而言之,在涉及到用户界面的响应灵敏度时,基准设得更高了。

定义Ajax

  Adaptive Path公司的Jesse James Garrett这样定义Ajax

  Ajax不是一种技术。实际上,它由几种蓬勃发展的技术以新的强大方式组合而成。Ajax包含:

  • 基于XHTMLCSS标准的表示;
  • 使用Document Object Model进行动态显示和交互;
  • 使用XMLHttpRequest与服务器进行异步通信;
  • 使用JavaScript绑定一切。

  这非常好,但为什么要以Ajax命名呢?其实术语Ajax是由Jesse James Garrett创造的,他说它是“Asynchronous JavaScript + XML的简写”。

Ajax的工作原理

  Ajax的核心是JavaScript对象XmlHttpRequest。该对象在Internet Explorer 5中首次引入,它是一种支持异步请求的技术。简而言之,XmlHttpRequest使您可以使用JavaScript向服务器提出请求并处理响应,而不 阻塞用户。

  在创建Web站点时,在客户端执行屏幕更新为用户提供了很大的灵活性。下面是使用Ajax可以完成的功能:

  • 动态更新购物车的物品总数,无需用户单击Update并等待服务器重新发送整个页面。
  • 提升站点的性 能,这是通过减少从服务器下载的数据量而实现的。例如,在Amazon的购物车页面,当更新篮子中的一项物品的数量时,会重新载入整个页面,这必须下载 32K的数据。如果使用Ajax计算新的总量,服务器只会返回新的总量值,因此所需的带宽仅为原来的百分之一。
  • 消除了每次用户输入时的页面刷新。例如,在Ajax中,如果用户在分页列表上单击Next,则服务器数据只刷新列表而不是整个页面。
  • 直接编辑表格数据,而不是要求用户导航到新的页面来编辑数据。对于Ajax,当用户单击Edit时,可以将静态表格刷新为内容可编辑的表格。用户单击Done之后,就可以发出一个Ajax请求来更新服务器,并刷新表格,使其包含静态、只读的数据。

  一切皆有可能!但愿它能够激发您开始开发自己的基于Ajax的站点。然而,在开始之前,让我们介绍一个现有的Web站点,它遵循传统的提交/等待/重新显示的范例,我们还将讨论Ajax如何提升用户体验。

Ajax可用于那些场景?——一个例子:MSN Money页面

  前几天,在浏览MSN Money页面的时候,有一篇关于房地产投资的文章引起了我的好奇心。我决定使用站点的“Rate this article”(评价本文)功能,鼓励其他的用户花一点时间来阅读这篇文章。在我单击vote按钮并等待了一会儿之后,整个页面被刷新,在原来投票问题所在的地方出现了一个漂亮的感谢画面。

  而Ajax能够使用户的体验更加愉快,它可以提供响应更加灵敏的UI,并消除页面刷新所带来的闪烁。目前,由于要刷新整个页面,需要传送大量的 数据,因为必须重新发送整个页面。如果使用Ajax,服务器可以返回一个包含了感谢信息的500字节的消息,而不是发送26,813字节的消息来刷新整个 页面。即使使用的是高速Internet,传送26K和1/2K的差别也非常大。同样重要的是,只需要刷新与投票相关的一小节,而不是刷新整个屏幕。

  让我们利用Ajax实现自己的基本投票系统。

原始的Ajax:直接使用XmlHttpRequest

  如上所述,Ajax的核心是JavaScript对象XmlHttpRequest。下面的示例文章评价系统将带您熟悉Ajax的底层基本知识:http://tearesolutions.com/ajax-demo/raw-ajax.html。注:如果您已经在本地WebLogic容器中安装了ajax-demo.war,可以导航到http://localhost:7001/ajax-demo/raw-ajax.html

  浏览应用程序,参与投票,并亲眼看它如何运转。熟悉了该应用程序之后,继续阅读,进一步了解其工作原理细节。

  首先,您拥有一些简单的定位点标记,它连接到一个JavaScriptcastVote(rank)函数。
function castVote(rank) {
var url = "/ajax-demo/static-article-ranking.html";
var callback = processAjaxResponse;
executeXhr(callback, url);
}

  该函数为您想要与之通信的服务器资源创建一个URL并调用内部函数executeXhr,提供一个回调JavaScript函数,一旦服务器响 应可用,该函数就被执行。由于我希望它运行在一个简单的Apache环境中,“cast vote URL”只是一个简单的HTML页面。在实际情况中,被调用的URL将记录票数并动态地呈现包含投票总数的响应。

  下一步是发出一个XmlHttpRequest请求:
function executeXhr(callback, url) {
// branch for native XMLHttpRequest object
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
req.onreadystatechange = callback;
req.open("GET", url, true);
req.send(null);
} // branch for IE/Windows ActiveX version
else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange = callback;
req.open("GET", url, true);
req.send();
}
}
}

  如您所见,执行一个XmlHttpRequest并不简单,但非常直观。和平常一样,在JavaScript领域,大部分的工作量都花在确保浏 览器兼容方面。在这种情况下,首先要确定XmlHttpRequest是否可用。如果不能用,很可能要使用Internet Explorer,这样就要使用所提供的ActiveX实现。

executeXhr()方法中最关键的部分是这两行:

req.onreadystatechange = callback;
req.open("GET", url, true);

  第一行定义了JavaScript回调函数,您希望一旦响应就绪它就自动执行,而req.open()方法中所指定的“true”标志说明您想要异步执行该请求。

  一旦服务器处理完XmlHttpRequest并返回给浏览器,使用req.onreadystatechange指派所设置的回调方法将被自动调用。
function processAjaxResponse() {
// only if req shows "loaded"
if (req.readyState == 4) {
// only if "OK"
if (req.status == 200) {
502 502'votes').innerHTML = req.responseText;
} else {
alert("There was a problem retrieving the XML data:
" +
req.statusText);
}
}
}

  该代码相当简洁,并且使用了几个幻数,这使得难以一下子看出发生了什么。为了弄清楚这一点,下面的表格(引用自http://developer.apple.com/internet/webcontent/xmlhttpreq.html)列举了常用的XmlHttpRequest对象属性。

属性

描述

onreadystatechange

每次状态改变所触发事件的事件处理程序

readyState

对象状态值:

  • 0 = 未初始化(uninitialized)
  • 1 = 正在加载(loading)
  • 2 = 加载完毕(loaded)
  • 3 = 交互(interactive)
  • 4 = 完成(complete)

responseText

从服务器进程返回的数据的字符串形式

responseXML

从服务器进程返回的DOM兼容的文档数据对象

status

从服务器返回的数字代码,比如404(未找到)或200(就绪)

statusText

伴随状态码的字符串信息

  现在processVoteResponse()函数开始显示出其意义了。它首先检查XmlHttpRequest的整体状态以保证它已经完成 (readyStatus == 4),然后根据服务器的设定询问请求状态。如果一切正常(status == 200),就使用innerHTML属性重写DOM的“votes”节点的内容。

  既然您亲眼看到了XmlHttpRequest对象是如何工作的,就让我们利用一个旨在简化JavaScript与Java应用程序之间的异步通信的框架来对具体的细节进行抽象。

Ajax: DWR方式

  按照与文章评价系统相同的流程,我们将使用Direct Web Remoting(DWR)框架实现同样的功能。

  假定文章和投票结果存储在一个数据库中,使用某种对象/关系映射技术来完成抽取工作。为了部署起来尽可能地简单,我们不会使用数据库进行持久性 存储。此外,为使应用程序尽可能通用,也不使用Web框架。相反,应用程序将从一个静态HTML文件开始,可以认为它由服务器动态地呈现。除了这些简化措 施,应用程序还应该使用Spring Framework关联一切,以便轻松看出如何在一个“真实的”应用程序中使用DWR。

  现在应该下载示例应用程序并熟悉它。该应用程序被压缩为标准的WAR文件,因此您可以把它放置到任何一个Web容器中——无需进行配置。部署完毕之后,就可以导航到http://localhost:7001/ajax_demo/dwr-ajax.html来运行程序。

  可以查看HTML 源代码,了解它如何工作。给人印象最深的是,代码如此简单——所有与服务器的交互都隐藏在JavaScript对象ajaxSampleSvc的后面。更加令人惊讶的是,ajaxSampleSvc服务不是由手工编写而是完全自动生成的!让我们继续,看看这是如何做到的。

引入DWR

  如同在“原始的Ajax”一节所演示的那样,直接使用XmlHttpRequest创建异步请求非常麻烦。不仅JavaScript代码冗长,而且必须考虑服务器端为定位Ajax请求到适当的服务所需做的工作,并将结果封送到浏览器。

  设计DWR的目的是要处理将Web页面安装到后端服务上所需的所有信息管道。它是一个Java框架,可以很轻松地将它插入到Web应用程序中, 以便JavaScript代码可以调用服务器上的服务。它甚至直接与Spring Framework集成,从而允许用户直接向Web客户机公开bean。

  DWR真正的巧妙之处是,在用户配置了要向客户机公开的服务之后,它使用反射来生成JavaScript对象,以便Web页面能够使用这些对象 来访问该服务。然后Web页面只需接合到生成的JavaScript对象,就像它们是直接使用服务一样;DWR无缝地处理所有有关Ajax和请求定位的琐 碎细节。

  让我们仔细分析一下示例代码,弄清它是如何工作的。

应用程序细节:DWR分析

  关于应用程序,首先要注意的是,它是一个标准的Java应用程序,使用分层架构(Layered Architecture)设计模式。使用DWR通过JavaScript公开一些服务并不影响您的设计。

  下面是一个简单的Java服务,我们将使用DWR框架直接将其向JavaScript代码公开:

package com.tearesolutions.service;

public interface AjaxSampleSvc {
Article castVote(int rank);
}

  这是一个被简化到几乎不可能的程度的例子,其中只有一篇文章可以投票。该服务由Spring管理,它使用的bean名是ajaxSampleSvc,它的持久性需求则依赖于ArticleDao。详情请参见applicationContext.xml。

  为了把该服务公开为JavaScript对象,需要配置DWR,添加dwr.xml文件到WEB-INF目录下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 0.4//EN"
"http://www.getahead.ltd.uk/dwr/dwr.dtd">

<dwr>
<allow>
<create creator="spring" javascript="ajaxSampleSvc">
<param name="beanName" value="ajaxSampleSvc" />
</create>
<convert converter="bean" match="com.tearesolutions.model.Article"/>
<exclude method="toString"/>
<exclude method="setArticleDao"/>
</allow>
</dwr>

  dwr.xml文件告诉DWR哪些服务是要直接向JavaScript代码公开的。注意,已经要求公开Spring bean ajaxSampleSvc。DWR将自动找到由应用程序设置的SpringApplicationContext。为此,必须使用标准的servlet 过滤器ContextLoaderListener来初始化Spring ApplicationContext。

  DWR被设置为一个servlet,所以把它的定义添加到web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD
Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<display-name>Ajax Examples</display-name>

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

<servlet>
<servlet-name>ajax_sample</servlet-name>
<servlet-class>com.tearesolutions.web.AjaxSampleServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet>
<servlet-name>dwr-invoker</servlet-name>
<display-name>DWR Servlet</display-name>
<description>Direct Web Remoter Servlet</description>
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>ajax_sample</servlet-name>
<url-pattern>/ajax_sample</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
</web-app>

  做完这些之后,可以加载http://localhost:7001/ajax-demo/dwr,看看哪些服务可用。结果如下:

图3. 可用的服务

  单击ajaxSampleSvc链接,查看有关如何在HTML页面内直接使用服务的示例实现。其中包含的两个JavaScript文件完成了大部分的功能:
<script type='text/javascript' 
src='/ajax-demo/dwr/interface/ajaxSampleSvc.js'></script>
<script type='text/javascript'
src='/ajax-demo/dwr/engine.js'></script>

ajaxSampleSvc.js是动态生成的:

function ajaxSampleSvc() { }

ajaxSampleSvc.castVote = function(callback, p0)
{
DWREngine._execute(callback, '/ajax-demo/dwr',
'ajaxSampleSvc', 'castVote', p0);
}

  现在可以使用JavaScript对象ajaxSampleSvc替换所有的XmlHttpRequest代码,从而重构raw-ajax.html文件。可以在dwr-ajax.html文件中看到改动的结果;下面是新的JavaScript函数:

function castVote(rank) {
ajaxSampleSvc.castVote(processResponse, rank);
}
function processResponse(data) {
var voteText = "

Thanks for Voting!

"
+ "

Current ranking: " + data.voteAverage
+ " out of 5

"
+ "

Number of votes placed: "
+ data.numberOfVotes + "

";
502 502'votes').innerHTML = voteText;
}

  惊人地简单,不是吗?由ajaxSampleSvc对象返回的Article域对象序列化为一个JavaScript对象,允许在它上面调用诸 如numberOfVotes()和voteAverage()之类的方法。在动态生成并插入到DIV元素“votes”中的HTML代码内使用这些数 据。

下一步工作

   在后续文章中,我将继续有关Ajax的话题,涉及下面这些方面:

  • Ajax最佳实践

  像许多技术一样,Ajax是一把双刃剑。对于一些用例,其应用程序其实没有必要使用Ajax,使用了反而有损可用性。我将介绍一些不适合使用的模式,突出说明Ajax的一些消极方面,并展示一些有助于缓和这些消极方面的机制。例如,对Netflix电影浏览器来说,Ajax是合适的解决方案吗?或者,如何提示用户确实出了一些问题,而再次单击按钮也无济于事?

  • 管理跨请求的状态

  在使用Ajax时,最初的文档DOM会发生一些变化,并且有大量的页面状态信息存储在客户端变量中。当用户跟踪一个链接到应用程序中的另一个页面时,状态就丢失了。当用户按照惯例单击Back按钮时,呈现给他们的是缓存中的初始页面。这会使用户感到非常迷惑!

  • 调试技巧

  使用JavaScript在客户端执行更多的工作时,如果事情不按预期方式进行,就需要一些调试工具来帮助弄清出现了什么问题。

结束语

  本文介绍了Ajax方法,并展示了如何使用它来创建一个动态且响应灵敏的Web应用程序。通过使用DWR框架,可以轻松地把Ajax融合到站点中,而无需担心所有必须执行的实际管道工作。

  特别感谢Getahead IT咨询公司的Joe Walker和他的团队开发出DWR这样神奇的工具。感谢你们与世界共享它!

下载

  本文中演示的应用程序源代码可供下载:ajax-demo.war(1.52 MB)。

参考资料

原文出处

An Introduction To Ajax

http://dev2dev.bea.com/pub/a/2005/08/ajax_introduction.html


posted @ 2005-11-23 12:53 Dion 阅读(560) | 评论 (0)编辑 收藏

     摘要: 在Java2平台企业版中应用异步JavaScript技术和XML(AJAX) ...  阅读全文
posted @ 2005-11-23 11:43 Dion 阅读(1870) | 评论 (4)编辑 收藏

转载自TheServerSide网站,介绍使用Spring来创建Observer模式。
http://www.theserverside.com/articles/article.tss?l=SpringLoadedObserverPattern
 

This article describes an easy process of implementing the observer pattern in the Spring framework (Spring Core). Also discussed in this article are a few of the Spring Core classes as well as an easy way to start the Spring Framework in any project. Finally, this article shows developers and designers that the Spring framework is a great reason to continue design pattern advocacy in your projects.

Recently, it seems when developers use the Spring framework to improve their projects they focus only on simple object oriented design techniques. Unfortunately some of the more brilliantly researched patterns are forgotten in place of a brilliant framework (Spring). Although the Factory Pattern and the Singleton Pattern are built into Spring, other patterns such as the Decorator Pattern, the Adapter Pattern, and the Observer Pattern are often forgotten because of the new ideas Spring has to offer. Fortunately, design patterns and the Spring framework can exist in the same application. In this article I show how the commonly used Observer Pattern fits nicely in the Spring Framework.

Observer Pattern

The Observer Pattern is also known as a publisher and subscriber design pattern. The pattern is useful when you have one publisher and many subscribers (one-to-many) that are interested in the publisher's state or messages. Additionally, interested subscribers have the ability to register and unregister as they please. Lastly, subscribers are notified of the publisher's messages automatically (that is, by no effort of their own). Figure 1 is an example of a typical observer pattern.

Figure 1. Observer Pattern


I chose to use a more widely accepted diagram to describe the Observer Pattern so you will notice that the aforementioned publisher is actually the Subject in this diagram. The subscriber is the Observer in the diagram. The intimate details of the Observer Pattern are far outside of the scope of this article, but a note worthy topic is how the Spring framework can be used to leverage good object oriented design techniques while creating the concrete classes of this pattern.

A normal concreteObserver class is required to have code similar to this constructor (or a similar “setter” method to achieve the registering of the Observer with the Subject):

public concreteObserver(Subject s) {
	s.addListener(this);
}

Below you will see how the Spring framework wires the two concrete classes together with XML and not with code inside the classes. Ultimately, this allows the developer to avoid any unnecessary coupling of the concrete classes.

Spring Considerations

Since this article covers only the most simple implementation of the observer pattern, I utilize only the required Spring framework jars. At a minimum you need to have the spring-core.jar, the spring-context.jar, and the spring-beans.jar from the Spring framework distribution. Also to avoid any run time errors you need the commons-logging.jar from the Apache Commons project in your class path.

Each of these jars provide a specific role that make using the Spring framework possible. First is the spring-core.jar; this jar is required for all Spring applications. It includes Spring's dependency injection classes as well as other classes that are used to create Spring beans. The spring-context.jar contains the ApplicationContext interface. This interface is used to start the Spring framework in my included example project.

The last Spring jar is the spring-beans.jar. It contains the DesposibleBean interface which the FileSystemXmlApplicationContext bean sub-interfaces. I do not directly use the DesposibleBean interface but I use the FileSystemXmlApplicationContext bean to located the XML file used to configure the Spring framework. The code that implements these classes is shown in Listing 6.

Wiring The Observer Pattern with Spring

To illustrate the Observer Pattern concretely, I chose to create a Town Crier class that sends messages to any registered Town Resident class. To keep this example simple, I developed the same interfaces shown in Figure 1, but the concrete classes are TownCrier and TownResident. All four of these classes are shown in Listings 1 through 4.

After I created the TownCrier (Listing 3) and two TownResident (Listing 4) classes I created an incomplete version the ObserverContext.xml file (Listing 5). This file contains the Spring definitions of the concrete implementation beans. Since this example is simple, I chose not to use any of the more complex attributes of the bean tag.

Typical Bean tags for the shown classes:

	<bean id="townCrier" class="springobserver.TownCrier"/>
	<bean id="townResident1" class="springobserver.TownResident"/>
	<bean id="townResident1" class="springobserver.TownResident2"/>

At this point, I was able to run my ExampleRun class (Listing 6), but nothing eventful actually happened. This is because the TownResident classes were not “wired” into the TownCrier class.

To perform the wiring of the Observer Pattern I chose to use Spring's MethodInvokingFactoryBean class. This process is a very simple way of calling a method on a class and ultimately passing a parameter into method. In this example, the parameter is the bean definition of a townResident. A snapshot of this bean definition is:

<bean id="registerTownResident1" 
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject"><ref local="townCrier"/></property>
    <property name="targetMethod"><value>addListener</value></property>
    <property name="arguments">
    <list>
      <ref bean="townResident1"/>
    </list>
    </property>
</bean>

As you can see, the targetObject is the townCrier bean, the targetMethod is the addListener method and the argument is the townResident1 bean. This configuration is the only code needed to compose the concrete implementations of the TownCrier with TownResident class.

Now that I have the beans wired together using the MethodInvokingFactoryBean class, I can run my ExampleRun class and see that my TownResident classes are receiving messages from the TownCrier class. Results shown in Example 1.

Conclusion

A few lessons learned in this article include a simple way to start the Spring framework, how to use the MethodInvokingFactoryBean, and an efficient implementation the Observer Pattern in the Spring framework. Since this is a minimal approach to the Spring framework, I was able to show the relationship between the ApplicationContext and it's implementation FileSystemXmlApplicationContext class. This process for starting Spring applications is a very easy way to leverage an incredible framework.

Part of this framework is the MethodInvokingFactoryBean. When using it you are free to employ any parameter available to you such as an Integer, a String, or in our case, another Spring bean. By allowing you to expose methods in your context xml files you can be as flexible as you can dream. This article has covered the addListener() method of the Observer Pattern. I would like to extend a challenge to you to figure out how to implement the removeListener() method using strictly the Spring framework.

Lastly, the Observer Pattern is a common and very useful pattern. The practices shown in this article provide an example of how the concrete implementation of the Observer interface can be developed with no additional coupling to the concrete implementation of the Subject interface. This feature of Spring encourages good object oriented design techniques. As a final note, there is really no reason developers and designers can not find ways to marry proven design patterns with beautifully developed frameworks.

Listing 1. The Observer Interface
package springobserver;
public interface Observer {
  public void update(String messageText);
}
Listing 2. The Subject Interface
package springobserver;
public interface Subject {
  public void addListener(Observer o);
  public void removeListener(Observer o);
  public void notifyListeners();
}
Listing 3. The Town Crier
package springobserver;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class TownCrier implements Subject {

	private List townResident = new ArrayList();
	private String messageText;

	// this message is added so I can give 
	// this class a reason to call notifyListener.
	public void setMessage(String message){
		System.out.println("I'm the Town Crier and " +
				"I've got a message: " + message);
		this.messageText = message;
		this.notifyListeners();
	}
	
	public void addListener(Observer o) {
		this.townResident.add(o);
	}

	public void removeListener(Observer o) {
		if (this.townResident.contains(o)){
			this.townResident.remove(o);
		}
	}

	
	// call the update method on 
	// each observer (town resident)
	public void notifyListeners() {
		for (Iterator iter = townResident.iterator(); iter.hasNext();) {
			Observer listener = (Observer) iter.next();
			listener.update(messageText);
		}
	}

}
Listing 4. The Town Residents
package springobserver;

public class TownResident implements Observer {
	public void update(String messageText) {
		System.out.println("Greetings my name is: " + this);
		System.out.println("I heard: " + messageText);
	}

-------- new class --------
package springobserver;

public class TownResident2 implements Observer {
	public void update(String messageText) {
		System.out.println("Greetings my name is: " + this);
		System.out.println("I heard: " + messageText);
	}

}
Listing 5. The Application Context XML (ObserverContext.xml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
	<!-- This bean is the town crier.  
	He's responsible for notifying all town residents that are interested in his message -->
	<bean id="townCrier" class="springobserver.TownCrier"/>
	
	<!-- this bean is a town resident interested in the town criers messages -->
	<bean id="townResident1" class="springobserver.TownResident"/>          
       
	<!-- this bean is another town resident interested in the town criers messages -->
	<bean id="townResident2" class="springobserver.TownResident2"/>
    
    
     <!-- this is a method invoking bean that registers the first town resident with
          with the town crier -->   
    <bean id="registerTownResident1" 
      class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
      <property name="targetObject"><ref local="townCrier"/></property>
      <property name="targetMethod"><value>addListener</value></property>
      <property name="arguments">
      <list>
        <ref bean="townResident1"/>
      </list>
      </property>
    </bean>
    
    
     <!-- this is a method invoking bean that registers the second town 
          resident with the town crier -->   
    <bean id="registerTownResident2" 
      class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
      <property name="targetObject"><ref local="townCrier"/></property>
      <property name="targetMethod"><value>addListener</value></property>
      <property name="arguments">
      <list>
        <ref bean="townResident2"/>
      </list>
      </property>
    </bean>         
 
 </beans>
Listing 6. Example Run
package springobserver;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class ExampleRun {
	public static void main(String[] args) {
		// launch the spring frame work.
		ApplicationContext ctx = new FileSystemXmlApplicationContext(
				"/config/ObserverContext.xml");
		// grab the Town Crier out of the spring 
		// framework and send a message too all observers
		TownCrier crier = (TownCrier) ctx.getBean("townCrier");
		crier.setMessage("It is 1 O'Clock and all is well!");
	}
}
Example 1. System Output
I'm the Town Crier and I've got a message: It is 1 O'Clock and all is well!
Greetings my name is: springobserver.TownResident@80fa6f
I heard: It is 1 O'Clock and all is well!
Greetings my name is: springobserver.TownResident2@1b9ce4b
I heard: It is 1 O'Clock and all is well!

posted @ 2005-11-22 14:17 Dion 阅读(772) | 评论 (0)编辑 收藏

仅列出标题
共5页: 上一页 1 2 3 4 5