﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-无为-随笔分类-软件构架</title><link>http://www.blogjava.net/mlh123caoer/category/6370.html</link><description>无为则可为，无为则至深！
</description><language>zh-cn</language><lastBuildDate>Wed, 05 Sep 2007 02:38:51 GMT</lastBuildDate><pubDate>Wed, 05 Sep 2007 02:38:51 GMT</pubDate><ttl>60</ttl><item><title>acegi参考手册翻译</title><link>http://www.blogjava.net/mlh123caoer/archive/2007/09/04/142743.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Tue, 04 Sep 2007 13:13:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2007/09/04/142743.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/142743.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2007/09/04/142743.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/142743.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/142743.html</trackback:ping><description><![CDATA[序言 <br />
Acegi Security为基于J2EE的企业应用软件提供全面的安全解决方案。正如你在本手册中看到的那样，我们尝试为您提供有用的，高可配置的安全系统。 <br />
安 全是一个永无止境的目标，获取一个全面的，系统级的实现方式是至关重要的。在安全界，我们鼓励你采用&#8220;分层安全&#8221;，这样每个层都确保自身尽可能的安全，另 外的层提供另外的安全。每个层自身越&#8220;紧密&#8221;，你的系统就越鲁棒和安全。在底层，你要处理传输入安全和系统认证，减少&#8220;中间人攻击&#8221;（man-in- the-middle attacks）。接下来你要使用防火墙，结合VPN或者IP安全来确保只有认证过的系统能够尝试连接。在企业环境中，你可能部署DMZ （demilitarized zone，隔离区）来把面向公众的服务器和后端的数据和应用服务器分隔开。在以非授权用户运行进程和文件系统安全最大化上，你的操作系统也将扮演一个关键 的角色。接下来你要防止针对系统的拒绝服务和暴力攻击。入侵检测系统在检测和应对攻击方面尤其有用，这些系统可以实时屏蔽恶意TCP/IP地址。在更高层 上，你的Java虚拟机需要进行配置，将授予不同Java类型的权限最小化，然后，你的应用程序要对添加针对自身特定问题域的安全配置。Acegi Security使后者－应用程序安全变得容易。 <br />
当然，你要正确对待上述提到的每个安全层，以及包含于每个层的管理因素。这样的管理因素具体包括：安全公告监测，补丁，人工诊断，审计，变更管理，工程管理系统，数据备份，灾难恢复，性能评测，负载监测，集中日志，应急反应程序等等。 <br />
Acegi Security专注于在企业应用安全层为您提供帮助，你将会发现和各式各样的需求和商业问题领域一样多。银行系统的需求和电子商务应用的需求不同。电子 商务应用和售卖军用自动工具的公司的需求不同。这些客户化的需求使得应用安全显得有趣，富有挑战性而且物有所值。 <br />
本手册为Acegi Security 1.0.0的发布而大规模重新组织。请先阅读Part I 架构概览。手册的其余部分按照传统的手册方式编排，需要一定的基础才能阅读。 <br />
我们希望您会觉得手册有用，并且欢迎您提供反馈意见和建议。 <br />
最后，欢迎加入Acegi Security社区。 <br />
acegi参考手册(v1.0.4)[译]－第一章 简介 <br />
Part I. 架构概览 <br />
象其他的软件一样，Acegi Security也有在整个框架中都会使用的特定核心接口，类，和概念抽象。在手册的这一部分，在检视这些规划和执行Acegi Security集成所必须的核心要素之前，我们先介绍Acegi Security。 <br />
<br />
第一章. 简介 <br />
1.1. Acegi Security是什么? <br />
Acegi Security为基于J2EE的企业软件应用提供全面的安全服务。特别是使用领先的J2EE解决方案－Srping框架开发的项目。如果您不是使用 Spring开发企业应用，我们温馨提醒您仔细研究一下。熟悉Spring，尤其是依赖注射原理，会极大的帮助你快速掌握Acegi Security。 <br />
人们使用Acegi Security有很多种原因，不过通常吸引他们到这个项目的原因是他们在J2EE的 Servlet Specification 或者 EJB Specification中找不到迫切需要的典型企业应用场景。提到这些规范，特别要提出的是他们不是在WAR或者EAR级别可移植的。这样，如果你切 换服务器环境，一般来说你要在目标环境中花费很多工夫来重新配置你的应用安全。使用Acegi Security解决了这些问题，并且为你提供了很多其他有用的，完全可定制的安全特性。 <br />
如你所知，安全包含两个主要操作。第一个被称为&#8220;认 证&#8221;，是为用户建立一个它所声明的principal。Principal通常代表用户，设备，或者其他能在你的应用中执行操作的其他系统。&#8220;授权&#8221;指判 定一个principal能否在你的系统中执行某个操作。在到达授权判断之前，principal的的身份认证已经由认证过程执行过了。这些概念是通用 的，不是Acegi Security特有的。 <br />
在认证层面，Acegi Security广泛支持各种认证模块。这些认证模块绝大多数是第三方提供，或者相关的标准组织开发的，例如Internet Engineering Task Force。作为补充，Acegi Security自己也提供了一些认证功能。Acegi Security当前支持如下的认证技术。 <br />
&amp;S226; HTTP BASIC authentication headers (an IEFT RFC-based standard) <br />
&amp;S226; HTTP Digest authentication headers (an IEFT RFC-based standard) <br />
&amp;S226; HTTP X.509 client certificate exchange (an IEFT RFC-based standard) <br />
&amp;S226; LDAP (a very common approach to cross-platform authentication needs, especially in large environments) <br />
&amp;S226; Form-based authentication (for simple user interface needs) <br />
&amp;S226; Computer Associates Siteminder <br />
&amp;S226; JA-SIG Central Authentication Service (otherwise known as CAS, which is a popular open source single sign on system) <br />
&amp;S226; Transparent authentication context propagation for Remote Method Invocation (RMI) and HttpInvoker (a Spring remoting protocol) <br />
&amp;S226; Automatic "remember-me" authentication (so you can tick a box to avoid re-authentication for a predetermined period of time) <br />
&amp;S226; Anonymous authentication (allowing every call to automatically assume a particular security identity) <br />
&amp;S226; Run-as authentication (which is useful if one call should proceed with a different security identity) <br />
&amp;S226; Java Authentication and Authorization Service (JAAS) <br />
&amp;S226; Container integration with JBoss, Jetty, Resin and Tomcat (so you can still use Container Manager Authentication if desired) <br />
&amp;S226; 你自己的认证系统 (如下所示) <br />
很 多独立软件供应商(ISVs)选择Acegi Security是因为它具有丰富的认证模块。这样无论他们的终端客户需要什么，他们都可以快速集成到他们的系统中，不用花很多工夫或者让终端客户改变环 境。如果Acegi Security System for Spring的7个认证模块还没有满足你的需求的话，Acegi Security是一个开放的系统，很容易写你自己的认证机制。许多Acegi Security的企业用户需要和&#8220;遗留&#8221;系统集成，这些遗留系统不遵循任何安全标准，Acegi Security能够和这样的系统&#8220;合作愉快&#8221;。 <br />
有 时候基本的认证是不够的。有时候你需要根据principal和应用交互的方式来应用不同的安全措施。例如，你可能为了防止密码被窃取，或者防止终端用户 受到&#8220;中间人&#8221;攻击，需要保证到达的是请求通过HTTPS的。或者，你要确保是一个真正的人而不是某种机器人或者自动进程在发送请求。这对于保护密码恢复 不受暴力破解攻击，或者防止他人很容易的复制你应用的关键内容。为了帮助你实现这些目标，Acegi Security完全支持自动&#8220;通道安全&#8221;("channel security")，以及集成Jcaptcha来检测是否是真正人类用户。 <br />
Acegi Security不仅提供了认证功能，而且提供了完备的授权功能。在授权方面主要有三个领域，授权web请求，授权方法调用，授权存取单个领域对象实例。 为了帮助你理解这些区别，对照考虑一下Servlet 规范中的web模式安全的授权功能，EJB容器管理安全以及文件系统安全。Acegi Security提供了所有这些重要领域的完备功能，我们将在本手册的后面介绍。 <br />
1.2. 历史 <br />
Acegi Security始于2003年晚期，当时在Spring Developers邮件列表中有人提问是否有人考虑提供一个基于Spring的安全实现。当时，Srping的社区是相对比较小的（尤其是和今天相 比！），实际上Spring本身也是2003年早期才作为一个SourceForge项目出现的。对此问题的回应是它确实是一个值得研究的领域，虽然限于 时间无法进行深入。 <br />
有鉴于此，这个简单的安全实现虽然构建了但是并没有发布。几周以后，Spring社区的其他成员询问了安全框架，代码就被提供给了他们。 <br />
随后又有人请求，到了2004年一月，大约有20人左右在使用这些代码。另外一些人加入到这些先行的用户中来，并建议建立一个SourceForge项目，这个项目在2004年3月建立起来。 <br />
在 早期，该项目自身并布具备任何认证模块。认证过程依赖容器管理安全（Container Managed Security）而Acegi Security注重授权。在一开始这样是合适的，但是随着越来越多的用户要求额外的容器支持，基于容器的认证的限制就显示出来了。另外一个相关的问题是 添加新的JAR文件到容器的classpath，通常会让最终用户感到困惑并且配置错误。 <br />
随后，Acegi Security加入了认证服务。大约一年后，Acegi Security成为了一个Spring Framework官方子项目。在2年半多的在多个软件项目中的活跃使用以及数以百计的改进和社区贡献，1.0.0最终版在2006年5月发布。 <br />
今天，Acegi Security成为一个强大而活跃的社区。在支持论坛上有数以千计的帖子。14位开发人员专职开发，一个活跃的社区也定期共享补丁并支持他们的同侪。 <br />
<br />
1.3. 发行版本号 <br />
理 解Acegi Security的版本号是非常好处的，它可以帮助你判定升级的到新的版本是否需要花费很大精力。我们的正式发行版本使用Apache Portable Runtime Project版本指引，可以在下述网站查看http://apr.apache.org/versioning.html。为了您查看方便，我们引用该 页的说明部分如下： <br />
&#8220;版本号由三个部分的整数组成：主版本号（MAJOR）、副版本号（MINOR）、补丁版本号（PATCH）。主要的含义 是主版本号（MAJOR）是不兼容的，API大规模升级。副版本号（MINOR）在源文件和可执行版和老版本保持兼容，补丁版本号（PATCH）则意味着 向前和向后的完全兼容&#8221;。 <br />
acegi参考手册(v1.0.4)[译]-第二章 技术概览[上] <br />
<br />
第二章. 技术概览 <br />
2.1. 运行时环境 <br />
Acegi Security可以在JRE1.3中运行。这个发行版本中支持也Java 5.0，尽管对应的Java类型被分开打包到一个后缀是&#8220;tiger&#8221;的包中。因为Acegi Security致力于以一种自包含的方式运行，因此不需要在JRE中放置任何特殊的配置文件。特别无需配置Java Authentication and Authorization Service (JAAS)策略文件或者将Acegi Security放置到通用的classpath路径中。 <br />
<br />
同样的，如果你使用EJB容器或者Servlet容器，同样无需放置任何特别的配置文件或者将Acegi Security包含在服务器的类加载器（classloader）中。 <br />
<br />
上述的设计提供了最大的部署灵活性，你可以直接把目标工件（JAR, WAR 或者 EAR)）直接从一个系统copy到另一个系统，它马上就可以运行起来。 <br />
<br />
2.2. 共享组件 <br />
让我们来看看Acegi Security中最重要的一些共享组件。所谓共享组件是指在框架中处于核心地位，系统脱离了它们之后就不能运行。这些Java类型代表了系统中其他部分的构建单元，因此理解它们是非常重要的，即使你不需要直接和它们打交道。 <br />
<br />
最 基础的对象是SecurityContextHolder。在这里存储了当前应用的安全上下文（security context），包括正在使用应用程序的principal的详细信息。SecurityContextHolder默认使用ThreadLocal来 存储这些详细信息，这意味着即便安全上下文（security context）没有被作为一个参数显式传入，它仍然是可用的。如果在当前principal的请求处理后清理线程,那么用这种方式使用 ThreadLocal是非常安全的。当然， Acegi Security自动为你处理这些，所以你无需担心。 <br />
<br />
有些应用程序由于使 用线程的方式而并不是完全适用ThreadLocal。例如，Swing客户端可能需要一个Java Virtual Machine中的所有线程都使用同样的安全上下文（security context）。在这种情况下你要使用SecurityContextHolder.MODE_GLOBAL模式。另外一些应用程序可能需要安全线程产 生的线程拥有同样的安全标识符（security identity）。这可以通过SecurityContextHolder.MODE_INHERITABLETHREADLOCAL来实现。你可以通 过两种方法来修改默认的SecurityContextHolder.MODE_THREADLOCAL。第一种是设置一个系统属性。或者，调用 SecurityContextHolder的一个静态方法。大部分的应用程序不需要修改默认值，不过如果你需要，那么请查看 SecurityContextHolder的JavaDocs获取更多信息。 <br />
<br />
我们在SecurityContextHolder中 存储当前和应用程序交互的principal的详细信息。Acegi Security使用一个Authentication对象来代表这个信息。尽管你通常不需要自行创建一个Authentication对象，用户还是经 常会查询Authentication对象。 <br />
<br />
你可以在你的应用程序中的任何地方使用下述的代码块： <br />
java 代码 <br />
<br />
1. Object obj = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); <br />
2. if (obj instanceof UserDetails) { <br />
3. String username = ((UserDetails)obj).getUsername(); <br />
4. } else { <br />
5. String username = obj.toString(); <br />
6. } <br />
<br />
上 述的代码展示了一些有趣的联系和关键的对象。首先，你会注意到在SecurityContextHolder和Authentication之间有一个媒 介对象。SecurityContextHolder.getContext() 方法实际上返回一个SecurityContext。Acegi Security使用若干个不同的SecurityContext实现，以备我们需要存储一些和principal无关的特殊信息。一个很好的例子就是我 们的Jcaptcha集成，它需要知道一个需求是否是由人发起的。这样的判断和principal是否通过认证完全没有关系，因此我们将它保存在 SecurityContext中。 <br />
<br />
从上述的代码片段可以看出的另一个问题是你可以从一个Authentication对象中获取一 个principal。Principal只是一个对象。通常可以把它cast为一个UserDetails对象。UserDetails在Acegi Security中是一个核心接口，它以一种扩展以及应用相关的方式来展现一个principal。可以把UserDetails看作是你的用户数据库和 Acegi Security在SecurityContextHolder所需要的东西之间的一个适配器（adapter）。作为你自己用户数据库的一个展现，你可 能经常要把它cast到你应用程序提供的原始对象，这样你就可以调用业务相关的方法(例如 getEmail(), getEmployeeNumber())。 <br />
<br />
现在你可能已经开始疑惑，那我什么时候提供UserDetails对象呢？我要如何提供呢？ <br />
我 想你告诉过我这个东西是声明式的，我不需要写任何Java代码－那怎么做到呢？对此的简短回答就是有一个叫做UserDetailsService的特殊 接口。这个接口只有一个方法，接受一个Sring类型的参数并返回一个UserDetails。Acegi Security提供的大多数认证提供器将部分认证过程委派给UserDetailsService。UserDetailsService用来构建保存 在SecurityContextHolder中的Authentication对象。好消息是我们提供若干个UserDetailsService的实 现，包括一个使用in-memory map和另一个使用JDBC的。 <br />
大多数用户还是倾向于写自己的实现，这样的实现经常就是简单的构建于已 有的Data Access Object (DAO)上，这些DAO展现了他们的雇员、客户、或者其他企业应用程序中的用户。要记得这样做的好处，不论你的UserDetailsService返 回什么，它总是可以从SecurityContextHolder中获取，象上面的代码显示的那样。 <br />
<br />
除了principal， Authentication提供的另一个重要方法就是getAuthorities（）。这个方法返回一个GrantedAuthority对象数组。 GrantedAuthority，毫无疑问，就是授予principal的权限。这些权限通常是&#8220;角色&#8221;，例如ROLE_ADMINISTRATOR 或者ROLE_HR_SUPERVISOR。这些角色稍后配置到web授权，方法授权和领域对象授权。Acegi Security的其他部分能够处理这些权限，并且期待他们被提供。通常你会从UserDetailsService中返回 GrantedAuthority对象。 <br />
<br />
通常GrantedAuthority对象都是应用范围的权限。它们都不对应特定的领域对 象。因此，你应该不会有一个代表54号员工对象的GrantedAuthority，因为这样会有数以千计的authority，你马上就会用光所有内存 （或者，至少会让系统花太长时间来认证一个用户）。当然，Acegi Security会高效的处理这种普遍的需求，但是你不会使用领域对象安全功能来实现这个目的。 <br />
<br />
最后，但不是不重要，你有时候需要在 HTTP 请求之间存储SecurityContext。另外有些时候你在每次请求的时候都会重新认证principal，不过大部分时候你会存储 SecurityContext。HttpSessionContextIntegrationFilter在HTTP之间存储 SecurityContext。正如类名字显示的那样，它使用HttpSession来进行存储。基于安全原因，你永远都不要直接和 HttpSession交互。没有理由这么做，所以记得使用SecurityContextHolder来代替。 <br />
<br />
让我们回忆一下，Acegi Security的基本组成构件是： <br />
&amp;S226; SecurityContextHolder,提供对SecurityContext的所有访问方式。 <br />
&amp;S226; SecurityContext, 存储Authentication以及可能的请求相关的安全信息。 <br />
&amp;S226; HttpSessionContextIntegrationFilter, 在web请求之间把SecurityContext存储在HttpSession中。 <br />
&amp;S226; Authentication, 以Acegi Security的方式表现principal。 <br />
&amp;S226; GrantedAuthority, 表示赋予一个principal的应用范围的权限。 <br />
&amp;S226; UserDetails, 为从你的应用程序DAO中获取必要的信息来构建一个Authentication 对象。 <br />
&amp;S226; UserDetailsService,用传入的String类型的username（或者认证ID，或类似）来创建一个UserDetails。 <br />
<br />
现在你已经理解了这些重复使用的组件，让我们仔细看看认证过程吧。 <br />
<br />
2.3. 认证 <br />
正 如我们在手册开始部分所说的那样，Acegi Security适用于很多认证环境。虽然我们建议大家使用Acegi Security自身的认证功能而不是和容器管理认证（Container Managed Authentication）集成，但是我们仍然支持这种和你私有的认证系统集成的认证。让我们先从Acegi Security完全自行管理管理web安全的角度来探究一下认证，这也是最复杂和最通用的情形。 <br />
<br />
想象一个典型的web应用的认证过程： <br />
<br />
1．你访问首页，点击一个链接。 <br />
2．一个请求被发送到服务器，服务器判断你是否请求一个被保护的资源。 <br />
3．因为你当前未被认证，服务器发回一个回应，表明你必须通过认证。这个回应可能是一个HTTP回应代码，或者重定向到一个特定的网页。 <br />
4．基于不同的认证机制，你的浏览器会重定向到一个网页好让你填写表单，或者浏览器会用某种方式获取你的身份认证（例如一个BASIC认证对话框，一个cookie，一个X509证书等等。）。 <br />
5．浏览器会发回给服务器一个回应。可能是一个包含了你填写的表单内容的HTTP POST，或者一个包含你认证详细信息的HTTP header。 <br />
6．接下来服务器会判断提供的认证信息是否有效。如果它们有效，你进入到下一步。如果它们无效，那么通常请求你的浏览器重试一次（你会回到上两步）。 <br />
7．你引发认证的那个请求会被重试。但愿你认证后有足够的权限访问那些被保护的资源。如果你有足够的访问权限，请求就会成功。否则，你将会受到一个意味&#8220;禁止&#8221;的HTTP403错误代码。 <br />
<br />
在Acegi Security中，对应上述的步骤，有对应的类。主要的参与者（按照被使用的顺序）是：ExceptionTranslationFilter， AuthenticationEntryPoint， 认证机制(authentication mechanism)， 以及AuthenticationProvider。 <br />
<br />
ExceptionTranslationFilter是Acegi Security用来检测任何抛出的安全异常的过滤器(filter)。这种异常通常是由AbstractSecurityInterceptor抛出 的，它是授权服务的主要提供者。我们将会在下一部分讨论AbstractSecurityInterceptor，现在我们只需要知道它产生Java异 常，并且对于HTTP或者如何认证一个principal一无所知。反而是ExceptionTranslationFilter提供这样的服务，它负责 要么返回403错误代码(如果principal通过了认证，只是缺少足够的权限，象上述第7步那样)，要么加载一个 AuthenticationEntryPoint (如果principal还没有被认证，那么我们要从第3步开始)。 <br />
<br />
AuthenticationEntryPoint 负责上述的第3步。如你所想，每个web应用都有一个默认的认证策略（象Acegi Security中几乎所有的东西一样，它也是可配置的，不过我们现在还是还是从简单开始）。每个主流的认证系统都有它自己的 AuthenticationEntryPoint实现，负责执行第3步中描述的动作。 <br />
<br />
当浏览器确定要发送你的认证信息（HTTP 表单或者HTTP header），服务器上需要有什么东西来&#8220;收集&#8221;这些认证信息。现在我们在上述的第6步。在Acegi Security中对从用户代理（通常是浏览器）收集认证信息有一个特定的名字，这个名字是&#8220;认证机制（authentication mechanism）&#8221;。当认证信息从客户代理收集过来以后，一个&#8220;认证请求（Authentication request）&#8221;对象被创建，并发送到AuthenticationProvider。 <br />
<br />
Acegi Security中认证的最后一环是一个AuthenticationProvider。非常简单，它的职责是取用一个认证请求 （Authentication request）对象，并且判断它是否有效。这个provider要么抛出一个异常，要么返回一个组装完毕的Authentication对象。还记得我 们的好朋友UserDetails 和 UserDetailsService吧？如果没有，回到前一部分重新回忆一下。大部分的AuthenticationProviders都会要求 UserDetailsService提供一个UserDetails对象。如前所述，大部分的应用程序会提供自己的 UserDetailsService，尽管有些会使用Acegi Security提供的JDBC或者 in-memory实现。作为成品的UserDetails 对象，特别是其中的GrantedAuthority[]s，在构建完备的Authentication对象时会被使用。 <br />
<br />
当认证机制 （authentication mechanism）取回组装完全的Authentication对象后，它将会相信请求是有效的，将Authentication放到 SecurityContextHolder中，并且将原始请求取回（上述第7步）。反之，AuthenticationProvider则拒绝请求，认 证机制（authentication mechanism）会请求用户重试（上述第2步）。 <br />
<br />
在讲述典型的认证流程的同时，有个好消 息是Acegi Security不关心你是如何把Authentication放到SecurityContextHolder内的。唯一关键的是在 AbstractSecurityInterceptor授权一个请求之前，在SecurityContextHolder中包含一个代表了 principal的Authentication。 <br />
<br />
你可以（很多用户确实）实现自己的过滤器（filter）或者MVC控制器 （controller）来提供和不是基于Acegi Security的认证系统交互。例如，你可能使用使用容器管理认证（Container Managed Authentication），从ThreadLocal 或者JNDI中获取当前用户信息，使得它有效。或者，你工作的公司有一个遗留的私有认证系统，而它是公司&#8220;标准&#8221;，你对它无能为力。在这种情况之下也是非 常容易让Acegi Security运作起来，提供认证能力。你所需要做的是写一个过滤器（或等价物）从某处读取第三方用户信息，构建一个Acegi Security式的Authentication对象，把它放到SecurityContextHolder中。这非常容易做，也是一种广泛支持的集成 方式。 <br />
acegi参考手册(v1.0.4)[译]-第二章 技术概览[下] <br />
2.4. 安全对象 <br />
如果你熟悉AOP，你会知 道有很多种advice可用：before, after, throws 和 around。around advice非常有用，因为它能够选择是否选择是否执行一个方法调用，是否修改返回值，以及是否抛出异常。Acegi Security对方法调用和web请求都提供around advice。我们使用AOP联盟实现对方法调用的around advice，对于web请求的around advice则是使用标准的过滤器（Filter）。 <br />
<br />
对于那些不熟悉AOP的人来说， 关键是要理解Acegi Security能够帮助你保护方法调用以及web请求。大多数人对保护他们服务层的方法调用感兴趣。这是因为在当前的J2EE应用中，服务层包含了大多 数的业务逻辑（声明，作者不赞成这种设计，反而支持正确封装的领域模型以及DTO，assembly, facade 以及 transparent persistence patterns，而不是当前主流的贫血模型，我们将在这里讨论）。如果你需要保护service层的方法调用，使用标准的Spring AOP平台（或者被成为AOP 联盟（AOP Alliance））就足够了。如果你需要直接对领域模型进行保护，那么可以考虑使用AspectJ。 <br />
<br />
你 可以选择对使用AspectJ 或者AOP联盟（AOP Alliance）对方法进行授权，或者你可以选择使用过滤器（filter）来对web请求进行授权。你将0个，1个，2个或者3个这些方法一起使用。 主流的用法是执行一些web请求授权，以及在服务层使用AOP联盟（AOP Alliance）对一些方法调用授权。 <br />
<br />
Acegi Security使用&#8220;安全对象&#8221;（secure object）这个词来指任何能够将安全应用于其上的对象。每个Acegi Security支持的安全对象都有自己的类，它是AbstractSecurityInterceptor的子类。重要的一点是，如果一个 principal通过认证，当AbstractSecurityInterceptor执行的时候，SecurityContextHolder中要包 含一个有效的Authentication。 <br />
<br />
AbstractSecurityInterceptor提供一个固定的工作流程来处理 安全对象请求。这个工作流程包括查找和当前请求相关联的&#8220;配置属性（configuration attributes）&#8221;。配置属性（configuration attributes）可以被认为是对被AbstractSecurityInterceptor使用的类有特殊含义的字符串。他们通常针对 AbstractSecurityInterceptor使用XML进行配置。反正，AbstractSecurityInterceptor会询问 AccessDecisionManager &#8220;这是配置属性（configuration attributes），这是当前的认证对象（Authentication object），这是当前请求的详细信息－那么这个特定的principal可以执行这个特定的操作吗？&#8221;。 <br />
<br />
假如 AccessDecisionManager判定允许这个请求，那么AbstractSecurityInterceptor一般来说就继续执行请求。虽 然这样，用户在少数情况之下可能需要替换SecurityContext中的Authentication，可以通过 AccessDecisionManager调用一个RunAsManager来实现。在某些不常见的情形下这将非常有用，例如服务层的方法需要用另一种 标识（身份）来调用远程系统。这可能有所帮助，因为Acegi Security自动在不同的服务器之间传播安全标识（假设你正确配置了RMI或者HttpInvoker remoting protocol client）。 <br />
<br />
随着安全对象处理和返回－意味着方法调用完毕或者过滤器链（filter chain）处理完毕－AbstractSecurityInterceptor有最后的机会来处理调用。这时， AbstractSecurityInterceptor可能会修改返回的对象。我们可能要这样做，因为授权判断不能在安全对象调用途中执行。由于高度的 可插拔性，如果需要AfterInvocationManager将控制权交给AfterInvocationManager来实际修改对象。这个类甚至 可以彻底替换对象，或者抛出异常，或者根本不修改它。 <br />
<br />
因为是AbstractSecurityInterceptor中心模版类，看起来第一副插图该献给它。（译注：原手册里的图画的太丑陋了，我用jude重新画了一遍） <br />
&lt;!--[if gte vml 1]&gt;&lt;v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"&gt; &lt;v:stroke joinstyle="miter" /&gt; &lt;v:formulas&gt; &lt;v:f eqn="if lineDrawn pixelLineWidth 0" /&gt; &lt;v:f eqn="sum @0 1 0" /&gt; &lt;v:f eqn="sum 0 0 @1" /&gt; &lt;v:f eqn="prod @2 1 2" /&gt; &lt;v:f eqn="prod @3 21600 pixelWidth" /&gt; &lt;v:f eqn="prod @3 21600 pixelHeight" /&gt; &lt;v:f eqn="sum @0 0 1" /&gt; &lt;v:f eqn="prod @6 1 2" /&gt; &lt;v:f eqn="prod @7 21600 pixelWidth" /&gt; &lt;v:f eqn="sum @8 21600 0" /&gt; &lt;v:f eqn="prod @7 21600 pixelHeight" /&gt; &lt;v:f eqn="sum @10 21600 0" /&gt; &lt;/v:formulas&gt; &lt;v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect" /&gt; &lt;o:lock v:ext="edit" aspectratio="t" /&gt; &lt;/v:shapetype&gt;&lt;v:shape id="_x0000_i1025" type="#_x0000_t75" style='width:423pt; height:270.75pt'&gt; &lt;v:imagedata src="file:///C:\WINDOWS\TEMP\msohtml1\01\clip_image001.jpg" o:title="ch2-1" /&gt; &lt;/v:shape&gt;&lt;![endif]--&gt;&lt;!--[if !vml]--&gt;&lt;!--[endif]--&gt; <br />
<br />
图1 关键&#8220;安全对象&#8221;模型 <br />
<br />
只有那些希望实现全 新的对请求进行截取截取和授权方式的开发者才需要直接使用安全对象。例如，可能构建一个新的安全对象安全调用一个消息系统。任何需要安全并且能够提供一种 截取调用的方式(例如AOP around advice semantics)的东西都可以成为安全对象。虽然如此，大部分的Spring应用都会只是透明应用当前支持的三种安全对象类型（AOP Alliance MethodInvocation, AspectJ JoinPoint 和 web request FilterInterceptor）。 <br />
<br />
2.5. 结论 <br />
恭喜！你已经获取了Acegi Security足够的概括性的图景来开始着手你的项目。我们探究了共享组件，认证过程，以及对&#8220;安全对象&#8221;的通用授权概念。手册中的余下部分你可能用到也可能用不到，可以按照任意顺序阅读。 <br />
acegi参考手册(v1.0.4)[译]-第三章 协助系统 <br />
第三章. 协助系统 <br />
本章介绍一些Acegi Security使用的附加和协助系统。那些和安全无关，但是包含在Acegi Security项目中的部分，将会在本章中讨论 <br />
3.1. 本地化 <br />
Acegi Security支持对终端客户可能会看到的异常信息进行本地化。如果你的应用是为英文用户设计的，那么你什么都不用做，因为Acegi Security的所有消息默认都是英文的。如果你要支持其他区域用户，那么本节包含了你所需要了解的所有东西。 <br />
包括认证失败或者访问被拒绝（授权失败）的所有异常消息都可以被本地化。提供给开发者或者系统部署人员的异常或者日志信息(包括错误的属性、接口不符、构造器错误、debug级日志)没有被本地化，它们硬编码在Acegi Security的代码中。 <br />
在acegi -security-xx.jar（译注：xx代表版本号）的org.acegisecurity包中包含了一个 messages.properties文件。这个文件会被你的application context引用，因为Acegi Security实现了Spring的MessageSourceAware接口，它期待在application context启动的时候注入一个message resolver。通常你所需要做的是在你的application context中注册一个引用这个消息的bean，如下所示： <br />
xml 代码 <br />
<br />
1. &lt;bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"&gt; <br />
2. &lt;property name="basename"&gt;&lt;value&gt;org/acegisecurity/messages&lt;!--&lt;/span--&gt;value&gt;&lt;!--&lt;/span--&gt;property&gt; <br />
3. &lt;!--&lt;/span--&gt;bean&gt; <br />
<br />
messages.properties是按照资源包标准命名的，它代表了Acegi Securtiy支持的默认语言。文件默认是英文的。如果你不注册一个消息源，Acegi Security仍然可以正常工作，它会用回硬编码的英文消息。 <br />
如 果你想定制messages.properties文件，或者支持其他语言，那么你应该copy这个文件，然后重命名，并在上述的bean定义中 注册。因为文件中的key并不多，因此本地化花不了多少工夫。如果你针对消息文件进行了本地化，那么请和社区分享，你可以添加一个JIRA任务，将你正确 命名的messages.properties本地化文件作为附件添加。 <br />
为了完善关于本地化的讨论需要知道Spring的 ThreadLocal org.springframework.context.i18n.LocaleContextHolder。你应该为每个用户设置代表他区域的 LocaleContextHolder。Acegi Security会尝试从这个ThreadLocal中获取的Locale来从消息源中获取消息。请参考Spring的文档以获取更多使用 LocaleContextHolder和能够帮你自动设置它的辅助类(例如 <br />
AcceptHeaderLocaleResolver, CookieLocaleResolver, FixedLocaleResolver, SessionLocaleResolver 等)的详细信息。 <br />
3.2. Filters <br />
正如你在整个手册中看到的那样，Acegi Security使用很多filter。你可以使用FilterToBeanProxy或者FilterChainProxy来确定这些是怎样加入到你的web应用中的，下面我们来看看。 <br />
大部分filter使用FilterToBeanProxy来配置。例如下面web.xml中配置所示： <br />
xml 代码 <br />
<br />
1. &lt;filter&gt; <br />
2. &lt;filter-name&gt;Acegi HTTP Request Security Filter&lt;/filter-name&gt; <br />
3. &lt;filter-class&gt;org.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt; <br />
4. &lt;init-param&gt; <br />
5. &lt;param-name&gt;targetClass&lt;/param-name&gt; <br />
6. &lt;param-value&gt;org.acegisecurity.ClassThatImplementsFilter&lt;/param-value&gt; <br />
7. &lt;/init-param&gt; <br />
8. &lt;/filter&gt; <br />
<br />
<br />
注 意在web.xml中的filter实际上是一个FilterToBeanProxy，而不是真正实现filter逻辑的filter。 FilterToBeanProxy所作的是代理Filter的方法到一个从Spring的application context 获取的bean。这使得这个bean可以享受Spring application context的生命周期支持以及配置灵活性。这个bean必须实现javax.servlet.Filter。 <br />
FilterToBeanProxy 只需要一个简单的初始化参数，targetClass或者targetBean。targetClass会定位 application context中指定的类的第一个对象，而FilterToBeanProxy按照bean的名字定位对象。象标准的Spring web应用一样，FilterToBeanProxy使用 WebApplicationContextUtils.getWebApplicationContext(ServletContext)来访问 application context，所以你应该在web.xml中配置一个ContextLoaderListener。 <br />
<br />
在IoC 容器而不是servlet容器中部署Filter会有一个生命周期的问题。特别是，哪个容器应该负责调用Filter的"startup" 和 "shutdown"方法？注意到Filter的初始化和析构顺序随servlet容器不同而不同，如果一个Filter依赖于由另一个更早初始化的 Filter的配置，这样就会出现问题。另一方面，Spring IoC具备更加完善的生命周期/IoC接口（例如InitializingBean, DisposableBean, BeanNameAware, ApplicationContextAware以及其他许多）以及一个容易理解的接口契约（interface contract），可预见的方法调用顺序，自动装配支持，以及可以避免实现Spring接口的选项（例如Spring XML中的destroy-method 属性）。因此，我们推荐尽可能使用Spring生命周期服务而不是servlet容器生命周期服务。FilterToBeanProxy默认不会将 init(FilterConfig) 和 destroy()方法委派到被代理的bean。如果你需要这些调用被委派，那么将lifecycle初始化参数设置为servlet- container-managed。 <br />
我们强烈推荐你使用FilterChainProxy而不是FilterToBeanProxy。虽然 FilterToBeanProxy是一个非 常有用的类FilterToBeanProxy，问题是当web.xml中filter变多时， 和 项就会太多而变得臃肿不堪。为了解决这个问题，Acegi Security提供一个FilterChainProxy类。它在FilterToBeanProxy中被装配（正如上面例子中所示），但目标类 （target class）是org.acegisecurity.util.FilterChainProxy。这样过滤器链（filter chain）可以在application context中按照如下代码配置： <br />
xml 代码 <br />
<br />
1. &lt;bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy"&gt; <br />
2. &lt;property name="filterInvocationDefinitionSource"&gt; <br />
3. &lt;value&gt; <br />
4. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON <br />
5. PATTERN_TYPE_APACHE_ANT <br />
6. /webServices/*=httpSessionContextIntegrationFilterWithASCFalse,basicProcessingFilter,exceptionTranslationFilter, <br />
7. /*=httpSessionContextIntegrationFilterWithASCTrue,authenticationProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor <br />
8. &lt;!--&lt;/span--&gt;value&gt; <br />
9. &lt;!--&lt;/span--&gt;property&gt; <br />
10. &lt;!--&lt;/span--&gt;bean&gt; <br />
<br />
你 可能注意到FilterSecurityInterceptor定义方式的相似之处。同时支持正则表达式和Ant Paths格式，越对应的URI越早出现。在运行时，FilterChainProxy会定位符合当前的web请求的第一个URI模式。每个对应的配置属 性代表了在application context中定义的一个bean的名字。接着fiter会按照它们被指定的顺序，按照FilterChain的标准行为模式被调用(如果一个 Filter决定停止处理，它可以不在chain中执行)。 <br />
如你所见，FilterChainProxy需要为不同的请求模式重复配置 filter的名字（在上面的例子中，, exceptionTranslationFilter 和 filterSecurityInterceptor 是重复的）。这样的设计是为了让FilterChainProxy能够为不同的URI配置不同的filter调用顺序，同时也提高了表达力（针对正则表达 式、Ant Paths、以及任何FilterInvocationDefinitionSource的特定实现）和清晰度，可以知道是哪个filter应该被调用。 <br />
你可能注意到了我们在filter chain定义了两个HttpSessionContextIntegrationFilter (ASC是allowSessionCreation的缩写,是HttpSessionContextIntegrationFilter的一个属性)。 因为web服务不会为将来的请求提供一个jsessionid，为这样的用户创建HttpSessions是浪费的。如果你有一个需要最大限度的伸缩性的 高容量的应用，我们建议你使用上述的方法。对于小的应用，使用单一的HttpSessionContextIntegrationFilter (默认的allowSessionCreation设为true)应该足够了。 <br />
说到生命周期问题，如果对FilterChainProxy自 身调用init(FilterConfig) 和 destroy()方法，它会把它代理到底层的filter。这样FilterChainProxy保证只初始化和析构每个filter一次，不论它在 FilterInvocationDefinitionSource中定义了多少次。你可以通过FilterToBeanProxy的lifecycle 初始化参数来控制这些方法是否被调用。如上面所讨论的那样，默认所有servlet容器生命周期调用是不被代理到FilterChainProxy的。 <br />
在web.xml中定义的filter的顺序是非常重要的。不管你实际用到哪个filter，的顺序应该是如下所示的： <br />
1．ChannelProcessingFilter，因为可能要重定向到另一种协议。 <br />
2．ConcurrentSessionFilter 因为不使用任何SecurityContextHolder的功能，但是需要更新SessionRegistry来表示当前的发送请求的principal。 <br />
3． HttpSessionContextIntegrationFilter, 这样当一个web请求开始的时候就可以在SecurityContextHolder中设置一个SecurityContext，当web请求结束的时候 任何对SecurityContext的改动都会被copy到HttpSession（以备下一个web请求使用）。 <br />
4． Authentication processing mechanisms - AuthenticationProcessingFilter, CasProcessingFilter, BasicProcessingFilter, HttpRequestIntegrationFilter, JbossIntegrationFilter 等 - 修改SecurityContextHolder，使其中包含一个有效的认证请求令牌（token）。 <br />
5．SecurityContextHolderAwareRequestFilter, 如果你使用它来在你的servlet容器中安装一个Acegi Security aware HttpServletRequestWrapper。 <br />
6． RememberMeProcessingFilter, 如果早期的认证处理过程没有更新SecurityContextHolder，并且请求（request）提供了一个cookie启用remember- me服务，一个合适的被记住的Authentication对象会被放到SecurityContextHolder那里。 <br />
7．AnonymousProcessingFilter, 如果早期的认证处理过程没有更新SecurityContextHolder，, 一个匿名Authentication 对象会被放到SecurityContextHolder那里。 <br />
8．ExceptionTranslationFilter, 捕获所有的Acegi Security 异常，这样要么返回一个HTTP错误响应或者加载一个对应的AuthenticationEntryPoint。 <br />
9．FilterSecurityInterceptor, 保护 web URIs <br />
所 有上述的filter使用FilterToBeanProxy或FilterChainProxy。建议在一个应用中使用一个单个的 FilterToBeanProxy代理到一个单个的FilterChainProxy。，在FilterChainProxy中定义所有的Acegi Security Filters。如果你使用SiteMesh，确保Acegi Security filters 在 SiteMe**ers调用前调用。这样使SecurityContextHolder在SiteMesh decorator使用前能够 <br />
<br />
<br />
acegi参考手册(v1.0.4)[译]-第四章 信道安全 <br />
第四章. 信道安全 <br />
4.1. 概述 <br />
Acegi Security不仅能满足你的认证和授权的请求，而且能够保证你的未认证的web请求也能拥有某些属性。这些属性可能包括使用特定的传输类型，在HttpSession设置特定的属性等等。Web请求的最普遍的需求是使用特定的传输协议，例如HTTPS。 <br />
在 传输安全中的一个重要议题就是会话劫持（session hijacking）。Web容器通过一个jsessionid来引用一个HttpSession，这个jsessionid通过cookie 或者URL重写转向（URL rewriting）发送到到客户端。如果jsessionid是通过HTTP发送的，那么就存在被劫持以及在认证过程之后冒充被认证用户的可能。这是因 为大部分的web容器为特定的用户维护同一个会话标识符，即便是用户从HTTP 切换到 HTTPS页面。 <br />
如果对于你的特定应用来说，会话劫 持（session hijacking）是一个很严重的风险，那么唯一的解决方法就是对每一个请求都使用HTTPS。这意味着jsessionid不会使用非安全信道传输。 你要保证你的web.xml中定义，把它指向一个HTTPS位置，同时应用程序不把用户指向一个HTTP位置。 Acegi Security提供一个解决方案帮助你实现后者。 <br />
4.2. 配置 <br />
启用Acegi Security的信道安全服务，需要在web.xml中增加如下行： <br />
xml 代码 <br />
<br />
1. &lt;filter&gt; <br />
2. &lt;filter-name&gt;Acegi Channel Processing Filter&lt;/filter-name&gt; <br />
3. &lt;filter-class&gt;org.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt; <br />
4. &lt;init-param&gt; <br />
5. &lt;param-name&gt;targetClass&lt;/param-name&gt; <br />
6. &lt;param-value&gt;org.acegisecurity.securechannel.ChannelProcessingFilter&lt;/param-value&gt; <br />
7. &lt;/init-param&gt; <br />
8. &lt;/filter&gt;&lt;filter-mapping&gt; <br />
9. &lt;filter-name&gt;Acegi Channel Processing Filter&lt;/filter-name&gt; <br />
10. &lt;url-pattern&gt;/*&lt;/url-pattern&gt; <br />
11. &lt;/filter-mapping&gt; <br />
<br />
<br />
和平时一样，你同样需要在application context中配置filter <br />
java 代码 <br />
<br />
1. "channelProcessingFilter" class="org.acegisecurity.securechannel.ChannelProcessingFilter"&gt; <br />
2. "channelDecisionManager"&gt;"channelDecisionManager"/&gt; <br />
3. "filterInvocationDefinitionSource"&gt; <br />
4. <br />
5. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON <br />
6. \A/secure/.*\Z=REQUIRES_SECURE_CHANNEL <br />
7. \A/acegilogin.jsp.*\Z=REQUIRES_SECURE_CHANNEL <br />
8. \A/j_acegi_security_check.*\Z=REQUIRES_SECURE_CHANNEL <br />
9. \A.*\Z=REQUIRES_INSECURE_CHANNEL <br />
10. <br />
11. <br />
12. <br />
13. <br />
14. "channelDecisionManager" class="org.acegisecurity.securechannel.ChannelDecisionManagerImpl"&gt; <br />
15. "channelProcessors"&gt; <br />
16. <br />
17. "secureChannelProcessor"/&gt; <br />
18. "insecureChannelProcessor"/&gt; <br />
19. <br />
20. <br />
21. <br />
22. <br />
23. "secureChannelProcessor" class="org.acegisecurity.securechannel.SecureChannelProcessor"/&gt; <br />
24. <br />
25. "insecureChannelProcessor" class="org.acegisecurity.securechannel.InsecureChannelProcessor"/&gt; <br />
<br />
<br />
ChannelProcessingFilter和FilterSecurityInterceptor一样支持Apache Ant style paths。 <br />
ChannelProcessingFilter 的工作方式是过滤所有的web请求，并将判断将适合的配置属性应用于其上。然后它代理到 ChannelDecisionManager。默认的实现类ChannelDecisionManagerImpl应该能够满足大多数需求。它就代理到 配置好的ChannelProcessor实例列表。ChannelProcessor会检视请求，如果它不满意请求（例如请求是发送自不正确的传输协 议）它将会重定向，抛出异常或者采取其他任何恰当的措施。 <br />
Acegi Security 包括ChannelProcessor两个实体类实现：SecureChannelProcessor 保证配置了REQUIRES_SECURE_CHANNEL 属性的请求都是从HTTPS发送过来的。而InsecureChannelProcessor 保证配置了REQUIRES_INSECURE_CHANNEL 属性的请求都是从HTTP发送过来的。如果没有使用请求的协议，这两个实现都会转到ChannelEntryPoint，而两个 ChannelEntryPoint 实现所作的就是简单的把请求相应按照HTTP 和 HTTPS重定向。 <br />
要注意重定向是绝对（例如 http://www.company.com:8080/app/page ） 而不是相对的(例如 /app/page)。在测试中发现Internet Explorer 6 Service Pack 1 有一个bug，因此如果在重定向的时候也改变使用的端口，它就不能正确响应。对应这个bug，在很多Acegi Security bean中都会使用的PortResolverImpl也使用绝对URL。请参阅PortResolverImpl的JavaDoc以获取更多信息。 <br />
你 要注意使用为了在登录过程中保证用户名和密码的安全，要使用安全信道。如果你配合基于表单的登录使用 ChannelProcessingFilter，请记得一定要把你的登录页面设置为REQUIRES_SECURE_CHANNEL，并且 AuthenticationProcessingFilterEntryPoint.forceHttps属性设置为true。 <br />
4.3. 结论 <br />
一 旦配置好了，使用安全信道是非常简单的。只要请求页面，不用管使用什么协议（HTTP 或 HTTPS）或什么端口（80, 8080, 443, 8443等）。显然你只要确定初始请求(获取通过在web.xml 中的 或一个众所周知的主页URL)，完成以后filter会执行你application context定义的重定向。 <br />
你也可以在ChannelDecisionManagerImpl中增加自己的ChannelProcessor实现。例如，你可能通过"输入图片中的内容"检测到一个个人类用户，然后在HttpSession中设置一个属性。 <br />
要判断一个安全检查应该是或者ChannelProcessor或是 AccessDecisionVoter 记得前者是设计用来处理认证或者未认证的请求，而后者是设计用来处理已认证的请求。因此后者可以访问已认证的principal被授予的权限。 <br />
另 外，ChannelProcessor检测到问题后一般是引发一个HTTP/HTTPS重定向这样他的请求可以被满足，而 AccessDecisionVoter将则会跑出一个AccessDeniedException异常(取决于支配的 AccessDecisionManager)。 <br />
acegi参考手册(v1.0.4)[译]-第五章 标签库 <br />
5.1. 概述 <br />
Acegi Security带有若干个可以降低JSP编写难度的JSP标签库。标签库的标志是authz，它提供了一些各不相同的服务。 <br />
5.2. 配置 <br />
所 有的标签库类都包含在acegi-security-xx.jar文件中，authz.tld在JAR的META-INF目录。这意味着如果在 JSP1.2以上的wb容器中，你只要把JAR文件放到WEB-INF/lib目录它就可用了。如果你使用JSP1.1容器，你需要在web.xml文件 中声明JSP标签库，并在WEB-INF/lib中包含authz.tld文件。将如下片段加入到web.xml中： <br />
<br />
java 代码 <br />
1. <br />
2. http://acegisecurity.org/authz <br />
3. /WEB-INF/authz.tld <br />
4. <br />
第六章. 通用认证服务 <br />
6.1. Mechanisms, Providers 和 Entry Points <br />
如果你使用Acegi Security提供的认证方法，那么通常你需要配置一个web filter，一个AuthenticationProvider <br />
以及AuthenticationEntryPoint。在本节我们将要浏览一个示例应用，它需要支持基于form的认证（例如提供给用户登录的HTML页面）以及基础认证（例如web service或者类似的可以访问受保护资源）。 <br />
<br />
在web.xml中，这个应用需要一个单独的Acegi Security filter来使用FilterChainProxy。几乎所有的Acegi Security应用都有一个类似的项，看起来象下面这样： <br />
<br />
xml 代码 <br />
1. &lt;filter&gt; <br />
2. &lt;filter-name&gt;Acegi Filter Chain Proxy&lt;/filter-name&gt; <br />
3. &lt;filter-class&gt;org.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt; <br />
4. &lt;init-param&gt; <br />
5. &lt;param-name&gt;targetClass&lt;/param-name&gt; <br />
6. &lt;param-value&gt;org.acegisecurity.util.FilterChainProxy&lt;/param-value&gt; <br />
7. &lt;/init-param&gt; <br />
8. &lt;/filter&gt; <br />
9. &lt;filter-mapping&gt; <br />
10. &lt;filter-name&gt;Acegi Filter Chain Proxy&lt;/filter-name&gt; <br />
11. &lt;url-pattern&gt;/*&lt;/url-pattern&gt; <br />
12. &lt;/filter-mapping&gt; <br />
<br />
上 述声明将使每个web请求都要经过Acegi Security的FilterChainProxy。正如在本手册的filter那节中所说，FilterChainProxy是一个通用类，它使得 web请求按照URL模式被发送到不同的filter。那些被委派的filter是由application context管理的，因此它们可以享受依赖注射的好处。我们来看看在你的application context中FilterChainProxy的定义会是什么样的： <br />
<br />
xml 代码 <br />
1. &lt;bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy"&gt; <br />
2. &lt;property name="filterInvocationDefinitionSource"&gt; <br />
3. &lt;value&gt; <br />
4. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON <br />
5. PATTERN_TYPE_APACHE_ANT <br />
6. /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,basicProcessingFilter,securityContextHolderAwareRequestFilter,&lt;/value&gt; <br />
7. &lt;/property&gt; <br />
8. &lt;/bean&gt; <br />
<br />
在内部，Acegi Security会使用PropertyEditor来将上述XML片段中的字符串转化为一个 FilterInvocationDefinitionSource对象。在这个阶段需要注意的是，一系列的filter会按照定义的顺序运行，并且这些 filter实际就是application context中的bean的。所以，在我们的例子中，会在application context出现另外一些bean，它们会被命名为httpSessionContextIntegrationFilter, logoutFilter 等。Filter出现的顺序会在手册中filter那一节讨论，虽然上述的例子中它们是正确的。 <br />
<br />
在我们的 例子中，我们使用了AuthenticationProcessingFilter和BasicProcessingFilter。它们分别对应了基于 form的认证和BASIC HTTP header-based认证的&#8220;认证机制&#8221;（我们在手册的前面部分讨论了认证机制扮演的角色）。如果你既不使用form也不使用BASIC认证，就不需 要定义这些bean了。取而代之的是你要定义对应你所需要的认证环境的filter，例如DigestProcessingFilter 或者CasProcessingFilter。请对照手册中对应的章节来了解如何配置这些认证机制。 <br />
<br />
让我们回忆一下，在 HttpSessionContextIntegrationFilter中保存了每个HTTP session调用中的SecurityContext。这意味着认证机制只会在principal最初尝试认证的时候被使用一次。在余下的时间内，认证 机制只是静静的待在那里，将请求发往filter链中的下一个filter。这个基于实际的需求源于这样的一个事实，很少有认证实现在每一个，每一次的调 用的时候都会进行认证（BASIC认证是一个值得注意的例外），但是如果一个pricipal在最初的认证步骤之后帐号被取消了，或者被禁用了，或者被修 改了（例如GrantedAuthority[]中增加或者减少）会怎么样呢？让我们来看看现在这些情况是如何处理的。 <br />
<br />
前面已经介绍 了安全对象的主要认证provider AbstractSecurityInterceptor。这个类需要能够访问一个AuthenticationManager。它同时有个可选配置可以 设定一个认证对象每次安全对象调用的时候是否需要重新认证。如果Authentication.isAuthenticated()返回true，那么它 默认在SecurityContextHolder中的认证对象是已认证的。这样做对于提高性能是非常好的，但是对于即时的认证验证是不理想的。在这样的 情况下你可能需要将AbstractSecurityInterceptor.alwaysReauthenticate属性设置为true。 <br />
<br />
你 可能会问自己&#8220;这个AuthenticationManager是什么？&#8221;我们之前没有见过它，但是我们曾经讨论过 AuthenticationProvider的概念。非常简单，AuthenticationManager负责在 AuthenticationProvider链之间传递请求。它非常象我们之前讨论过的filter链，虽然有一些不同。Acegi Security只提供了一个AuthenticationManager实现，因此让我们看看对于我们这章的例子，它是如何配置的： <br />
<br />
xml 代码 <br />
1. &lt;bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"&gt; <br />
2. &lt;property name="providers"&gt; <br />
3. &lt;list&gt; <br />
4. &lt;ref local="daoAuthenticationProvider"/&gt; <br />
5. &lt;ref local="anonymousAuthenticationProvider"/&gt; <br />
6. &lt;ref local="rememberMeAuthenticationProvider"/&gt; <br />
7. &lt;/list&gt; <br />
8. &lt;/property&gt; <br />
9. &lt;/bean&gt; <br />
<br />
在这个时候，可能值得提到的是你的认证机制（通常是filter）也被注入了一个AuthenticationManager的引用。所以和认证机制都会使用上述的ProviderManager来轮询一系列的AuthenticationProvider。 <br />
<br />
在 我们例子中有三个provider。它们按照上述的顺序调用（使用list而不是set来显示是按照顺序调用的），每个provider都能够尝试认证， 或者仅仅返回一个null来跳过认证。如果所有的实现都返回null，ProviderManager会抛出一个相应的异常。如果你想了解更多 chaining providers的信息，请参阅ProviderManager的JavaDoc。 <br />
<br />
authentication mechanism使用的那些provider有时候是可以互换的，而有时候它们又依赖于特定的authentication mechanism。例如，DaoAuthenticationProvider只需要一个基于字符串的用户名和密码。若干个认证机制会产生基于字符串的 用户名和密码的集合，包括（但不限于）BASIC 和 form 认证。同时，有些认证机制会产生一个只能和特定类型的AuthenticationProvider交互的认证请求对象。一个这种一对一映射的例子是JA -SIG CAS，它使用service ticket的概念，只能被Common Authentication Services CasAuthenticationProvider认证。一个更加深入的一对一映射的例子是LDAP认证机制，它只能由 LdapAuthenticationProvider处理。这种特定的对应关系在每个类的JavaDoc以及在本手册的特定认证方法章节中有详细说明。 你不用担心这些实现的细节，因为如果你忘记注册一个合适的provider，你在尝试认证时只会收到一个 ProviderNotFoundException异常。 <br />
<br />
当你在FilterChainProxy中正确配置了认证机制，并且确保 注册了对应的AuthenticationProvider，你的最后一步是配置一个AuthenticationEntryPoint。回忆一下早先我 们讨论过的ExceptionTranslationFilter的角色，当一个基于HTTP的请求收到一个HTTP头或者一个HTTP重定向以开始认证 时它被使用。继续我们早先的例子： <br />
<br />
xml 代码 <br />
1. &lt;bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter"&gt; <br />
2. &lt;property name="authenticationEntryPoint"&gt;&lt;ref <br />
3. local="authenticationProcessingFilterEntryPoint"/&gt;&lt;/property&gt; <br />
4. &lt;property name="accessDeniedHandler"&gt; <br />
5. &lt;bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl"&gt; <br />
6. &lt;property name="errorPage" value="/accessDenied.jsp"/&gt; <br />
7. &lt;/bean&gt; <br />
8. &lt;/property&gt; <br />
9. &lt;/bean&gt; <br />
10. &lt;bean id="authenticationProcessingFilterEntryPoint" <br />
11. class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint"&gt; <br />
12. &lt;property name="loginFormUrl"&gt;&lt;value&gt;/acegilogin.jsp&lt;/value&gt;&lt;/property&gt; <br />
13. &lt;property name="forceHttps"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/property&gt; <br />
14. &lt;/bean&gt; <br />
<br />
注 意到ExceptionTranslationFilter需要两个协作者。第一个AccessDeniedHandlerImpl，使用一个 RequestDispatcher导向显示特定的访问拒绝的错误页面。我们使用forwad所以SecurityContextHolder中仍然保留 principal的详细信息，这些对于显示给用户来说是有用的（在Acegi Security的老版本中，我们依赖rervlet容器来处理403错误信息，它缺乏这个有用的上下文信息）。 AccessDeniedHandlerImpl同时将会将HTTP头设置为403，它是访问拒绝的正式错误代码。至于 AuthentionEntryPoint，这里设置如果一个未受认证的principal尝试执行一个受保护的操作时，我们需要执行那些动作。因为在我 们的例子中要使用基于form的认证，因此我们设定AuthenticationProcessinFilterEntryPoint以及登录页面的 URL。你的应用系统通常只需要一个entry point，并且大多数的认证方法都定义了自己特有的AuthenticationEntryPoint。每个认证方式所对应的特定entry point的详细情况会在本手册特定的认证方法章节中介绍。 <br />
6.2. UserDetails 和 Associated Types <br />
正如在第一部分中提到的，大多数认证provider要用到UserDetails 和UserDetailsService 接口。后面那个接口只包含一个方法： <br />
<br />
java 代码 <br />
1. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, <br />
2. DataAccessException; <br />
<br />
<br />
返 回值UserDetails是一个接口，它提供了若干个getter保证返回非null值，例如用户名，密码，授予的权限以及用户是启用还是禁用状态。大 部分认证provider都会使用一个，即使它在认证判断过程中实际并不使用用户名和密码。通常这些provider只会使用返回的 UserDetails中的GrantedAuthority[]信息，因为有些系统（例如LDAP 或 X509 或 CAS）已经承担了实际的身份验证的责任。 <br />
<br />
Acegi Security提供了一个UserDetails的实体类实现－User。Acegi Security用户需要确定什么时候实现UserDetailsService以及返回什么样的UserDetails实体类。通常，直接使用User 类或者继承User类就可以了，尽管有一些特殊情况(例如 object relational mappers)，需要用户从头写他们自己的UserDetails实现。这种情况也时有发生，用户只要返回他们正常的代表系统用户的领域对象就可以了。 特别是UserDetails经常被用来存储额外的principal相关属性（例如他们的电话号码以及email地址），这样它们可以很容易被web视 图使用。 <br />
<br />
特定的UserDetailsService实现起来是很简单的，它应该很容易由用户来选择持久化策略来获取认证信息。说到这里，Acegi Security确实包含了一些有用的基础实现，下面让我们看一下。 <br />
<br />
6.2.1. In-Memory 认证 <br />
虽 然用户可以创建一个定制的UserDetailsService实现来从一个持久化引擎中获取信息，很多应用不需要这种复杂性。特别是如果你正在进行快速 原型开发或者刚开始集成Acegi Security，当你不需要花费时间来进行数据库配置或者写UserDetailsService的实现。这种情况之下，你有一个简单的选择，就是配置 InMemoryDaoImpl实现。 <br />
<br />
xml 代码 <br />
1. &lt;bean id="inMemoryDaoImpl" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl"&gt; <br />
2. &lt;property name="userMap"&gt; <br />
3. &lt;value&gt; <br />
4. marissa=koala,ROLE_TELLER,ROLE_SUPERVISOR <br />
5. dianne=emu,ROLE_TELLER <br />
6. scott=wombat,ROLE_TELLER <br />
7. peter=opal,disabled,ROLE_TELLER <br />
8. &lt;/value&gt; <br />
9. &lt;/property&gt; <br />
10. &lt;/bean&gt; <br />
<br />
在 上面的例子中，userMap属性包含了每个用户的用户名，密码，一个授权列表以及一个可选的启用/禁用关键词。使用逗号分隔。用户名必须在等号的左侧， 密码必须在等号右侧第一个出现。启用和禁用关键词（大小写敏感）可以出现在第二个或者之后任意位置。剩余的字符串被看作是授予的权限，这些权钱被创建为 GrantedAuthorityImpl对象（仅供参考－大多数的应用不需要自定义的GrantedAuthority实现，所以使用默认的实现就可以 了）。注意如果一个用户没有密码及或没有被授予权限，该用户不会在in-memory 认证库中创建。 <br />
<br />
InMemoryDaoImpl 也提供了一个setUserProperties(Properties)方法，可以允许你用另一个Spring的配置好的bean或者一个外部的 properties文件来实例化属性。你可能要使用Spring的PropertiesFactoryBean，它在加载外部属性文件的时候非常有用。 这个setter可能对于有大量用户的应用，或者开发期配置变更有所助益，但是不要指望使用整个数据库来处理认证细节。 <br />
<br />
6.2.2. JDBC 认证 <br />
也 包括了一个从JDBC数据源获取认证信息的UserDetailsService。使用Spring内部的JDBC，避免了仅仅为了存储用户信息而使用复 杂的对象关系Common Authentication Services 映射（ORM）。如果你确实使用ORM工具，你可能要写一个定制的UserDetailsService来重用你已经创建的映射文件。回到 JdbcDaoImpl，下面是一个配置的例子： <br />
<br />
xml 代码 <br />
1. &lt;bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt; <br />
2. &lt;property name="driverClassName"&gt;&lt;value&gt;org.hsqldb.jdbcDriver&lt;/value&gt;&lt;/property&gt; <br />
3. &lt;property name="url"&gt;&lt;value&gt;jdbc:hsqldb:hsql://localhost:9001&lt;/value&gt;&lt;/property&gt; <br />
4. &lt;property name="username"&gt;&lt;value&gt;sa&lt;/value&gt;&lt;/property&gt; <br />
5. &lt;property name="password"&gt;&lt;value&gt;&lt;/value&gt;&lt;/property&gt; <br />
6. &lt;/bean&gt; <br />
7. &lt;bean id="jdbcDaoImpl" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl"&gt; <br />
8. &lt;property name="dataSource"&gt;&lt;ref bean="dataSource"/&gt;&lt;/property&gt; <br />
9. &lt;/bean&gt; <br />
10. <br />
你 可能要修改上述的DriverManagerDataSource来使用不同的关系数据库管理系统。你还可以使用从JNDI获取的全局数据源，如上的常规 Spring选项。不论是使用什么数据库以及如何获取数据源，必须使用一个按照dbinit.txt中写明的数据库模式。你可以从Acegi Security网站下载这个文件。 <br />
<br />
如果你的默认数据库模式不能满足需要，JdbcDaoImpl提供了两个属性允许定制SQL语 句。如果需要进一步定制，你可以继承JdbcDaoImpl。请参考JavaDocs获取详情，不过请注意这个类并不是为了复杂的自定义继承而写的。如果 你的需求比较复杂(例如数据库结构比较特殊或者需要返回一个特定的UserDetails实现)，那么你最好写自己的 UserDetailsService实现。Acegi Security提供的基础实现只是为了典型场景，并没有提供无限的配置灵活性。 <br />
<br />
6.3. 并行Concurrent Session 处理 <br />
Acegi Security能够限定次数防止一个principal多次并行认证到同一个应用。许多ISV利用这一点来加强授权管理，网管也喜欢这个特性因为可以防止一个用户名被重复使用。例如，你可以限制&#8220;Batman&#8221;用户从两个不同的session登录系统。 <br />
<br />
使用并行session支持，你需要在web.xml中增加如下内容： <br />
<br />
xml 代码 <br />
1. &lt;listener&gt; <br />
2. &lt;listener-class&gt;org.acegisecurity.ui.session.HttpSessionEventPublisher&lt;/listener-class&gt; <br />
3. &lt;/listener&gt; <br />
<br />
而 且，你需要在中FilterChainProxy增加 org.acegisecurity.concurrent.ConcurrentSessionFilter to your FilterChainProxy。ConcurrentSessionFilter需要两个属性，sessionRegistry用来指向一个 SessionRegistryImpl实例，expiredUrl指向一个session实效时显示的页面。 <br />
<br />
当一个 HttpSession开始或者结束的时候web.xml HttpSessionEventPublisher发送一个ApplicationEvent到Spring ApplicationContext。这很关键，因为它确保session终止的时候SessionRegistryImpl会收到通知。 <br />
<br />
你还要装配ConcurrentSessionControllerImpl并在ProviderManager中引用： <br />
<br />
xml 代码 <br />
1. &lt;bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"&gt; <br />
2. &lt;property name="providers"&gt; <br />
3. &lt;!-- your providers go here --&gt; <br />
4. &lt;/property&gt; <br />
5. &lt;property name="sessionController"&gt;&lt;ref bean="concurrentSessionController"/&gt;&lt;/property&gt; <br />
6. &lt;/bean&gt; <br />
7. &lt;bean id="concurrentSessionController" <br />
8. class="org.acegisecurity.concurrent.ConcurrentSessionControllerImpl"&gt; <br />
9. &lt;property name="maximumSessions"&gt;&lt;value&gt;1&lt;/value&gt;&lt;/property&gt; <br />
10. &lt;property name="sessionRegistry"&gt;&lt;ref local="sessionRegistry"/&gt;&lt;/property&gt; <br />
11. &lt;/bean&gt; <br />
12. &lt;bean id="sessionRegistry" class="org.acegisecurity.concurrent.SessionRegistryImpl"/&gt; <br />
6.4. 认证标签库 <br />
AuthenticationTag只是用来把principal的Authentication.getPrincipal()对象的属性显示到web页面。 <br />
<br />
下面的JSP片段展示了如何使用AuthenticationTag： <br />
java 代码 <br />
1. "username"/&gt; <br />
<br />
这个标签将会显示pricipal的名字。这里我们假设Authentication.getPrincipal()是一个UserDetails对象，这在使用典型的DaoAuthenticationProvider时候的一般状况。<br />
[转载自 dxjsunday]<img src ="http://www.blogjava.net/mlh123caoer/aggbug/142743.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2007-09-04 21:13 <a href="http://www.blogjava.net/mlh123caoer/archive/2007/09/04/142743.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>什么是JMX?</title><link>http://www.blogjava.net/mlh123caoer/archive/2007/09/03/142456.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Mon, 03 Sep 2007 14:26:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2007/09/03/142456.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/142456.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2007/09/03/142456.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/142456.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/142456.html</trackback:ping><description><![CDATA[<p>JMX(Java Management Extensions)是一个为应用程序植入管理功能的框架。JMX是一套标准的代理和服务，实际上，用户可以在任何Java应用程序中使用这些代理和服务实现管理。 </p>
<p>JMX的前身是<a class="editpage" title="Create 'JMAPI'" href="http://wiki.matrix.org.cn/Edit.jsp?page=JMAPI">JMAPI</a>。 </p>
<p>JMX致力于解决分布式系统管理的问题，因此，能够适合于各种不同的环境是非常重要的。为了能够利用功能强大的Java计算环境解决这一的问题，Sun公司扩充了<a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=Java">Java</a>基础类库，开发了专用的管理类库。 </p>
<p>JMX是一种应用编程接口，可扩充对象和方法的集合体，可以用于跨越一系列不同的异构操作系统平台、系统体系结构和网络传输协议，灵活的开发无缝集成的系统、网络和服务管理应用它提供了用户界面指导、Java类和开发集成系统、网络及网络管理应用的规范。 </p>
<p>管理对象是JMX应用程序的核心。JMX结构包括：支持Java的Web浏览器用户接口，管理运行模块ARM(Admin Runtime Module)和应用。这三个部件之间通过<a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=RMI">RMI</a>（Remote Method Invocation）进行通信。这里需要说明的是，RMI是使得一个Java虚拟机（JVM）上运行的程序可以调用远程服务器上另一个<a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=JVM">JVM</a>总的对象。 </p>
<p>用户接口用来发布管理操作，这些操作可以间接的通过浏览器或通过单独的应用程序来激发。管理运行模块用来给应用提供实例化的管理对象。它包括<a class="editpage" title="Create 'Agent'" href="http://wiki.matrix.org.cn/Edit.jsp?page=Agent">Agent</a>对象接口，通知接口和被管数据接口。应用指的是那些被管设备单元。 </p>
<p>JMX是一个完整的网络管理应用程序开发环境，它同时提供了：厂商需要收集的完整的特性清单，可生成资源清单表格，图形化的用户接口；访问<a class="editpage" title="Create 'SNMP'" href="http://wiki.matrix.org.cn/Edit.jsp?page=SNMP">SNMP</a>的网络API；主机间远程过程调用；数据库访问方法。 </p>
<p>JMX这一轻型的管理基础结构，价值在于对被管理资源的服务实现了抽象，提供了低层的基本类集合，开发人员在保证大多数的公共管理类的完整性和一致性的前提下，进行扩展以满足特定网络管理应用的需要。 </p>
<p>JMX注重于构造管理工具的软件框架，并尽量采用已成熟的技术。 </p>
<p>JMX体系被分成三个层次 </p>
<ul>
    <li>表现层
    <li>代理层
    <li>分布式服务层 </li>
</ul>
<h2 id="section-JMX-_E8_A1_A8_E7_8E_B0_E5_B1_82">表现层 </h2>
<p>表现层定义的是JMX可管理资源所在的层。 </p>
<p>这些已管理的资源可以编写或封装为<a class="editpage" title="Create 'MBean'" href="http://wiki.matrix.org.cn/Edit.jsp?page=MBean">MBean</a>。 </p>
<p>MBean分为四种类型： 标准、动态、开放、模型 </p>
<h2 id="section-JMX-_E4_BB_A3_E7_90_86_E5_B1_82">代理层 </h2>
<p>定义的是MBean向应用程序施加管理的层。包括MBean服务器和代理服务的定义。还至少包括一个协议适配器或连接器。 </p>
<p>代理的组成： 。一个MBean服务器 。要管理的MBean 。作为MBean实现的代理服务 。至少一个协议适配器 </p>
<h3 id="section-JMX-MBean">MBean </h3>
<p>在JMX中，最小的可管理单元是MBean。 </p>
<p>MBean不是一个真正的接口和类，而是必须准循的设计模式以确保资源是一个兼容的MBean。 </p>
<p>MBean的激活方法: </p>
<p>invoke()方法是管理应用程序用于激活MBean的方法的手段。 invoke()方法有三个参数，分别是方法的名称、表示属性的对象数组和描述方法签名的一个字符串数组。它与使用<a class="editpage" title="Create 'JavaReflection'" href="http://wiki.matrix.org.cn/Edit.jsp?page=JavaReflection">Java Reflection</a> Api 激活方法的方式类似。 </p>
<p>Notification(通知)模型： </p>
<p>MBean的通知模型类似与Java事件的监听器模型。 MBean或管理应用程序可以作为MBean事件的监听器注册。 通知支持由两个基本的概念组成，即广播器和监听器。 </p>
<h3 id="section-JMX-MBean_E6_9C_8D_E5_8A_A1_E5_99_A8">MBean服务器 </h3>
<p>MBean服务器用于注册可管理的MBean。 </p>
<p>所有对MBean的请求或查询都是通过MBean服务器实施的。 </p>
<h3 id="section-JMX-_E4_BB_A3_E7_90_86_E6_9C_8D_E5_8A_A1">代理服务 </h3>
<p>代理服务是一些特殊的函数，代理把这些服务提供给MBean，这些代理服务独立于任何MBean。 </p>
<p>一个代理可以提供四种主要的服务： </p>
<ul>
    <li>动态装载：允许代理通过下载这个Bean的类动态实例化MBean，这与装载applet的方式类似。 </li>
</ul>
<p>JMX使用m-let这个标记指定期望动态装载的MBean的位置。 </p>
<ul>
    <li>监控：允许代理通知有关的监听器监控一个MBean的属性值的变化 </li>
</ul>
<p>JMX允许使用三种基本类型的监控程序 (1)CounterMonitor：该程序可以观察类型方面的变化，比如Byte类似或Integer类型 (2)GaugeMonitor：该程序可以观察类型方面的变化，比如Byte类似或Integer类型，还可以在到达上下阀值时进行报告。 (3)StringMonitor：该程序可以观察java.lang.String类型的变化。 </p>
<ul>
    <li>计时器：允许预设的时间间隔发送通知，可以作为一个调度程序
    <li>关系：允许创建和维护MBean之间的关系 </li>
</ul>
<h2 id="section-JMX-_E5_88_86_E5_B8_83_E5_BC_8F_E6_9C_8D_E5_8A_A1_E5_B1_82">分布式服务层 </h2>
<p>包含协议适配器和连接器两种类型的组件，通过它们连接到外部的应用，如<a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=RMI">RMI</a>管理应用、基于浏览器的管理控制等 </p>
<h2 id="section-JMX-_E5_8D_8F_E8_AE_AE_E9_80_82_E9_85_8D_E5_99_A8_E5_92_8C_E8_BF_9E_E6_8E_A5_E5_99_A8">协议适配器和连接器 </h2>
<h2>协议适配器是代理与管理客户通信的手段，每个通信的协议都可能不同。 </h2>
<p>它们都是管理客户与MBean交互的方式。 </p>
<h2 id="section-JMX-JMX_E7_9A_84_E5_A5_BD_E5_A4_84">JMX的好处 </h2>
<ul>
    <li>可减少对JAVA应用实施管理的投资
    <li>提供了一个可伸缩的管理框架
    <li>集成现有的管理方案：如：WBEM，SNMP，TMN
    <li>使用现有的标准JAVA技术
    <li>能使用未来的一些管理概念：如Jini连接技术、通用即插即用、服务定位协议(Service Location Protocol)
    <li>只定义了一些可以访问的接口 </li>
</ul>
<p>相关资源：</p>
<ul>
    <li><a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=JMX%E7%9B%B8%E5%85%B3">JMX相关框架</a>
    <li><a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=MC4J">MC4J</a>
    <li><a class="editpage" title="Create 'XMOJO'" href="http://wiki.matrix.org.cn/Edit.jsp?page=XMOJO">XMOJO</a>
    <li><a class="editpage" title="Create 'MX4J'" href="http://wiki.matrix.org.cn/Edit.jsp?page=MX4J">MX4J</a>
    <li><a class="editpage" title="Create 'JFoxMX'" href="http://wiki.matrix.org.cn/Edit.jsp?page=JFoxMX">JFoxMX</a>
    <li><a class="editpage" title="Create 'JMX4Ant'" href="http://wiki.matrix.org.cn/Edit.jsp?page=JMX4Ant">JMX4Ant</a>
    <li><a class="editpage" title="Create 'Panoptes'" href="http://wiki.matrix.org.cn/Edit.jsp?page=Panoptes">Panoptes</a>
    <li><a class="editpage" title="Create 'EJToolsJMXBrowser'" href="http://wiki.matrix.org.cn/Edit.jsp?page=EJToolsJMXBrowser">EJTools JMX Browser</a>
    <li><a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=JManage">jManage</a> </li>
</ul><img src ="http://www.blogjava.net/mlh123caoer/aggbug/142456.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2007-09-03 22:26 <a href="http://www.blogjava.net/mlh123caoer/archive/2007/09/03/142456.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EJB3.0入门</title><link>http://www.blogjava.net/mlh123caoer/archive/2007/09/02/142067.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Sun, 02 Sep 2007 06:22:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2007/09/02/142067.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/142067.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2007/09/02/142067.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/142067.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/142067.html</trackback:ping><description><![CDATA[<p><span style="word-spacing: 0px; font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 16px; line-height: normal; font-size-adjust: none; font-stretch: normal; text-transform: none; color: #000000; text-indent: 0px; white-space: normal; letter-spacing: normal; border-collapse: separate; orphans: 2; widows: 2;" class="Apple-style-span">作者： Lynn Munsinger<br />
翻译：草儿<br />
时间：2007年8月29日（My Birthday）<br />
原文地址：<span style="word-spacing: 0px; font-family: 'Lucida Grande'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; font-size-adjust: none; font-stretch: normal; text-transform: none; color: #000000; text-indent: 0px; white-space: pre; letter-spacing: normal; border-collapse: separate; orphans: 2; widows: 2;" class="Apple-style-span"><a href="http://www.oracle.com/technology/tech/java/newto/introejb.htm">http://www.oracle.com/technology/tech/java/newto/introejb.htm</a></span></span></p>
<p><br />
EJB3.0规范使开发EJB比过去更容易，可能诱惑你考虑开发第一个EJB。如果真是这种情况，那么祝贺你，<br />
你经成功避免了在你以前EJB开发者的很多挫折，并且享受到EJB3.0开发的便利性。但是你开始开发以前，<br />
你可能想知道EJB是什么和它们用于什么目的。本篇文章解释了EJB的基础和你如何在一个J2EE程序中使用<br />
它们。<br />
<br />
<span class="boldbodycopy">什么是EJB？</span></p>
<p>一个企业JavaBean (EJB)是一个可重用的，可移植的J2EE组件。 EJB由封装了业务逻辑的多个方法组成。<br />
例如，一个EJB可以有包括一个更新客户数据库中数据的方法的业务逻辑。多个远程和本地客户端可以调用这<br />
个方法。另外，EJB运行在一个容器里，允许开发者只关注与bean中的业务逻辑而不用考虑象事务支持，安全<br />
性和远程对象访问等复杂和容易出错的事情。EJB以POJO或者普通旧的Java对象形式开发，开发者可以用元数<br />
据注释来定义容器如何管理这些Bean。</p>
<p><span class="boldbodycopy">EJB类型</span></p>
<p>EJB主要有三种类型：会话Bean，实体Bean和消息驱动Bean。会话Bean完成一个清晰的解耦的任务，例如<br />
检查客户账户历史记录。实体Bean是一个代表存在于数据库中业务对象的复杂业务实体。消息驱动Bean用于<br />
接收异步JMS消息。让我们更详细的认识这些类型。</p>
<p>会话<span class="italicbodycopy">Bean</span></p>
<p>会话Bean一般代表着业务流程中象"处理订单"这样的动作。会话Bean基于是否维护过度状态分为有状<br />
态或者无状态。<br />
无状态会话Bean 没有中间状态。它们不保持追踪一个方法调用另一个方法传递的信息。因此一个无状<br />
态业务方法的每一次调用都独立于它的前一个调用；例如，税费计算或者转移账款。 当计算税费额的方法被<br />
调用时，税费值被计算并返回给调用的方法，没有必要存储调用者为将来调用备用的内部状态。因为它们不<br />
维护状态，所以这些Bean是仅仅由容器管理。当客户端请求一个无状态的Bean实例时，它可以接收来自由容器管理的无状态会话Bean实例集中的一个实例。也因为无状态会话Bean能够被共享，所以容器可以维护更少<br />
数量的实例来为大量的客户端服务。简单地象该Bean增加元注释<span style="font-family: Courier New;">@Stateless</span> 来指定一个 Java Bean作为一个<br />
无状态会话Bean被部署和管理。<br />
一个有状态的会话Bean维护一个跨越多个方法调用的会话状态；例如在线购物篮应用。当客户开始在线<br />
购物时，客户的详细信息从数据库获得。相同的信息对于当客户从购物篮中增加或者移除商品等等操作时被调用的其他方法也是可访问的 。但是因为该状态不是在会话结束，系统崩溃或者网络失败时保留，所以有状<br />
态会话Bean是暂时的。当一个客户端请求一个有状态会话Bean实例时，客户端将会得到一个会话实例，该Bean的状态只为给客户端维持。通过向方法增加元注释<span style="font-family: Courier New;">@Remove来告诉容器当某个方法调用结束一个有状态<br />
会话Bean实例应该被移除。</span></p>
<h4>会话Bean实例</h4>
<blockquote>
<table border="1" width="100%">
    <tbody>
        <tr>
            <td>
            <p><code>import javax.ejb.Stateless.*;</code></p>
            <p><code>/**<br />
            * 一个简单无状态会话Bean实现了CalculateEJB接口的incrementValue()方法<br />
            </code><code>**/<br />
            <br />
            @Stateless(name="CalculateEJB")<br />
            public class CalculateEJBBean<br />
            implements CalculateEJB<br />
            {<br />
            int value = 0;<br />
            public String incrementValue()<br />
            {<br />
            value++;<br />
            return "value incremented by 1";<br />
            }<br />
            }</code></p>
            </td>
        </tr>
    </tbody>
</table>
</blockquote>
<p><span class="italicbodycopy">实体Bean</span></p>
<p>实体Bean是管理持久化数据的一个对象，潜在使用一些相关的Java对象并且可以依靠主键被唯一识别。通<br />
过包括<span style="font-family: Courier New;">@Entity</span> 元注释来指定一个类是一个实体Bean。实体Bean表示来自数据库的持久化数据，例如客户表<br />
中的一个记录，或者一个员工表中的一个员工记录。实体Bean也可以被多个客户端共享。例如一个员工实体<br />
能够被多个计算一个员工每年工资总额或者更新员工地址的客户端使用。实体Bean对象特定变量能够保持持<br />
久化。实体Bean中所有没有<span style="font-family: Courier New;">@Transient</span> 元注释的变量需要考虑持久化。EJB3.0的一个主要特色是创建包含使用元数据注释的对象/关系映射实体Bean的能力。例如，指定实体Bean的empId变量映射到employee表中的<br />
EMPNO属性，象下面实例中一样用<span style="font-family: Courier New;">@Table(name="Employees")</span> 注释这个表的名字和用<span style="font-family: Courier New;">@Column<br />
(name="EMPNO")注释empId变量。另外，EJB3.0中的一个特色是你可以很容易的在开发时测试实体<br />
Bean，可以用<span style="font-family: Times New Roman;">Oracle Application Server Entity Test Harness</span>在容器外部运行一个实体Bean。</span></p>
<h4>实体Bean实例</h4>
<blockquote>
<table border="1" width="100%">
    <tbody>
        <tr>
            <td>
            <p><code>import javax.persistence.*;<br />
            import java.util.ArrayList;<br />
            import java.util.Collection;</code></p>
            <p><code>@Entity<br />
            @Table(name = "EMPLOYEES")<br />
            public class Employee implements java.io.Serializable<br />
            {<br />
            private int empId;<br />
            private String eName;<br />
            private double sal;<br />
            <br />
            @Id<br />
            @Column(name="EMPNO", primaryKey=true)<br />
            public int getEmpId()<br />
            </code><code>{<br />
            return empId;<br />
            </code><code>}</code></p>
            <p><code>public void setEmpId(int empId)<br />
            {<br />
            this.empId = empId;<br />
            }</code></p>
            <p><code>public String getEname()<br />
            {<br />
            return eName;<br />
            }</code></p>
            <p><code>public void setEname(String eName)<br />
            {<br />
            this.eName = eName;<br />
            }<br />
            <br />
            public double getSal()<br />
            {<br />
            return sal;<br />
            }</code><br />
            <br />
            <code>public void setSal(double sal)<br />
            {<br />
            this.sal = sal;<br />
            }<br />
            <br />
            public String toString()<br />
            {<br />
            StringBuffer buf = new StringBuffer();<br />
            buf.append("Class:")<br />
            .append(this.getClass().getName()).append(" :: ").append(" empId:").append(getEmpId()).append(" ename:").append(getEname()).append("sal:").append(getSal());<br />
            return buf.toString();<br />
            }<br />
            }</code></p>
            </td>
        </tr>
    </tbody>
</table>
</blockquote>
<p><span class="italicbodycopy">消息驱动Bean</span></p>
<p>驱动Bean (MDB) 提供了一个实现异步通信比直接使用Java消息服务（JMS）更容易地方法。创建MDB接<br />
收异步JMS消息。容器处理为JMS队列和主题所要求加载处理的大部分工作。它向相关的MDB发送所有的消<br />
息。一个MDB允许J2EE应用发送异步消息，该应用能处理这些消息。实现<span style="font-family: Courier New;"><span style="font-family: Courier New;">javax.jms.<br />
</span></span><span style="font-family: Courier New;">MessageListener接口和使用<code>@MessageDriven注释该Bean来</code></span>指定一个Bean是消息驱动Bean。</p>
<h4>消息驱动Bean实例</h4>
<blockquote>
<table border="1" width="100%">
    <tbody>
        <tr>
            <td>
            <p><code>import javax.ejb.MessageDriven;<br />
            import javax.ejb.ActivationConfigProperty;<br />
            import javax.ejb.Inject;<br />
            import javax.jms.*;<br />
            import java.util.*;<br />
            import javax.ejb.TimedObject;<br />
            import javax.ejb.Timer;<br />
            import javax.ejb.TimerService;<br />
            @MessageDriven(<br />
            activationConfig = {<br />
            @ActivationConfigProperty(propertyName="connectionFactoryJndiName", propertyValue="jms/TopicConnectionFactory"),<br />
            @ActivationConfigProperty(propertyName="destinationName", propertyValue="jms/myTopic"),<br />
            @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Topic"),<br />
            @ActivationConfigProperty(propertyName="messageSelector", propertyValue="RECIPIENT = 'MDB'")</code><br />
            <code>}<br />
            )</code></p>
            <p><code>/**<br />
            *监听可配置JMS队列或者主题和通过当一个消息发送到队列或者主题<br />
            *</code><code>调用它的onMessage()方法得到提醒的一个简单的消息驱动<br />
            *该Bean打印消息的内容<br />
            </code><code>*/</code></p>
            <p><code>public class MessageLogger implements MessageListener, TimedObject<br />
            {</code></p>
            <p><code>@Inject javax.ejb.MessageDrivenContext mc;<br />
            <br />
            public void onMessage(Message message)<br />
            {<br />
            System.out.println("onMessage() - " + message);<br />
            try<br />
            </code><code>{<br />
            </code><code>String subject = message.getStringProperty("subject");<br />
            String inmessage = message.getStringProperty("message");<br />
            System.out.println("Message received\n\tDate: " + new java.util.Date() + "\n\tSubject: " + subject + "\n\tMessage: " + inmessage + "\n");<br />
            System.out.println("Creating Timer a single event timer");<br />
            TimerService ts = mc.getTimerService();<br />
            Timer timer = ts.createTimer(30000, subject);<br />
            System.out.println("Timer created by MDB at: " + new Date(System.currentTimeMillis()) +" with info: "+subject);<br />
            }<br />
            catch (Throwable ex)<br />
            {<br />
            ex.printStackTrace();<br />
            }<br />
            }<br />
            </code><code><br />
            public void ejbTimeout(Timer timer)<br />
            {<br />
            System.out.println("EJB 3.0: Timer with MDB");<br />
            </code><code>System.out.println("ejbTimeout() called at: " + new Date(System.currentTimeMillis()));<br />
            </code><code>return;<br />
            }</code><code><br />
            }</code></p>
            </td>
        </tr>
    </tbody>
</table>
<br />
</blockquote>
<p><span class="boldbodycopy">使用EJB</span></p>
<p>客户端是访问Bean的应用程序。虽然没有必要保存在客户层，但是能够作为一个独立的应用，JSP，<br />
Servlet，或者另一个EJB。客户端通过Bean的远程或者本地接口访问EJB中的方法，主要取决于客户端和Bean<br />
运行在同一个还是不同的JVM中。这些接口定义了Bean中的方法，而由Bean类实际实现这些方法。当一个<br />
客户端访问该Bean类中的一个方法时，容器生成Bean的一个代理，被叫做远程对象或者本地对象。远程或者<br />
本地对象接收请求，委派它到相应的Bean实例，返回结果给客户端。调用一个Bean中的方法，客户端使用定<br />
义在EJB不是描述文件的名字查找到Bean。在以下实例中，客户端使用上下文对象找到命名为"StateLessejb"<br />
Bean。</p>
<p>EJB 客户端实例</p>
<blockquote>
<table border="1" width="100%">
    <tbody>
        <tr>
            <td>
            <p><code>import javax.naming.Context;<br />
            import javax.naming.InitialContext;</code></p>
            <p><code>/**<br />
            * 一个调用无状态会话Bean中方法的简单的Bean客户端<br />
            */</code></p>
            <p><code>public class CalculateejbClient<br />
            {<br />
            public static void main(String [] args)<br />
            {<br />
            Context context = new InitialContext();</code><br />
            <code>CalculateEJB myejb =<br />
            (CalculateEJB)context.lookup("java:comp/env/ejb/CalculateEJB");<br />
            myejb.incrementValue();<br />
            }<br />
            }</code></p>
            </td>
        </tr>
    </tbody>
</table>
<br />
</blockquote>
<p><span class="boldbodycopy">总结</span></p>
<p>EJB3.0开发企业JavaBean是相当容易的。此规范使用元数据注释定义Bean的类型和暴露给客户端的方法。<br />
因此，无论你将创建一个执行特定任务的会话Bean还是映射一个表到实体Bean来更新数据，你都能象使用普<br />
通Java对象和接口一样进行处理，在业务方法中使用元注释向客户端暴露方法。既然你已经理解了EJB的基础,<br />
可以到OTN中<a href="http://www.oracle.com/technology/tech/java/ejb30.html">EJB 3.0 Resources Page</a>发现更多信息。</p><img src ="http://www.blogjava.net/mlh123caoer/aggbug/142067.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2007-09-02 14:22 <a href="http://www.blogjava.net/mlh123caoer/archive/2007/09/02/142067.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>软件开发技术常用术语英中对照</title><link>http://www.blogjava.net/mlh123caoer/archive/2007/08/26/139506.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Sun, 26 Aug 2007 08:45:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2007/08/26/139506.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/139506.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2007/08/26/139506.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/139506.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/139506.html</trackback:ping><description><![CDATA[<p>A.I. 人工智能<br>A2A integration A2A整合<br>abstract 抽象的<br>abstract base class (ABC)抽象基类<br>abstract class 抽象类<br>abstraction 抽象、抽象物、抽象性<br>access 存取、访问<br>access function 访问函数<br>access level访问级别<br>account 账户<br>action 动作<br>activate 激活<br>active 活动的<br>actual parameter 实参<br>adapter 适配器<br>add-in 插件<br>address 地址<br>address space 地址空间<br>address-of operator 取地址操作符<br>ADL (argument-dependent lookup)<br>ADO(ActiveX Data Object)ActiveX数据对象<br>advanced 高级的<br>aggregation 聚合、聚集<br>algorithm 算法<br>alias 别名<br>align 排列、对齐<br>allocate 分配、配置<br>allocator分配器、配置器<br>angle bracket 尖括号<br>annotation 注解、评注<br><span id=more-140></span><br>API (Application Programming Interface) 应用(程序)编程接口<br>app domain (application domain)应用域<br>appearance 外观<br>append 附加<br>application 应用、应用程序<br>application framework 应用程序框架<br>Approximate String Matching 模糊匹配<br>Arbitrary Precision Arithmetic 高精度计算<br>architecture 架构、体系结构<br>archive file 归档文件、存档文件<br>argument引数(传给函式的值)。参见parameter<br>array 数组<br>arrow operator 箭头操作符<br>ASP(Active Server Page)活动服务器页面<br>ASP.NET worker process ASP.NET工作者进程<br>assembly 装配件、配件<br>assembly language 汇编语言<br>assembly manifest 装配件清单<br>assert(ion) 断言<br>assign 赋值<br>assignment 赋值、分配<br>assignment operator 赋值操作符<br>associated 相关的、相关联的<br>associative container 关联式容器(对应sequential container)<br>asynchronous 异步的<br>atomic 原子的<br>atomic operation 原子操作<br>attribute 特性、属性<br>audio 音频<br>authentication service 验证服务<br>authorization 授权<br>B2B integration B2B整合、B2B集成(business-to-business integration)<br>background 背景、后台(进程)<br>backup 备份<br>backup device备份设备<br>backup file 备份文件<br>backward compatible 向后兼容、向下兼容<br>bandwidth 带宽<br>Bandwidth Reduction 带宽压缩<br>base class 基类<br>base type 基类型<br>batch 批处理<br>BCL (base class library)基类库<br>Bin Packing 装箱问题<br>binary 二进制<br>binary function 双参函数<br>binary large object二进制大对象<br>binary operator 二元操作符<br>binary search 二分查找<br>binary tree 二叉树<br>binding 绑定<br>bit 位<br>bitmap 位图<br>bitwise 按位&#8230;<br>bitwise copy 为单元进行复制；位元逐一复制,按位拷<br>bitwise operation 按位运算<br>block 块、区块、语句块<br>bookkeeping 簿记<br>boolean 布林值(真假值，true或false)<br>border 边框<br>bounds checking 边界检查<br>boxing 装箱、装箱转换<br>brace (curly brace) 大括号、花括号<br>bracket (square brakcet) 中括号、方括号<br>breakpoint 断点<br>browser applications 浏览器应用(程序)<br>browser-accessible application 可经由浏览器访问的应用程序<br>bug 臭虫<br>build 编连(专指编译和连接<br>built-in 内建、内置<br>bus 总线<br>business 业务、商务(看场合)<br>business Logic 业务逻辑<br>business rules 业务规则<br>buttons 按钮<br>by/through 通过<br>byte 位元组(由8 bits组成)<br>cache 高速缓存<br>calendar 日历<br>Calendrical Calculations 日期<br>call 调用<br>call operator 调用操作符<br>call-level interface (CLI)调用级接口(CLI)<br>callback 回调<br>candidate key 候选键 (for database)<br>cascading delete 级联删除 (for database)<br>cascading update 级联更新 (for database)<br>casting 转型、造型转换<br>catalog 目录<br>chain 链(function calls)<br>character 字符<br>character format 字符格式<br>character set 字符集<br>check box 复选框<br>check button 复选按钮<br>CHECK constraints CHECK约束 (for database)<br>checkpoint 检查点 (for database)<br>child class 子类<br>CIL (common intermediate language)通用中间语言、通用中介语言<br>class 类<br>class declaration 类声明<br>class definition 类定义<br>class derivation list 类继承列表<br>class factory 类厂<br>class hierarchy 类层次结构<br>class library 类库<br>class loader 类装载器<br>class template 类模板<br>class template partial specializations 类模板部分特化<br>class template specializations 类模板特化<br>classification 分类<br>clause 子句<br>cleanup 清理、清除<br>CLI (Common Language Infrastructure) 通用语言基础设施<br>client 客户、客户端<br>client application 客户端应用程序<br>client area 客户区<br>client cursor 客户端游标 (for database)<br>client-server 客户机/服务器、客户端/服务器<br>clipboard 剪贴板<br>Clique 最大团<br>clone 克隆<br>CLS (common language specification) 通用语言规范<br>code access security 代码访问安全<br>code page 代码页<br>COFF (Common Object File Format) 通用对象文件格式<br>collection 集合<br>COM (Component Object Model) 组件对象模型<br>Combinatorial Problems 组合问题<br>combo box 组合框<br>command line 命令行<br>comment 注释<br>commit 提交 (for database)<br>communication 通讯<br>compatible 兼容<br>compile time 编译期、编译时<br>compiler 编译器<br>component组件<br>composite index 复合索引、组合索引 (for database)<br>composite key 复合键、组合键 (for database)<br>composition 复合、组合<br>Computational Geometry 计算几何<br>concept 概念<br>concrete具体的<br>concrete class 具体类<br>concurrency 并发、并发机制<br>configuration 配置、组态<br>Connected Components 连通分支<br>connection 连接 (for database)<br>connection pooling 连接池<br>console 控制台<br>constant 常量<br>Constrained and Unconstrained Optimization 最值问题<br>constraint 约束 (for database)<br>construct 构件、成分、概念、构造（for language）<br>constructor (ctor) 构造函数、构造器<br>container 容器<br>containment包容<br>context 环境、上下文<br>control 控件<br>Convex Hull 凸包<br>cookie (不译)<br>copy 拷贝<br>CORBA 通用对象请求中介架构(Common Object Request Broker Architecture)<br>cover 覆盖、涵盖<br>create/creation 创建、生成<br>crosstab query 交叉表查询 (for database)<br>CRTP (curiously recurring template pattern)<br>Cryptography 密码<br>CTS (common type system)通用类型系统<br>cube 多维数据集 (for database)<br>cursor 光标<br>cursor 游标 (for database)<br>custom 定制、自定义<br>data 数据<br>data connection 数据连接 (for database)<br>Data Control Language (DCL) 数据控制语言(DCL) (for database)<br>Data Definition Language (DDL) 数据定义语言(DDL) (for database)<br>data dictionary 数据字典 (for database)<br>data dictionary view 数据字典视图 (for database)<br>data file 数据文件 (for database)<br>data integrity 数据完整性 (for database)<br>data manipulation language (DML)数据操作语言(DML) (for database)<br>data mart 数据集市 (for database)<br>data member 数据成员、成员变量<br>data pump 数据抽取 (for database)<br>data scrubbing 数据清理 (for database)<br>data source 数据源 (for database)<br>data source 数据源 (for database)<br>Data source name (DSN) 数据源名称(DSN) (for database)<br>data structure数据结构<br>Data Structures 基本数据结构<br>data table 数据表 (for database)<br>data warehouse 数据仓库 (for database)<br>data-aware control数据感知控件 (for database)<br>data-bound 数据绑定 (for database)<br>database 数据库 (for database)<br>database catalog 数据库目录 (for database)<br>database diagram 数据关系图 (for database)<br>database file 数据库文件 (for database)<br>database object 数据库对象 (for database)<br>database owner 数据库所有者 (for database)<br>database project 数据库工程 (for database)<br>database role 数据库角色 (for database)<br>database schema 数据库模式、数据库架构 (for database)<br>database script 数据库脚本 (for database)<br>datagram 数据报文<br>dataset 数据集 (for database)<br>dataset 数据集 (for database)<br>DBMS (database management system)数据库管理系统 (for database)<br>DCOM (distributed COM)分布式COM<br>dead lock 死锁 (for database)<br>deallocate 归还<br>debug 调试<br>debugger 调试器<br>decay 退化<br>decision support 决策支持<br>declaration 声明<br>declarative referential integrity (DRI)声明引用完整性(DRI) (for database)<br>deduction 推导<br>default 缺省、默认值<br>DEFAULT constraint默认约束 (for database)<br>default database 默认数据库 (for database)<br>default instance 默认实例 (for database)<br>default result set 默认结果集 (for database)<br>defer 推迟<br>definition 定义<br>delegate 委托<br>Delegates 一般译法为&#8221;委托&#8221;，微软没有对这个术语进行正式解释或翻译。<br>delegation 委托<br>dependent name<br>deploy 部署<br>dereference 解引用<br>dereference operator (提领)运算子<br>derived class 派生类<br>design by contract 契约式设计<br>design pattern 设计模式<br>destroy 销毁<br>destructor(dtor)析构函数、析构器<br>Determinants and Permanents 行列式<br>device 设备<br>DHTML (dynamic HyperText Markup Language)动态超文本标记语言<br>dialog 对话框<br>Dictionaries 字典<br>digest 摘要<br>digital 数字的<br>DIME (Direct Internet Message Encapsulation)直接Internet消息封装<br>directive (编译)指示符<br>directory 目录<br>dirty pages脏页 (for database)<br>dirty read 脏读 (for database)<br>disassembler 反汇编器<br>DISCO (Discovery of Web Services)Web Services的查找<br>Discrete Fourier Transform 离散Fourier变换<br>disk 盘<br>dispatch 调度、分派、派发（我喜欢&#8220;调度&#8221;）<br>DISPID (Dispatch Identifier)分派标识符<br>distributed computing 分布式计算<br>distributed query 分布式查询 (for database)<br>DNA (Distributed interNet Application) 分布式网间应用程序<br>document 文档<br>DOM (Document Object Model)文档对象模型<br>dot operator (圆)点操作符<br>double-byte character set (DBCS)双字节字符集(DBCS)<br>DP——Dynamic Programming——动态规划<br>Drawing Graphs Nicely 图的描绘<br>Drawing Trees 树的描绘<br>driver 驱动(程序)<br>DTD (document type definition) 文档类型定义<br>dump 转储<br>dump file 转储文件<br>dynamic assembly 动态装配件、动态配件<br>dynamic binding 动态绑定<br>dynamic cursor 动态游标 (for database)<br>dynamic filter 动态筛选 (for database)<br>dynamic locking 动态锁定 (for database)<br>dynamic recovery 动态恢复 (for database)<br>dynamic snapshot 动态快照 (for database)<br>dynamic SQL statements 动态SQL语句 (for database)<br>e-business 电子商务<br>EAI (enterprise application integration)企业应用程序集成(整合)<br>EBCO (empty base class optimization) 空基类优化（机制）<br>Edge and Vertex Connectivity 割边/割点<br>Edge Coloring 边染色<br>EDI (Dlectronic Data Interchange)电子数据交换<br>efficiency 效率<br>efficient 高效<br>encapsulation 封装<br>enclosing class 外围类别(与巢状类别 nested class有关)<br>end user 最终用户<br>end-to-end authentication 端对端身份验证<br>engine 引擎<br>entity 实体<br>enum (enumeration) 枚举<br>enumerators 枚举成员、枚举器<br>equal 相等<br>equality 相等性<br>equality operator 等号操作符<br>error log 错误日志 (for database)<br>escape character 转义符、转义字符<br>escape code 转义码<br>Eulerian Cycle / Chinese Postman Euler回路/中国邮路<br>evaluate 评估<br>event 事件<br>event driven 事件驱动的<br>event handler 事件处理器<br>evidence 证据<br>exception 异常<br>exception declaration 异常声明<br>exception handling 异常处理、异常处理机制<br>exception specification 异常规范<br>exception-safe 异常安全的<br>exclusive lock 排它锁 (for database)<br>exit 退出<br>explicit 显式<br>explicit specialization 显式特化<br>explicit transaction 显式事务 (for database)<br>export 导出<br>expression 表达式<br>facility 设施、设备<br>Factoring and Primality Testing 因子分解/质数判定<br>fat client 胖客户端<br>feature 特性、特征<br>Feedback Edge/Vertex Set 最大无环子图<br>fetch 提取<br>field 字段 (for database)<br>field 字段(java)<br>field length 字段长度 (for database)<br>file 文件<br>filter 筛选 (for database)<br>finalization 终结<br>finalizer 终结器<br>Finite State Machine Minimization 有穷自动机简化<br>firewall 防火墙<br>firmware 固件<br>flag 标记<br>flash memory 闪存<br>flush 刷新<br>font 字体<br>For GUI 界面<br>foreign key (FK) 外键(FK) (for database)<br>form 窗体<br>formal parameter 形参<br>forward declaration 前置声明<br>forward-only 只向前的<br>forward-only cursor 只向前游标 (for database)<br>fragmentation 碎片 (for database)<br>framework 框架<br>full specialization 完全特化<br>function 函数<br>function call operator (即operator ()) 函数调用操作符<br>function object 函数对象<br>function overloaded resolution函数重载决议<br>function template函数模板<br>functionality 功能<br>functor 仿函数<br>GAC (global assembly cache) 全局装配件缓存、全局配件缓存<br>game 游戏<br>GC (Garbage collection) 垃圾回收(机制)、垃圾收集(机制)<br>generate 生成<br>Generating Graphs 图的生成<br>Generating Partitions 划分生成<br>Generating Permutations 排列生成<br>Generating Subsets 子集生成<br>generic 泛化的、一般化的、通用的<br>generic algorithm通用算法<br>genericity 泛型<br>getter (相对于 setter)取值函数<br>global 全局的<br>global object 全局对象<br>global scope resolution operator 全局范围解析操作符<br>grant 授权 (for database)<br>granularity 粒度<br>Graph Data Structures 图<br>Graph Isomorphism 同构<br>Graph Partition 图的划分<br>Graph Problems — hard 图论-NP问题<br>Graph Problems — polynomial 图论-多项式算法<br>group 组、群<br>group box 分组框<br>GUI 图形界面<br>GUID (Globally Unique Identifier) 全球唯一标识符<br>Hamiltonian Cycle Hamilton回路<br>hand shaking 握手<br>handle 句柄<br>handler 处理器<br>hard disk 硬盘<br>hard-coded 硬编码的<br>hard-copy 截屏图<br>hardware 硬件<br>hash table 散列表、哈希表<br>header file头文件<br>heap 堆<br>help file 帮助文件<br>hierarchical data 阶层式数据、层次式数据<br>hierarchy 层次结构、继承体系<br>high level 高阶、高层<br>hook 钩子<br>Host (application)宿主(应用程序)<br>hot key 热键<br>HTML (HyperText Markup Language) 超文本标记语言<br>HTTP (HyperText Transfer Protocol) 超文本传输协议<br>HTTP pipeline HTTP管道<br>hyperlink 超链接<br>icon 图标<br>IDE (Integrated Development Environment)集成开发环境<br>identifier 标识符<br>IDL (Interface Definition Language) 接口定义语言<br>idle time 空闲时间<br>if and only if当且仅当<br>IL (Intermediate Language) 中间语言、中介语言<br>image 图象<br>IME 输入法<br>immediate base 直接基类<br>immediate derived 直接派生类<br>immediate updating 即时更新 (for database)<br>implement 实现<br>implementation 实现、实现品<br>implicit 隐式<br>implicit transaction隐式事务 (for database)<br>import 导入<br>in-place active 现场激活<br>increment operator 增加操作符<br>incremental update 增量更新 (for database)<br>Independent Set 独立集<br>index 索引 (for database)<br>infinite loop 无限循环<br>infinite recursive 无限递归<br>information 信息<br>infrastructure 基础设施<br>inheritance 继承、继承机制<br>initialization 初始化<br>initialization list 初始化列表、初始值列表<br>initialize 初始化<br>inline 内联<br>inline expansion 内联展开<br>inner join 内联接 (for database)<br>instance 实例<br>instantiated 具现化、实体化(常应用于template)<br>instantiation 具现体、具现化实体(常应用于template)<br>integrate 集成、整合<br>integrity 完整性、一致性<br>integrity constraint完整性约束 (for database)<br>interacts 交互<br>interface 接口<br>interoperability 互操作性、互操作能力<br>interpreter 解释器<br>interprocess communication (IPC)进程间通讯(IPC)<br>Intersection Detection 碰撞测试<br>introspection 自省<br>invariants 不变性<br>invoke 调用<br>isolation level 隔离级别 (for database)<br>item 项、条款、项目<br>iterate 迭代<br>iteration 迭代(回圈每次轮回称为一个iteration)<br>iterative 反复的、迭代的<br>iterator 迭代器<br>JIT compilation JIT编译 即时编译<br>Job Scheduling 工程安排<br>Kd-Trees 线段树<br>key 键 (for database)<br>key column 键列 (for database)<br>Knapsack Problem 背包问题<br>laser 激光<br>late binding 迟绑定<br>left outer join 左向外联接 (for database)<br>level 阶、层例<br>library 库<br>lifetime 生命期、寿命<br>Linear Programming 线性规划<br>link 连接、链接<br>linkage 连接、链接<br>linker 连接器、链接器<br>list 列表、表、链表<br>list box 列表框<br>literal constant 字面常数<br>livelock 活锁 (for database)<br>load 装载、加载<br>load balancing 负载平衡<br>loader 装载器、载入器<br>local 局部的<br>local object 局部对象<br>lock 锁<br>log 日志<br>login 登录<br>login security mode登录安全模式 (for database)<br>Longest Common Substring 最长公共子串<br>lookup table 查找表 (for database)<br>loop 循环<br>loose coupling 松散耦合<br>lvalue 左值<br>machine code 机器码、机器代码<br>macro 宏<br>maintain 维护<br>Maintaining Line Arrangements 平面分割<br>managed code 受控代码、托管代码<br>Managed Extensions 受控扩充件、托管扩展<br>managed object 受控对象、托管对象<br>mangled name<br>manifest 清单<br>manipulator 操纵器(iostream预先定义的一种东西)<br>many-to-many relationship 多对多关系 (for database)<br>many-to-one relationship 多对一关系 (for database)<br>marshal 列集<br>Matching 匹配<br>Matrix Multiplication 矩阵乘法<br>Medial-Axis Transformation 中轴变换<br>Median and Selection 中位数<br>member 成员<br>member access operator 成员取用运算子(有dot和arrow两种)<br>member function 成员函数<br>member initialization list成员初始值列表<br>memberwise 以member为单元&#8230;、members 逐一&#8230;<br>memberwise copy<br>memory 内存<br>memory leak 内存泄漏<br>menu 菜单<br>message 消息<br>message based 基于消息的<br>message loop 消息环<br>message queuing消息队列<br>metadata 元数据<br>metaprogramming元编程<br>method 方法<br>micro 微<br>middle tier 中间层<br>middleware 中间件<br>MIME Multipurpose Internet Mail Extension 多用途 Internet 邮件扩展<br>Minimum Spanning Tree 最小生成树<br>Minkowski Sum Minkowski和<br>modeling 建模<br>modeling language 建模语言<br>modem 调制解调器<br>modifier 修饰字、修饰符<br>module 模块<br>most derived class最底层的派生类<br>Motion Planning 运动规划<br>mouse 鼠标<br>multi-tasking 多任务<br>multi-thread 多线程<br>multicast delegate 组播委托、多点委托<br>multidimensional OLAP (MOLAP) 多维OLAP(MOLAP) (for database)<br>multithreaded server application 多线程服务器应用程序<br>multiuser 多用户<br>mutable 可变的<br>mutex 互斥元、互斥体<br>named parameter 命名参数<br>named pipe 命名管道<br>namespace 名字空间、命名空间<br>native 原生的、本地的<br>native code 本地码、本机码<br>Native Image Generator (NGEN)本地映像生成器<br>Nearest Neighbor Search 最近点对查询<br>nested class 嵌套类<br>nested query 嵌套查询 (for database)<br>nested table 嵌套表 (for database)<br>network 网络<br>network card 网卡<br>Network Flow 网络流<br>nondependent name<br>Numerical Problems 数值问题<br>object 对象<br>object based 基于对象的<br>object file 目标文件<br>object model 对象模型<br>object oriented 面向对象的<br>object pooling 对象池化<br>ODBC data source ODBC数据源 (for database)<br>ODBC driver ODBC驱动程序 (for database)<br>ODR (one-definition rule)<br>OLE Automation objects OLE自动化对象 (for database)<br>OLE Automation server OLE自动化服务器 (for database)<br>OLE DB consumer OLE DB使用者 (for database)<br>OLE DB for OLAP 用于OLAP的OLE DB (for database)<br>OLE DB provider OLE DB提供者 (for database)<br>one-to-many relationship 一对多关系 (for database)<br>one-to-one relationship 一对一关系 (for database)<br>online analytical processing (OLAP) 联机分析处理(OLAP) (for database)<br>online redo log 联机重做日志 (for database)<br>online transaction processing (OLTP) 联机事务处理(OLTP) (for database)<br>Open Data Services (ODS) 开放式数据服务(ODS) (for database)<br>Open Database Connectivity (ODBC) 开放式数据库连接(ODBC) (for database)<br>operand 操作数<br>operating system (OS) 操作系统<br>operation 操作<br>operator 操作符、运算符<br>optimizer 优化器<br>option 选项<br>outer join 外联接 (for database)<br>overflow 上限溢位(相对于underflow)<br>overhead 额外开销<br>overload 重载<br>overload resolution 重载决议<br>overloaded function 重载的函数<br>overloaded operator 被重载的操作符<br>override 覆写、重载、重新定义<br>package 包<br>packaging 打包<br>palette 调色板<br>parallel 并行<br>parameter 参数、形式参数、形参<br>parameter list 参数列表<br>parameterize 参数化<br>parent class 父类<br>parentheses 圆括弧、圆括号<br>parse 解析<br>parser 解析器<br>part 零件、部件<br>partial specialization 局部特化<br>pass by address 传址(函式引数的传递方式)(非正式用语)<br>pass by reference 传地址、按引用传递<br>pass by value 按值传递<br>pattern 模式<br>PDA (personal digital assistant)个人数字助理<br>PE (Portable Executable) file 可移植可执行文件<br>performance 性能<br>persistence 持久性<br>PInvoke (platform invoke service) 平台调用服务<br>pixel 像素<br>placeholder 占位符<br>placement delete<br>placement new<br>Planarity Detection and Embedding 平面性检测和嵌入<br>platform 平台<br>POD (plain old data (type))<br>POI (point of instantiation)<br>Point Location 位置查询<br>pointer 指针<br>poll 轮询<br>Polygon Partitioning 多边形分割<br>polymorphism 多态<br>pooling 池化<br>pop up 弹出式<br>port 端口<br>postfix 后缀<br>precedence 优先序(通常用于运算子的优先执行次序)<br>prefix 前缀<br>preprocessor 预处理器<br>primary key (PK)主键(PK) (for database)<br>primary table 主表 (for database)<br>primary template原始模板<br>primitive type 原始类型<br>print 打印<br>printer 打印机<br>Priority Queues 堆<br>procedural 过程式的、过程化的<br>procedure 过程<br>process 进程<br>profile 评测<br>profiler 效能(性能)评测器<br>program 程序<br>programmer 程序员<br>programming编程、程序设计<br>progress bar 进度指示器<br>project 项目、工程<br>property 属性<br>protocol 协议<br>pseudo code伪码<br>qualified 经过资格修饰(例如加上scope运算子)<br>qualified name<br>qualifier 修饰符<br>quality 质量<br>queue 队列<br>race condition 竞争条件（多线程环境常用语）<br>radian 弧度<br>radio button 单选按钮<br>raise 引发(常用来表示发出一个exception)<br>random number 随机数<br>Random Number Generation 随机数生成<br>range 范围、区间<br>Range Search 范围查询<br>rank 等级<br>raw 未经处理的<br>re-direction 重定向<br>readOnly只读<br>record 记录 (for database)<br>recordset 记录集 (for database<br>recursion —— 递归<br>recursive 递归<br>refactoring 重构<br>refer 引用、参考<br>reference 引用、参考<br>reference counting引用计数<br>referential integrity (RI)引用完整性(RI) (for database)<br>reflection 反射<br>refresh data 刷新数据 (for database)<br>register 寄存器<br>regular expression 正则表达式<br>relational database 关系数据库<br>remote 远程<br>remote request 远程请求<br>represent 表述，表现<br>resolution 解析过程<br>resolve 解析、决议<br>result set 结果集 (for database)<br>retrieve data 检索数据<br>return 返回<br>return type 返回类型<br>return value 返回值<br>revoke 撤销<br>right outer join 右向外联接 (for database)<br>robust 健壮<br>robustness 健壮性<br>roll back 回滚 (for database)<br>roll forward 前滚 (for database)<br>routine 例程<br>row 行 (for database)<br>row lock 行锁 (for database)<br>rowset 行集 (for database)<br>RPC (remote procedure call)RPC(远程过程调用)<br>runtime 执行期、运行期、执行时、运行时<br>rvalue 右值<br>Satisfiability 可满足性<br>save 保存<br>savepoint 保存点 (for database)<br>SAX (Simple API for XML)<br>scalable 可伸缩的、可扩展的<br>schedule 调度<br>scheduler 调度程序<br>schema 模式、纲目结构<br>scope 作用域、生存空间<br>scope operator 生存空间操作符<br>scope resolution operator 生存空间解析操作符<br>screen 屏幕<br>scroll bar滚动条<br>SDK (Software Development Kit)软件开发包<br>sealed class 密封类<br>search 查找<br>Searching 查找<br>semantics 语义<br>semaphore 信号量<br>sequential container序列式容器<br>serial 串行<br>serialization/serialize 序列化<br>server 服务器、服务端<br>server cursor服务端游标、服务器游标 (for database)<br>session 会话 (for database)<br>Set and String Problems 集合与串的问题<br>Set Cover 集合覆盖<br>Set Data Structures 集合<br>Set Packing 集合配置<br>setter 设值函数<br>Shape Similarity 相似多边形<br>shared lock 共享锁 (for database)<br>Shortest Common Superstring 最短公共父串<br>Shortest Path 最短路径<br>sibling 同级<br>side effect 副作用<br>signature 签名<br>Simplifying Polygons 多边形化简<br>single-threaded 单线程<br>slider滑块<br>slot 槽<br>smart pointer 智能指针<br>SMTP (Simple Mail Transfer Protocol) 简单邮件传输协议<br>snapshot 截屏图<br>snapshot 快照 (for database)<br>SOAP (simple object access protocol) 简单对象访问协议<br>software 软件<br>Solving Linear Equations 线性方程组<br>Sorting 排序<br>source code 源码、源代码<br>specialization 特化<br>specification 规范、规格<br>splitter 切分窗口<br>SQL (Structured Query Language) 结构化查询语言 (for database)<br>stack 栈、堆栈<br>stack unwinding 叠辗转开解(此词用于exception主题)<br>standard library 标准库<br>standard template library 标准模板库<br>stateless 无状态的<br>statement 语句、声明<br>static cursor 静态游标 (for database)<br>static SQL statements 静态SQL语句 (for database)<br>status bar 状态条<br>Steiner Tree Steiner树<br>stored procedure 存储过程 (for database)<br>stream 流<br>string 字符串<br>String Matching 模式匹配<br>stub 存根<br>subobject子对象<br>subquery 子查询 (for database)<br>subroutine 子例程<br>subscript operator 下标操作符<br>subset 子集<br>subtype 子类型<br>support 支持<br>suspend 挂起<br>symbol 记号<br>syntax 语法<br>system databases 系统数据库 (for database)<br>system tables 系统表 (for database)<br>table 表 (for database)<br>table lock 表锁 (for database)<br>table-level constraint 表级约束 (for database)<br>tape backup 磁带备份 (for database)<br>target 标的,目标<br>task switch 工作切换<br>TCP (Transport Control Protocol) 传输控制协议<br>template 模板<br>template argument deduction 模板参数推导<br>template explicit specialization 模板显式特化<br>template parameter 模板参数<br>template template parameter<br>template-id<br>temporary object 临时对象<br>temporary table 临时表 (for database)<br>text 文本<br>Text Compression 压缩<br>text file 文本文件<br>thin client 瘦客户端<br>third-party 第三方<br>thread 线程<br>thread-safe 线程安全的<br>throw 抛出、引发(常指发出一个exception)<br>token 符号、标记、令牌（看场合）<br>Topological Sorting 拓扑排序<br>trace 跟踪<br>transaction 事务 (for database)<br>transaction log 事务日志 (for database)<br>transaction rollback 事务回滚 (for database)<br>transactional replication 事务复制 (for database)<br>Transitive Closure and Reduction 传递闭包<br>translation unit 翻译单元<br>Traveling Salesman Problem 旅行商问题<br>traverse 遍历<br>Triangulation 三角剖分<br>trigger 触发器 (for database)<br>tuple<br>two-phase commit 两阶段提交 (for database)<br>two-phase lookup 两阶段查找<br>type 类型<br>UDDI(Universary Description, Discovery and Integration)统一描述、查询与集成<br>UML (unified modeling language)统一建模语言<br>unary function 单参函数<br>unary operator 一元操作符<br>unboxing 拆箱、拆箱转换<br>underflow 下限溢位(相对于overflow)<br>Unicode 统一字符编码标准，采用双字节对字符进行编码<br>Union query 联合查询 (for database)<br>UNIQUE constraints UNIQUE约束 (for database)<br>unique index 唯一索引 (for database)<br>unmanaged code 非受控代码、非托管代码<br>unmarshal 散集<br>unqualified 未经限定的、未经修饰的<br>URI (Uniform Resource identifier) 统一资源标识符<br>URL (Uniform Resource Locator) 统一资源定位器<br>user 用户<br>user interface 用户界面<br>value types 值类型<br>variable 变量<br>vector 向量(一种容器，有点类似array)<br>VEE (Virtual Execution Engine)虚拟执行引擎<br>vendor 厂商<br>Vertex Coloring 点染色<br>Vertex Cover 点覆盖<br>viable 可行的<br>video 视频<br>view 视图 (for database)<br>view 视图<br>virtual function 虚函数<br>virtual machine 虚拟机<br>virtual memory 虚拟内存<br>Voronoi Diagrams Voronoi图<br>vowel 元音字母<br>Web Services web服务<br>WHERE clause WHERE子句 (for database)<br>wildcard characters 通配符字符 (for database)<br>wildcard search 通配符搜索 (for database)<br>window 窗口<br>window function 窗口函数<br>window procedure 窗口过程<br>Windows authentication Windows身份验证<br>wizard 向导<br>word 单词<br>word processor 字处理器<br>wrapper 包装、包装器<br>write enable 写启用 (for database)<br>write-ahead log 预写日志 (for database)<br>write-only 只写<br>WSDL (Web Service Description Language)Web Service描述语言<br>XML (eXtensible Markup Language) 可扩展标记语言<br>XML Message Interface (XMI) XML消息接口<br>XSD (XML Schema Definition) XML模式定义语言<br>XSL (eXtensible Stylesheet Language) 可扩展样式表语言<br>XSLT (eXtensible Stylesheet Language Transformation)可扩展样式表语言转换<br>xxx based 基于xxx的<br>xxx oriented 面向xxx</p>
<p>数据结构术语英中对照表<br>abstract data type 抽象数据类型<br>activity on edge AOE网<br>activity on vertex AOV网<br>adjacency list 邻接表<br>adjacency matrix 邻接矩阵<br>adjacency multilist 邻接多重表<br>adjacent edge 相邻边<br>adjacent vertex 相邻顶点<br>ancestor 祖先<br>arc 弧<br>array 数组<br>articulation point 连接点<br>atomic data type 基本数据类型<br>augmenting path 增广路径<br>augmenting path graph 增广路径图<br>average search length 平均查找长度<br>balance merging sort 平衡归并排序<br>balance two-way merging 二路平衡归并排序<br>banlanced binary tree 平衡二叉树<br>biconnected graph 重连通图<br>binary search 二分查找<br>binary search tree 二叉查找树<br>binary sort tree 二叉排序树<br>binary tree 二叉树<br>bipartite graph 二部图<br>blank string 空白（空格）串<br>block search 分块查找<br>bottom 栈底<br>brother 兄弟<br>children 孩子<br>circular linked list 循环链表<br>cirular queue 循环队列<br>column major order 以列为主的顺序分配<br>complete binary tree 完全二叉树<br>complete graph 完全图<br>connected component 连通分量<br>connected graph 连通图<br>critical path 关键路径<br>cycle 回路（环）<br>data abstraction 数据抽象<br>data element 数据元素<br>data item 数据项<br>data object 数据对象<br>data type 数据类型<br>decision tree 判定树<br>deletion 删除<br>dense graph 稠密图<br>depth 深度<br>deque(double-ended queue) 双端列表<br>descentdant 子孙<br>destination 终点<br>digital analysis method 数字分析法<br>digital search tree 数字查找树<br>digraph(directed graph) 有向图<br>diminishing increment sort 随小增量排序<br>direct access file 直接存取文件<br>directed acyclic graph 有向无环图<br>directory structure 目录结构<br>division method 除法<br>doubly linked list 双向链表<br>doubly linked tree 双链树<br>edge 边<br>external sort 外部排序<br>file 文件<br>first-out list 先进先出表（队列）first-in<br>first-out list 后进先出表（队列）last-in<br>fixed-aggregate data type 固定聚合数据类型<br>folding method 折叠法<br>forest 森林<br>front 队头<br>full binary tree 满二叉树<br>generalized list 广义表<br>grabh 图<br>hash funticion 散列函数<br>hash search 散列查找<br>hash table 散列表<br>head 弧头<br>head node 头结点<br>head pointer 头指针<br>heap sort 堆排序<br>Huffman tree 哈夫曼树<br>immediate predecessor 直接前趋<br>immediate successor 直接后继<br>immediately allocating method 直接定址法<br>incident edge 关联边<br>indegree 入度<br>indexed file 索引文件<br>indexed non-sequential file 索引非顺序文件<br>indexed sequential file 索引顺序文件<br>initial node 初始结点<br>inorder traversal 中序遍历<br>insertion 插入<br>insertion sort 插入排序<br>internal sort 内部排序<br>inverted file 倒排文件<br>leaf 叶子<br>level 层次<br>linear linked list 线性链表<br>linear list 线性表<br>linear structure 线性结构<br>link 链<br>link field 链域<br>linked list 链表<br>logical structure 逻辑结构<br>master file 主文件<br>matching 匹配<br>matrix 矩阵<br>maximum matching 最大匹配<br>merge sort 归并排序<br>mid-square method 平方取中法<br>minimum(cost)spanning tree 最小（代价）生成树<br>multi-dimentional array 多维数组<br>multilinked list 多重链表<br>multilist file 多重链表文件<br>node 结点<br>nonlinear structure 非线性结构<br>ordered pair 有序对<br>ordered tree 有序数<br>orthogonal list 十字链表<br>outdegree 出度<br>overflow 上溢<br>parents 双亲<br>partical order 偏序<br>path 路径<br>phyical structure 物理结构<br>ployphase merging sort 多步归并排序<br>pointer 指针<br>pointer field 指针域<br>pop 弹出<br>postorder traversal 后序遍历<br>predecessor 前趋<br>preorder traversal 先序遍历<br>push 压入<br>queue 队列<br>quick sort 快速排序<br>radix sort 基数排序<br>random number method 随机数法<br>rear 队尾<br>replacement selection sort 置换选择排序<br>root 根<br>row major order 以行为主的顺序分配<br>search (sequential search) 线性查找（顺序查找）linear<br>searching 查找，线索<br>searching 查找<br>selection sort 选择排序<br>sequential file 顺序文件<br>shortest path 最短路径<br>simple cycle 简单回路<br>simple path 简单路径<br>single linked list 单链表<br>sink 汇点<br>sort 排序<br>sorting 排序（分类)<br>source 源点<br>spanning forest 生成森林<br>spanning tree 生成树<br>spares graph 稀疏图<br>sparse matrix 稀疏矩阵<br>stack 栈<br>string 空串（零串）null<br>string 串<br>string 串<br>strongly connected graph 强连通图<br>subgraph 子图<br>substring 子串<br>subtree 子树<br>successor 后继<br>symmetric matrix 对称矩阵<br>tail 弧尾<br>tail pointer 尾指针<br>terminal node 终端结点<br>threaded binary tree 线索二叉树<br>top 栈定<br>topological order 拓扑有序<br>topological sort 拓扑排序<br>transposed matrix 转置矩阵<br>traversal of tree 树的遍历<br>traversing binary tree 遍历二叉树<br>traversing graph 遍历图<br>tree 树<br>tree index 树型索引<br>truangular matrix 三角矩阵<br>unconnected graph 非连通图<br>underflow 下溢<br>undigraph(undirected graph) 无向图<br>unordered pair 无序对<br>unordered tree 无序数<br>updating 更新<br>variable-aggregate data type 可变聚合数据类型<br>vertex 顶点<br>weakly connected graph 弱连通图<br>weight 权<br>weighted graph 加权图</p>
<p>算法常用术语英中对照<br>Approximate String Matching 模糊匹配<br>Arbitrary Precision Arithmetic 高精度计算<br>Bandwidth Reduction 带宽压缩<br>Bin Packing 装箱问题<br>Calendrical Calculations 日期<br>Clique 最大团<br>Combinatorial Problems 组合问题<br>Computational Geometry 计算几何<br>Connected Components 连通分支<br>Constrained and Unconstrained Optimization 最值问题<br>Convex Hull 凸包<br>Cryptography 密码<br>Data Structures 基本数据结构<br>Determinants and Permanents 行列式<br>Dictionaries 字典<br>Discrete Fourier Transform 离散Fourier变换<br>Drawing Graphs Nicely 图的描绘<br>Drawing Trees 树的描绘<br>Edge and Vertex Connectivity 割边/割点<br>Edge Coloring 边染色<br>Eulerian Cycle / Chinese Postman Euler回路/中国邮路<br>Factoring and Primality Testing 因子分解/质数判定<br>Feedback Edge/Vertex Set 最大无环子图<br>Finite State Machine Minimization 有穷自动机简化<br>Generating Graphs 图的生成<br>Generating Partitions 划分生成<br>Generating Permutations 排列生成<br>Generating Subsets 子集生成<br>Graph Data Structures 图<br>Graph Isomorphism 同构<br>Graph Partition 图的划分<br>Graph Problems — hard 图论-NP问题<br>Graph Problems — polynomial 图论-多项式算法<br>Hamiltonian Cycle Hamilton回路<br>Independent Set 独立集<br>Intersection Detection 碰撞测试<br>Job Scheduling 工程安排<br>Kd-Trees 线段树<br>Knapsack Problem 背包问题<br>Linear Programming 线性规划<br>Longest Common Substring 最长公共子串<br>Maintaining Line Arrangements 平面分割<br>Matching 匹配<br>Matrix Multiplication 矩阵乘法<br>Medial-Axis Transformation 中轴变换<br>Median and Selection 中位数<br>Minimum Spanning Tree 最小生成树<br>Minkowski Sum Minkowski和<br>Motion Planning 运动规划<br>Nearest Neighbor Search 最近点对查询<br>Network Flow 网络流<br>Numerical Problems 数值问题<br>Planarity Detection and Embedding 平面性检测和嵌入<br>Point Location 位置查询<br>Polygon Partitioning 多边形分割<br>Priority Queues 优先队列<br>Random Number Generation 随机数生成<br>Range Search 范围查询<br>rate of convergence 收敛速度<br>robustness 鲁棒性<br>Satisfiability 可满足性<br>Searching 查找<br>Set and String Problems 集合与串的问题<br>Set Cover 集合覆盖<br>Set Data Structures 集合<br>Set Packing 集合配置<br>Shape Similarity 相似多边形<br>Shortest Common Superstring 最短公共父串<br>Shortest Path 最短路径<br>Simplifying Polygons 多边形化简<br>Solving Linear Equations 线性方程组<br>Sorting 排序<br>Steiner Tree Steiner树<br>String Matching 模式匹配<br>Text Compression 压缩<br>Topological Sorting 拓扑排序<br>Transitive Closure and Reduction 传递闭包<br>Traveling Salesman Problem 旅行商问题<br>Triangulation 三角剖分<br>Vertex Coloring 点染色<br>Vertex Cover 点覆盖<br>Voronoi Diagrams Voronoi图 </p>
<p>English Simplified Chinese </p>
<p>RIA &#8211; Rich Internet Application 丰富互联网应用程序<br>Framework 框架<br>delivery. delivering (a RIA) 提供<br>design pattern 设计模式<br>application vs. architectural framework 应用程序与架构框架<br>leveraging 利用<br>Factory, Flyweight, Observer, Decorator 工厂模式, 享元模式, 观察者模式, 装饰模式 Singleton 单例<br>Mandelbrot Mandelbrot<br>manage state 管理状态<br>stateful client 状态客户端<br>best practice 最佳实践<br>architecting the user experience 构建用户经验<br>widget 窗口小部件<br>upgrade 升级<br>development tool 开发工具<br>parent (of object), child 父级(对象),子对象<br>encapsulate 封装<br>implementation 实现<br>data collection 数据集合<br>persistence framework 持续性框架<br>transaction framework 事务框架<br>logging framework 日志框架<br>aspect-oriented framewor 面向方面的框架<br>animation framework 动画框架<br>unit-testing framework 单元测试框架<br>history management 历史管理<br>layout management 布局管理<br>cursor management 光标管理<br>exception handling 异常处理<br>application-level services 应用程序层服务<br>highly granular 高度微粒化<br>software engineering 软件工程<br>instance (of a class) （类的）实例<br>subset 子集 user gestures 用户姿态<br>drag&#8217;n'drop functionality 拖（拽）放功能 </p><img src ="http://www.blogjava.net/mlh123caoer/aggbug/139506.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2007-08-26 16:45 <a href="http://www.blogjava.net/mlh123caoer/archive/2007/08/26/139506.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Adobe Flex2</title><link>http://www.blogjava.net/mlh123caoer/archive/2007/07/06/128519.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Fri, 06 Jul 2007 02:59:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2007/07/06/128519.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/128519.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2007/07/06/128519.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/128519.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/128519.html</trackback:ping><description><![CDATA[<p><br>Flex2应用程序在无所不在的轻量级虚拟机Flash播放器9跨平台运行。该平台包括以下技术：<br>1、一种基于XML的MXML语言，它支持面对设计者的GUI组件声明式编程；<br>2、标准的OOP语言，基于最新的ECMASript规范的AS3；<br>3、使用FDS（Flex Data Services）方式进行服务端集成，是客户端程序能够对J2EE世界透明访问；<br>4、图表组件；<br>5、基于Eclipse功能强大的IDE，拥有自动化部署，调试，代码跟踪能力。<br>Flex2平台易于扩展也对服务端技术例如JAVA，ColdFusion，PHP，Ruby，ASP等等实现集成。即将发布的Adobe Apollo版允许基于Flash Player，Flex，PDF和HTML桌面程序的构建。<br>SWF文件格式是开放的，有第三方开源产品象Laszlo系统的OpenLaszlo为构建RIA程序提供工具，程序使用Flash Player发布。<br>与上一个版本相反，Flex2提供一种不会招致授权协议纠纷而构建RIA的方式。以下都免费得到：<br>1、MXML：基于XML声明式用来构建GUI的编程语言；<br>2、ActionScript3.0：与JAVA相似的OOP语言；<br>3、Flash Player9：运行在WEB浏览器占有很少内存的虚拟机，运行你编译的二进制代码（.SWF）;<br>4、命令行编译器和调试器；<br>5、Flex 框架：包含设计良好的GUI组件库：按钮，tab目录，数据网格，树控制，动画效果等等很多。<br>6、Flex数据服务预览版：部署在J2EE服务器WEB程序与运行在Flash Player上的ActionScript客户端程序通信模板。FDS预览版只能运行在单CPU上并且不支持在（24*7）高可访问性配置模式下使用。</p>
<p>构建一个基本的Flex2程序步骤有：<br>1、通过增加XML组件例如下面按钮来构建这个程序：<br>&lt;mx:Button label="Place Order" click="processOrder(event)"/&gt;<br>若使用收费的开发工具Flex Builder IDE，你就可以使用拖拉技术了。当然，你也可以手写MXML文本。<br>2、写按照业务逻辑ActionScript代码，例如：<br>private function processOrder (event:Event):void{<br>//业务逻辑代码<br>}<br>3、编译代码。Flex编译器自动的把MXML转换为ActionScript代码并以SWF格式字节码输出在Flash Player 9或者更高版本运行，如果你用Flex Builder IDE，你将得到更爽的自动化编译过程。<br>4、在你选择的WEB服务器中部署SWF文件和封装好的HTML页面。如果你用收钱的那个工具，这些过程完全透明。<br>有一个在线Flex编译器网站，你可以试着写一些Flex代码而不用在你自己的电脑上安装任何东西。同时该网站提供了一些示例代码供您修改和运行。还等什么，GO：<a href="http://try.flex.org/">http://try.flex.org/</a></p><img src ="http://www.blogjava.net/mlh123caoer/aggbug/128519.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2007-07-06 10:59 <a href="http://www.blogjava.net/mlh123caoer/archive/2007/07/06/128519.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Set up an SQL realm with DB2 Express-C, Eclipse WTP, and WebSphere Application Server Community Edition V1.1（2）</title><link>http://www.blogjava.net/mlh123caoer/archive/2007/01/12/93456.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Fri, 12 Jan 2007 07:33:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2007/01/12/93456.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/93456.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2007/01/12/93456.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/93456.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/93456.html</trackback:ping><description><![CDATA[<p>
				<span class="atitle">Conclusion</span>
		</p>
		<a name="conclusion">
				<p>This tutorial showed you how to create an SQL realm and deploy a Web application that uses the realm. In this example, you used DB2 Express-C as the database and the Eclipse Web Tools Platform for the development environment to create an application and deploy it to WebSphere Application Server Community Edition for hosting the application.</p>
				<p>
						<a name="N1064E">
								<b>Acknowledgements</b>
						</a>
				</p>
				<p>The author would like to thank Manu T. George (WebSphere Application Server Community Edition L3 Support) and Anitha Krishnasamy (WebSphere Application Server Community Edition Business Development) for reviewing this tutorial and providing their valuable comments.</p>
				<p>
						<span class="atitle">
								<a name="download">Download</a>
						</span>
				</p>
				<p>
				</p>
				<table class="data-table-1" cellspacing="0" cellpadding="0" width="70%" border="0">
						<tbody>
								<tr>
										<th>Description</th>
										<th>Name</th>
										<th align="right">Size</th>
										<th>Download method</th>
								</tr>
								<tr>
										<td class="tb-row">Sample code for this tutorial</td>
										<td nowrap="">sample-db2-realm.zip</td>
										<td nowrap="" align="right">28KB</td>
										<td nowrap="">
												<a class="fbox" href="http://www.ibm.com/developerworks/views/download.jsp?contentid=160154&amp;filename=sample-db2-realm.zip&amp;method=http&amp;locale=worldwide">
														<b>
																<font color="#002c99">HTTP</font>
														</b>
												</a>
										</td>
								</tr>
						</tbody>
				</table>
				<br />
				<p>
						<a name="resources">
								<span class="atitle">Resources</span>
						</a>
				</p>
				<p>
						<b>Learn</b>
						<br />
				</p>
				<ul>
						<li>
								<a href="http://www.ibm.com/developerworks/edu/j-dw-java-kickstart-i.html?S_TACT=105AGX01&amp;S_CMP=SIMPLE">
										<font color="#002c99">Kick-start your Java apps</font>
								</a>
								<br />
								<br />
						</li>
						<li>
								<a href="http://www.ibm.com/developerworks/websphere/zones/was/wasce.html">
										<font color="#002c99">WebSphere Application Server Community Edition resources</font>
								</a>
						</li>
				</ul>
				<p>
						<br />
						<b>Get products and technologies</b>
						<br />
				</p>
				<ul>
						<li>
								<a href="http://www.ibm.com/developerworks/downloads/ws/wasce/?S_TACT=105AGX10&amp;S_CMP=WSDD">
										<font color="#002c99">Download WebSphere Application Server Community Edition V1.1</font>
								</a>
								<br />
								<br />
						</li>
						<li>
								<a href="http://www.ibm.com/developerworks/downloads/im/udbexp/?S_TACT=105AGX10&amp;S_CMP=WSDD">
										<font color="#002c99">Download DB2 Express-C</font>
								</a>
								<br />
								<br />
						</li>
						<li>
								<a href="http://www.eclipse.org/downloads/">
										<font color="#002c99">Download Eclipse</font>
								</a>
								<br />
								<br />
								<p>
										<a name="author">
												<span class="atitle">About the author</span>
										</a>
								</p>
								<table cellspacing="0" cellpadding="0" width="70%" border="0">
										<tbody>
												<tr>
														<td colspan="3">
																<img height="5" alt="" src="https://www.ibm.com/i/c.gif" width="100%" />
														</td>
												</tr>
												<tr valign="top" align="left">
														<td>
																<p>
																		<img height="80" alt="" src="http://www.ibm.com/developerworks/i/p-kbalachandar.jpg" width="64" align="left" />
																</p>
														</td>
														<td>
																<img height="5" alt="" src="https://www.ibm.com/i/c.gif" width="4" />
														</td>
														<td width="100%">
																<p>
																		<b>Krishnakumar Balachandar</b> is a senior staff software engineer at IBM Software labs in Bangalore, India. He is part of the support team for Geronimo and WebSphere Community Edition. </p>
														</td>
												</tr>
										</tbody>
								</table>
						</li>
				</ul>
		</a><img src ="http://www.blogjava.net/mlh123caoer/aggbug/93456.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2007-01-12 15:33 <a href="http://www.blogjava.net/mlh123caoer/archive/2007/01/12/93456.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Thinking XML: Good advice for creating XML</title><link>http://www.blogjava.net/mlh123caoer/archive/2007/01/12/93350.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Fri, 12 Jan 2007 02:35:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2007/01/12/93350.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/93350.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2007/01/12/93350.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/93350.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/93350.html</trackback:ping><description><![CDATA[<p>Level: Introductory</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/xml/library/x-think35.html#author">
						<font color="#996699">Uche Ogbuji</font>
				</a> (<a href="mailto:uche.ogbuji@fourthought.com?subject=Good advice for creating XML&amp;cc=dwxed@us.ibm.com"><font color="#5c81a7">uche.ogbuji@fourthought.com</font></a>), Principal Consultant, Fourthought, Inc<br /></p>
		<p>31 Jan 2006</p>
		<blockquote>The use of XML has become widespread, but much of it is not well formed. When it is well formed, it's often of poor design, which makes processing and maintenance very difficult. And much of the infrastructure for serving XML can compound these problems. In response, there has been some public discussion of XML best practices, such as Henri Sivonen's document, "HOWTO Avoid Being Called a Bozo When Producing XML." Uche Ogbuji frequently discusses XML best practices on IBM developerWorks, and in this column, he gives you his opinion about the main points discussed in such articles.</blockquote>
		<!--START RESERVED FOR FUTURE USE INCLUDE FILES-->
		<script language="JavaScript" type="text/javascript">
				<!--
if (document.referrer&&document.referrer!="") { 
   // document.write(document.referrer);
   var q = document.referrer;
   var engine = q;
   var isG = engine.search(/google\.com/i);
   var searchTerms;
   //var searchTermsForDisplay;
   if (isG != -1) { 
	   var i = q.search(/q=/);
	   var q2 = q.substring(i+2);
	   var j = q2.search(/&/);
	   j = (j == -1)?q2.length:j;
	   searchTerms = q.substring(i+2,i+2+j);
	   if (searchTerms.length != 0) {
	       searchQuery(searchTerms);
	       document.write("<div id=\"contents\"></div>");
	   }
   } 
}
//-->
		</script>
		<!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
		<p>I have been discussing XML best practices in this column and in other series for years. Others, such as fellow columnist Elliotte Rusty Harold, have covered it as well. The more XML experts that join the discussion of XML design principles, the better, so the community can converge on solid advice for developers at all levels of XML adoption. In this article, using a recent document and a classic one, you learn more details about XML best practices.</p>
		<p>
				<a name="N1006A">
						<span class="atitle">
								<font face="Arial" size="4">Enter the no bozo zone</font>
						</span>
				</a>
		</p>
		<p>Henri Sivonen wrote a useful article, "HOWTO Avoid Being Called a Bozo When Producing XML" (see <a href="http://www-128.ibm.com/developerworks/xml/library/x-think35.html#resources"><font color="#996699">Resources</font></a>). Adopting the perspective of XML-based Web feed formats, such as RSS and Atom, he goes over his Dos and Don'ts for producing well-formed XML with namespaces. As he says in his introduction:</p>
		<blockquote>There seem to be developers who think that well-formedness is awfully hard -- if not impossible -- to get right when producing XML programmatically and developers who can get it right and wonder why the others are so incompetent. I assume no one wants to appear incompetent or to be called names. Therefore, I hope the following list of Dos and Don'ts helps developers to move from the first group to the latter. </blockquote>
		<p>The first bit of advice Henri gives is, "Don't think of XML as a text format." I think this is dangerous advice. Certainly his main point is valid -- you cannot be as careless in producing or editing XML as you would a simple text document, but this applies to all text formats with any structure. However, saying that XML is not text is denying one of the most important characteristics of XML, one that is enshrined in the very definition of XML in the specification. ("A textual object is a well-formed XML document [if it conforms to this specification.]") Henri's statement is also confusing because there is a technical definition of text in XML that is essentially the sequence of characters interpreted as XML. Text is not merely what goes within leaf elements or within attributes -- technically called <i>character data</i>. Text is the fundamental fabric of all XML entities, so to say that XML is not text is a contradiction. I think it's more useful to highlight the specific ways in which XML differs from text formats with which developers might already be familiar.</p>
		<p>This comment is an example of how Henri's advice is colored by his interest in the problem of generating well-formed Web feeds. He is right to warn people that carelessly slapping strings together and hoping they are well formed is a dangerous course. I too have written articles advising people to use mature XML toolkits rather than simple text tools when generating XML (see <a href="http://www-128.ibm.com/developerworks/xml/library/x-think35.html#Resources"><font color="#996699">Resources</font></a>). My concern is that the way in which Henri couches this advice is a bit confusing and could be misconstrued in the broader context of XML processing. He reiterates his advice in the sections, "Don't use text-based templates" and "Don't <code>print</code>". I think this should be summarized as: "Do not use mechanisms that you're not sure will result in well-formed XML." That's very important advice indeed. One approach to safe XML generation is sending SAX events, as Henri suggests in, "Use a tree or a stack (or an XML parser)." If you do so, however, do not assume you are home free. The SAX tools you use might not do all the necessary well-formedness checking. For example, some Unicode characters are not allowed in XML. You may need an additional level of checking to account for such issues.</p>
		<p>Henri rightly suggests that users not try to manage namespaces by hand. As I've discussed on developerWorks, XML namespaces require a great deal of care. His suggestion that developers only think in terms of universal name [namespace Uniform Resource Identifier (URI) plus local name] is generally sound, but sometimes a developer cannot avoid dealing with prefixes or XML declarations. In specifications, such as XSLT, a <i>QName</i> (prefix/local name combination) can be used within attribute values, and the prefix is supposed to be interpreted according to in-scope namespace declarations. This kind of pattern is called a <i>QName in context</i>. In this case, the developer must have control over the declared prefix or the resulting XML processing will fail. When developers do manage their own namespace declarations, the result is often messy because of the complexities of XML namespaces.</p>
		<p>One way to clean up namespace syntax that might become messy while passing through a pipeline of XML processing is to insert a canonicalization step to the end of the pipeline. XML canonicalization eliminates the syntactic variations permitted by XML 1.0 and XML namespaces, including different namespace declaration patterns. Canonicalization will not eliminate all the issues that make namespace declarations treacherous to developers. Canonicalization does not help with QNames in context problems since it does not change the prefixes used in a document, but it does reduce the mess of namespace declarations to the point where you can easily spot problems or even write code to automatically fix them. The GenX library, which is one of the XML generation options Henri suggests, automatically generates canonical XML, and many other toolkits provide canonicalization as an option.</p>
		<p>Henri's advice about Unicode and character handling is almost completely sound. However, in "Avoid adding pretty-printing white space in character data," I think the case is a bit overstated. Pretty-printing XML is safe in most cases between elements, rather than within elements with character data. As Henri says, if you have the XML in <a href="http://www-128.ibm.com/developerworks/xml/library/x-think35.html#listing1"><font color="#996699">Listing 1</font></a>, it is usually not safe to render it as in <a href="http://www-128.ibm.com/developerworks/xml/library/x-think35.html#listing2"><font color="#996699">Listing 2</font></a>.</p>
		<br />
		<a name="listing1">
				<b>Listing 1. XML sample</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console" size="2">&lt;foo&gt;bar&lt;/foo&gt;
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<a name="listing2">
				<b>Listing 2. XML sample with white space added to character data</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console" size="2">&lt;foo&gt;
  bar
&lt;/foo&gt;
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>But it is usually safe to pretty-print the XML in <a href="http://www-128.ibm.com/developerworks/xml/library/x-think35.html#listing3"><font color="#996699">Listing 3</font></a>, so that the output is as in <a href="http://www-128.ibm.com/developerworks/xml/library/x-think35.html#listing4"><font color="#996699">Listing 4</font></a>.</p>
		<br />
		<a name="listing3">
				<b>Listing 3. Another XML sample</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console" size="2">&lt;doc&gt;&lt;foo&gt;bar&lt;/foo&gt;&lt;/doc&gt;
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<a name="listing4">
				<b>Listing 4. XML sample in Listing 3 with white space added to character data</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console" size="2">&lt;doc&gt;
  &lt;foo&gt;bar&lt;/foo&gt;
&lt;/doc&gt;
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>Many XML serializer tools understand this distinction between relatively safe and relatively unsafe pretty-printing. It is important to understand that the form of pretty-printing shown in Listings 3 and 4 can cause distortion if white space is added to mixed content. Such problems can be avoided if the serialization is guided by a schema. In practice, though, most vocabularies that use mixed content are not so sensitive to white space normalization, so don't worry too much about pretty-printing. You should be knowledgeable of the issues, and be sure there is an option to turn pretty-printing off (preferably the default should be to <i>not</i> pretty-print). Henri recommends a pretty-printing practice as in <a href="http://www-128.ibm.com/developerworks/xml/library/x-think35.html#listing5"><font color="#996699">Listing 5</font></a>, but I disagree because I think it makes for ugly markup that's not friendly to manipulation by people.</p>
		<br />
		<a name="listing5">
				<b>Listing 5. Pretty-printing convention suggested by Henri Sivonen but not recommended by this author</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console" size="2">&lt;foo
    &gt;bar&lt;/foo
&gt;
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<a name="N100EC">
						<span class="atitle">
								<font face="Arial" size="4">From the monastery</font>
						</span>
				</a>
		</p>
		<p>Switching to a very different speed, the second resource I shall explore in this article is Simon St. Laurent's "Monastic XML" (see <a href="http://www-128.ibm.com/developerworks/xml/library/x-think35.html#resources"><font color="#996699">Resources</font></a>). This is a collection of brief essays with advice on how to process and even think about XML for maximum effect. Simon uses the metaphors of monasticism and asceticism to suggest that it is dangerous to load XML too heavily with baggage that does not suit its simple, textual roots. In "Marking-up at the foundation," he discusses the fundamental roles of character data and markup (elements and attributes). In "Naming things and reading names," he explains why the generic identifier (also called the element type name) is an important concept and how it should be the sole primary key to the structure of the marked-up information. Realistically, if you're using XML namespaces, the primary key is the universal name (namespace URI plus local name), and this complication is one of the reasons Simon urges caution in "Namespaces as opportunity." "Accepting the discipline of trees" calls out one of XML's dirty secrets: Even though it seems that XML's hierarchical structure could be easily extended to graph structure, in practice, the modeling of graphs in XML has proven a bit difficult. But by far the most important lesson on the "Monastic XML" site is found in "Optimizing markup for processing is always premature." XML is a declarative technology, and therein lies its strengths, as well as its frustrations, for many developers. Developers who try to pull XML design too close to the details of processing generally end up making that processing more difficult in the long term. The key to success with XML is to focus on the nature of the information that needs to be represented in the abstract separately from the technical design of the systems that need to process that information.</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/xml/library/x-think35.html#main">
																				<b>
																						<font color="#996699" size="2">Back to top</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N100FB">
						<span class="atitle">
								<font face="Arial" size="4">Wrap up</font>
						</span>
				</a>
		</p>
		<p>There is always bound to be some difference of opinion when considering XML best practices, especially in these early stages, but it is great to have a variety of voices on the topic. There are a few other sources for discussion of the topic, and I'll continue to cover them in this column. If you have sources for advice on best practices or want to share your own opinion, please join the discussion on the <a href="http://www.ibm.com/developerworks/forums/dw_forum.jsp?forum=185&amp;cat=11"><font color="#5c81a7">Thinking XML discussion forum</font></a>.</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/xml/library/x-think35.html#main">
																				<b>
																						<font color="#996699" size="2">Back to top</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">
								<font face="Arial" size="4">Resources</font>
						</span>
				</a>
		</p>
		<b>Learn</b>
		<br />
		<ul>
				<li>Read the online articles covered in this piece: "<a href="http://hsivonen.iki.fi/producing-xml/"><font color="#5c81a7">HOWTO Avoid Being Called a Bozo When Producing XML</font></a>," by Henri Sivonen and "<a href="http://monasticxml.org/markup.html"><font color="#5c81a7">Monastic XML</font></a>," by Simon St. Laurent. <br /><br /></li>
				<li>Learn more about the basic nature of XML, rather than just guessing. Start with "<a href="http://www.textuality.com/sgml-erb/dd-1996-0001.html"><font color="#5c81a7">Design Principles for XML</font></a>," which explains why XML is the way it is. See discussion and resources in "<a href="http://www.oreillynet.com/pub/wlg/5440"><font color="#5c81a7">Once again: no excuses to ignore i18n in XML</font></a>," by Uche Ogbuji, and be sure to bookmark "<a href="http://www.xml.com/axml/testaxml.htm"><font color="#5c81a7">The Annotated XML Specification</font></a>," which is the XML 1.0 specification with useful and liberal annotation by Tim Bray, one of the editors of the specification; just be aware that this covers the first edition of XML 1.0, which is now up to the third edition.<br /><br /></li>
				<li>Find out some of the hazards of producing XML through careless text printing in "<a href="http://www.xml.com/pub/a/2002/11/13/py-xml.html"><font color="#5c81a7">Proper XML Output in Python</font></a>." Despite the title, the discussion is useful for Python and non-Python programmers alike. More specific to Python, read a clarification of the details of Python and Unicode in "<a href="http://copia.ogbuji.net/blog/2006-01-09/Confusion_"><font color="#5c81a7">Confusion over Python storage form for Unicode</font></a>." Both articles are by Uche Ogbuji.<br /><br /></li>
				<li>Learn more about XML canonicalization in "<a href="http://www.ibm.com/developerworks/xml/library/x-c14n/"><font color="#5c81a7">Introducing XML canonical form</font></a>," (developerWorks, December 2004) by Uche Ogbuji. <br /><br /></li>
				<li>Find more XML resources on the <a href="http://www.ibm.com/developerworks/xml/"><font color="#996699">developerWorks XML zone</font></a>, where you'll find <a href="http://www.ibm.com/developerworks/views/xml/libraryview.jsp?search_by=thinking+xml"><font color="#5c81a7">previous installments</font></a> of the <i>Thinking XML</i> column, such as "<a href="http://www.ibm.com/developerworks/xml/library/x-think25.html"><font color="#5c81a7">Harold's Effective XML</font></a>" (July 2004) and "<a href="http://www.ibm.com/developerworks/xml/library/x-think26.html"><font color="#5c81a7">Hacking XML Hacks</font></a> (September 2004)." If you have comments on this article or any others in this column, please post them on <a href="http://www.ibm.com/developerworks/forums/dw_forum.jsp?forum=185&amp;cat=11"><font color="#5c81a7">the <i>Thinking XML</i> forum</font></a>.<br /><br /></li>
				<li>For more on XML best practices, see the series "<a href="http://www.ibm.com/developerworks/views/xml/libraryview.jsp?search_by=principles+of+xml+design"><font color="#5c81a7">Principles of XML design</font></a>" by Uche Ogbuji. <br /><br /></li>
				<li>Learn how you can become an <a href="http://www-03.ibm.com/certify/certs/adcdxmlrt.shtml"><font color="#5c81a7">IBM Certified Developer in XML and related technologies</font></a>.<br /><br /></li>
				<li>
						<a href="http://safari.bvdep.com/">
								<font color="#5c81a7">Browse for books</font>
						</a> on these and other technical topics.<br /><br /></li>
		</ul>
		<br />
		<b>Get products and technologies</b>
		<br />
		<ul>
				<li>Build your next development project with <a href="http://www.ibm.com/developerworks/downloads?S_TACT=105AGX06&amp;S_CMP=ART"><font color="#5c81a7">IBM trial software</font></a>, available for download directly from developerWorks. <br /><br /></li>
		</ul>
		<br />
		<b>Discuss</b>
		<br />
		<ul>
				<li>
						<a href="http://www.ibm.com/developerworks/forums/dw_forum.jsp?forum=185&amp;cat=11">
								<font color="#5c81a7">Participate in the discussion forum</font>
						</a>.<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/blogs/">
								<font color="#5c81a7">developerWorks blogs</font>
						</a>: Get involved in the developerWorks community. </li>
		</ul>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/xml/library/x-think35.html#main">
																				<b>
																						<font color="#996699" size="2">Back to top</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">
								<font face="Arial" size="4">About the author</font>
						</span>
				</a>
		</p>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td colspan="3">
										<font face="Arial" size="4">
												<img height="5" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										</font>
								</td>
						</tr>
						<tr valign="top" align="left">
								<td>
										<p>
												<font face="Arial" size="4">
														<img height="80" alt="Uche Ogbuji photo" src="http://www.ibm.com/developerworks/i/p-uche.jpg" width="64" align="left" />
												</font>
										</p>
								</td>
								<td>
										<font face="Arial" size="4">
												<img height="5" alt="" src="http://www.ibm.com/i/c.gif" width="4" />
										</font>
								</td>
								<td width="100%">
										<p>Uche Ogbuji is a consultant and co-founder of <a href="http://fourthought.com/"><font color="#5c81a7">Fourthought, Inc.</font></a>, a software vendor and consultancy specializing in XML solutions for enterprise knowledge management. Fourthought develops <a href="http://4suite.org/"><font color="#5c81a7">4Suite</font></a>, an open source platform for XML, RDF, and knowledge-management applications. Mr. Ogbuji is also a lead developer of the <a href="http://uche.ogbuji.net/tech/rdf/versa/"><font color="#5c81a7">Versa</font></a> RDF query language. He is a computer engineer and writer born in Nigeria, living and working in Boulder, Colorado, USA. You can find more about Mr. Ogbuji at his Weblog <a href="http://copia.ogbuji.net/blog/"><font color="#5c81a7">Copia</font></a>, or contact him at <a href="mailto:uche.ogbuji@fourthought.com"><font color="#5c81a7">uche.ogbuji@fourthought.com</font></a>.</p>
								</td>
						</tr>
				</tbody>
		</table><img src ="http://www.blogjava.net/mlh123caoer/aggbug/93350.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2007-01-12 10:35 <a href="http://www.blogjava.net/mlh123caoer/archive/2007/01/12/93350.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SCA/SDO走向成熟 将正式成为SOA标准</title><link>http://www.blogjava.net/mlh123caoer/archive/2007/01/12/93334.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Fri, 12 Jan 2007 01:39:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2007/01/12/93334.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/93334.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2007/01/12/93334.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/93334.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/93334.html</trackback:ping><description><![CDATA[本系列的主要内容是展望2007年即将出现的面向服务架构的标准情况。本文将首先将介绍服务组件架构(Service component architecture,SCA)和服务数据对象(Service Data Object,SDO)。2007年SCA规范和SDO规范逐渐成熟，在新的一年，SCA规范和SDO规范将正式被归为SOA标准。
<p>查看第二部分：<a href="http://searchwebservices.techtarget.com.cn/comment/464/3033464.shtml" target="_blank"><font face="Verdana" color="#0000ff">WS-Policy今年进入SOA标准审核流程</font></a></p><p>　　SCA规范和SDO规范将成为专门提供编程模型的标准，开发人员可以在创建Web服务时使用SCA和SDO规范，尽管此时SCA规范和SDO规范还没有完全成熟，达到标准水平，但是2007年他们一定能够成为SOA标准。</p><p>　　2006年7月，希望曾到来过，有消息表明SCA规范和SDO规范有望在去年圣诞节时正式成为SOA标准。开放SOA(OSOA)组织，一个由多家提供商包括IBM、 BEA Systems Inc、和Oracle Corp等公司自发成立的组织，目前正在致力于SCA和SDO规范晋升成为SOA标准的工作。去年夏天OSOA组织预测SCA和SDO规范将于2006年底正式成为SOA标准。现在看来，这似乎会是2007年的某一天。</p><p>　　在回复询问关于SCA和SDO规范更新情况的电子邮件中，IBM 的SOA合作伙伴、项目经理、规范编写人之一Graham J Barber这样答到：“我们希望在2007年第一季度将SCA规范的主要部分作为第一版推出。之后，我们希望将两个规范与已发布的V2.1 SDO规范放到一起，申请成为SOA标准。”</p><p>　　不论SCA规范是否已经完善或是否能成为SOA标准，SCA都是已被广大提供商应用于产品的SOA技术。甲骨文工具与中间件副总裁兼首席架构师Ted Farrell说，SCA规范是一种实用的技术。目前甲骨文的WebCenter Suite 就使用了SCA规范，使开发人员方便开发SOA和Web 2.0项目，他说。</p><p>　　Rogue Wave Software，Quovadx, Inc.的一家分公司，本月初宣布开始使用SDO规范，并将SDO加入产品名称，公司的SOA工具套装将被称为HydraSDO。</p><p>　　甲骨文的Farrell说，正式发布SOA标准是一件好事，他希望正式标准尽早出台，不过他真正关心的是在工具和应用程序开发中如何有效地使用SCA/SDO技术。</p><p>　　“我们对SCA何时成为标准十分感兴趣，现在我们叫它SCA伪标准，”他说。“我们不希望有所有权问题，因为采用开放结构会有许多好处。”</p><p>　　但是Farrell说，最重要的是，一个标准需要适用于应用程序，并有广泛的行业支持。</p><p>　　“SCA规范更趋于点对点模式，”他说。“IBM和BEA在推广一些标准的时候受到一些挫折，所以他们开始成立开放SOA组织。甲骨文以及其他一些提供商加入了该组织。尽管它不是以前的标准组织，但是它在不断发展，不断进步，其实我们最为企业软件提供商真的希望把这些规范变为一种软件标准，希望能够为SOA的发展献出一份力量。”</p><p>　　Farrell说SCA/SDO规范似乎在走业务处理执行语言(BPEL)的发展道路。业务处理执行语言(BPEL)最初由IBM和微软共同努力开发出第一个版本，之后BEA、 SAP AG和 Siebel Systems先后使用BPEL，现在甲骨文也开始使用BPEL。2003年，这些提供商正式将BPEL提交给开放标准组织OASIS标准化，2003年4月6日，OASIS组织用WS-BPEL的名字吸纳了BPEL标准。2003年5月3日，SAP/SIEBEL加入并共同推出WS-BPEL1.1版。2003年5月16日， WS-BPEL2.0的草案也在当时被纳入议事日程。</p><p>　　SOA项目的开发人员和架构师应该从现在开始就接触这些规范，不应该等着它们成熟成为正式标准，Harte-Hanks (HHS) 公司Aberdeen Group 企业集成副总裁Peter S. Kastner说。他认为SOA的工作人员都应该熟悉这些规范，并促进它们的发展。</p><p>　　“在未来几年，将迅速推出一批与SOA相关的标准，所以对用户来说，最好简要地使用这些标准，从某种意义上说，这是可能的，”他说。“基本上，变化是不可避免的，所以勇于面对变化，适应变化。如果要等到所有标准都完善，之后出台，我像那你会疯掉，这大概需要十年的时间。”</p><img src ="http://www.blogjava.net/mlh123caoer/aggbug/93334.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2007-01-12 09:39 <a href="http://www.blogjava.net/mlh123caoer/archive/2007/01/12/93334.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>COGNOS业务智能产品</title><link>http://www.blogjava.net/mlh123caoer/archive/2007/01/03/91613.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Wed, 03 Jan 2007 11:41:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2007/01/03/91613.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/91613.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2007/01/03/91613.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/91613.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/91613.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一、       																				Cognos														业务智能服务的主要产品																																																														 												使用				Cognos			...&nbsp;&nbsp;<a href='http://www.blogjava.net/mlh123caoer/archive/2007/01/03/91613.html'>阅读全文</a><img src ="http://www.blogjava.net/mlh123caoer/aggbug/91613.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2007-01-03 19:41 <a href="http://www.blogjava.net/mlh123caoer/archive/2007/01/03/91613.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>GCC 中文手册</title><link>http://www.blogjava.net/mlh123caoer/archive/2006/11/20/82241.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Mon, 20 Nov 2006 06:00:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2006/11/20/82241.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/82241.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2006/11/20/82241.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/82241.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/82241.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: GCC								Section: GNU Tools (1)Updated: 2003/12/05IndexReturn to Main Contents				 		 						NAME								gcc,g++-GNU				工程的				C				和				C++				编译器				(egcs-1.1.2)  ...&nbsp;&nbsp;<a href='http://www.blogjava.net/mlh123caoer/archive/2006/11/20/82241.html'>阅读全文</a><img src ="http://www.blogjava.net/mlh123caoer/aggbug/82241.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2006-11-20 14:00 <a href="http://www.blogjava.net/mlh123caoer/archive/2006/11/20/82241.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>j2ee web service开发(三) SAAJ 带附件的soap消息 </title><link>http://www.blogjava.net/mlh123caoer/archive/2006/11/09/80101.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Thu, 09 Nov 2006 04:25:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2006/11/09/80101.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/80101.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2006/11/09/80101.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/80101.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/80101.html</trackback:ping><description><![CDATA[带附件的soap消息api,其内容很丰富,它是一个允许用soap消息而不是用jax-rpc来调用web service的API .它通过直接创建XML消息来完成web serivce的调用.SOAP API 简化了创建XML的工作. 取自j2ee文档的soap消息的结构图.<br /><img height="306" alt="saaj-noAttach.gif" src="http://www.blogjava.net/images/blogjava_net/fool/saaj-noAttach.gif" width="267" border="0" /> <br />完整的SAAJ客户端程序. 服务器端的程序在j2ee web service开发(一) 里可以找到.没有详细介绍saaj的一些类<br />的使用.好在它们都有很好的自解释性.<br />package array;
<p>import javax.xml.soap.*;<br />import java.net.*;<br />import java.io.*;<br />import java.util.*;<br />import java.text.SimpleDateFormat;<br />public class SaajClient {<br />    public SaajClient() {<br />    }</p><p>    public static void main(String[] args) throws Exception {<br />        SaajClient client = new SaajClient();<br />        User[] user = new User[2];<br />        user[0] = new User("张三", "027-88888888", new Date());<br />        user[1] = new User("lisi", null, new Date());<br />        saajTest(user);</p><p>    }</p><p>    private static void saajTest(User[] user) throws MalformedURLException,<br />            IOException,<br />            UnsupportedOperationException, SOAPException {<br />        MessageFactory factory = MessageFactory.newInstance();//SAAJ的根工厂类<br />        SOAPMessage message = factory.createMessage();<br /><font color="#0000ff">        //SOAPMessage 对象需要一些元素，包括SOAPPart,SOAPEnvelope,SOAPHeader,SOAPBody对象<br />        //SAAJ通过返回一个新的已经包括这些元素的SOAPMessage对象来简化操作</font><br />        SOAPFactory s = SOAPFactory.newInstance();//<font color="#0000ff">通用工厂类，创建Name，SOAPElement对象</font></p><p>        Name countUser = s.createName("countUser", "mh", "<a href="http://array/"><font color="#2e9ce9">http://array</font></a>");<br />        <font color="#0000ff">//Name对象表示一个XML限定名称</font><br />        Name arrayOfUser_1 = s.createName("arrayOfUser_1");<br />        Name xsi = s.createName("xmlns:xsi");<br />        Name nullAttribute = s.createName("xsi:nil");</p><p>        //<font color="#0000ff">下面的代码创建soap对象</font><br />        SOAPBody body = message.getSOAPBody();<br />        SOAPBodyElement bodyChildElement = body.addBodyElement(countUser);<br />        SOAPElement arrayOfUser = bodyChildElement.addChildElement(<br />                arrayOfUser_1);<br />      //  arrayOfUser.addAttribute(xsi, "<a href="http://www.w3.org/2001/XMLSchema-instance"><font color="#2e9ce9">http://www.w3.org/2001/XMLSchema-instance</font></a>");<br />        arrayOfUser.addNamespaceDeclaration("xsi","<a href="http://www.w3.org/2001/XMLSchema-instance"><font color="#2e9ce9">http://www.w3.org/2001/XMLSchema-instance</font></a>");<br />    <font color="#0000ff">    //定义arrayOfUser的 xmlns:xsi属性  该名称空间是XML模式实例命名空间，由XML模式规范定义，它定义了<br />        //可以在XML文档中使用的属于该命名空间的一些特性.</font><br />        for (int i = 0; i &lt; user.length; i++) {<br />            <font color="#0000ff">//需要注意顺序，也就是和复杂类型的sequence元素的顺序对应</font><br />            Name valueName = s.createName("value");<br />            SOAPElement value = arrayOfUser.addChildElement(valueName);<br />            Name birthday = s.createName("birthDay");<br />            SOAPElement birthdayElement = value.addChildElement(birthday);</p><p>            if (user[i].getBirthDay() == null) {<br />                birthdayElement.addAttribute(nullAttribute, "1");<br />            } else {<br />               <font color="#0000ff"> //日期类型必须进行格式化</font><br />                SimpleDateFormat format= new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");<br />                birthdayElement.addTextNode(format.format(user[i].getBirthDay()));<br />            }<br />            Name name = s.createName("name");<br />            SOAPElement nameElement = value.addChildElement(name);<br />            if (user[i].getName() == null) {<br />                <font color="#0000ff">//传送空值</font><br />                nameElement.addAttribute(nullAttribute, "1");<br />            } else {<br />                nameElement.addTextNode(user[i].getName());<br />            }<br />            Name phone = s.createName("phone");<br />            SOAPElement phoneElement = value.addChildElement(phone);<br />            if (user[i].getPhone() == null) {<br />                phoneElement.addAttribute(nullAttribute, "1");<br />            } else {<br />                phoneElement.addTextNode(user[i].getPhone());<br />            }</p><p>        }</p><p>        <font color="#0000ff">//发送soap消息</font><br />        SOAPConnectionFactory f = SOAPConnectionFactory.newInstance();<br />        SOAPConnection conn = f.createConnection();<br />        URL url = new URL("<a href="http://localhost:8082/complexType-array/services/CountUser"><font color="#2e9ce9">http://localhost:8082/complexType-array/services/CountUser</font></a>");<br />        SOAPMessage response = conn.call(message, url);</p><p>        SOAPBody soapBody = response.getSOAPBody();<br />        Iterator it = soapBody.getChildElements();<br />        while (it.hasNext()) {<br />            SOAPBodyElement bodyElement = (SOAPBodyElement) it.next();<br />            String returnValue = bodyElement.getValue();<br />            System.out.println(bodyElement.getElementName().getLocalName() +<br />                               "      " + returnValue);<br />        }</p><p><br />        response.writeTo(System.out);<br />    }<br />}<br /><br />程序向服务器端传送的数据:<br /><br />POST /complexType-array/services/CountUser HTTP/1.1<br />SOAPAction: ""<br />Content-Type: text/xml; charset=UTF-8<br />User-Agent: Java/1.5.0_03<br />Host: localhost:8082<br />Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2<br />Connection: keep-alive<br />Content-Length: 448</p><p>&lt;env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'&gt;<br />   &lt;env:Header/&gt;<br />   &lt;env:Body&gt;<br />      &lt;mh:countUser xmlns:mh='http://array'&gt;<br />         &lt;arrayOfUser_1 xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'&gt;<br />            &lt;value&gt;<br />               &lt;birthDay&gt;2006-11-08T22:36:13&lt;/birthDay&gt;<br />               &lt;name&gt;张三&lt;/name&gt;<br />               &lt;phone&gt;027-88888888&lt;/phone&gt;<br />            &lt;/value&gt;<br />            &lt;value&gt;<br />               &lt;birthDay&gt;2006-11-08T22:36:13&lt;/birthDay&gt;<br />               &lt;name&gt;lisi&lt;/name&gt;<br />               &lt;phone xsi:nil='1'/&gt;<br />            &lt;/value&gt;<br />         &lt;/arrayOfUser_1&gt;<br />      &lt;/mh:countUser&gt;<br />   &lt;/env:Body&gt;&lt;/env:Envelope&gt;<br />从传送的数据来看,就是一个符合soap规范的xml文档.既然是xml文档,也就是说可以用jdom api 来操作它<br />事实上就是这样,soap api 可以跟 jdom api混合使用.<br /><font face="宋体" size="2">如果你想赐教或者讨论,欢迎加入QQ群:30406099 </font><br /></p><img src ="http://www.blogjava.net/mlh123caoer/aggbug/80101.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2006-11-09 12:25 <a href="http://www.blogjava.net/mlh123caoer/archive/2006/11/09/80101.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>j2ee web service开发(二) 动态代理与动态调用 </title><link>http://www.blogjava.net/mlh123caoer/archive/2006/11/09/80100.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Thu, 09 Nov 2006 04:24:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2006/11/09/80100.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/80100.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2006/11/09/80100.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/80100.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/80100.html</trackback:ping><description><![CDATA[<font size="2">
				<font face="宋体">j2ee web service <span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">客户端的三种调用方式：</span></font>
		</font>
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">（一）占位程序<span lang="EN-US">:</span>该种调用方式需要服务端生成所谓的占位程序,也是性能最好的一种方式，据有的文档介绍说用占位程序实现的<span lang="EN-US">web</span>服务不能实现各种编程语言比如<span lang="EN-US">C#</span>之是互相调用就是会引起互操作性的问题.而且生成占位程序的<span lang="EN-US">web</span>服务的确稍麻烦一点，更重要的是我不喜欢这种方式，也就不作备忘了：）。<span lang="EN-US"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?><o:p></o:p></span></span>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">（二）动态代理：该种方式需要一个指向<span lang="EN-US">WSDL</span>文档的<span lang="EN-US">URL</span>。具体实现：<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>ServiceFactoryImpl factory = new ServiceFactoryImpl();<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">//</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">工厂类，取得<span lang="EN-US">service</span>对象，<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>URL wsdlURL = new File(<span style="mso-spacerun: yes">  </span>"complexType-array/WEB-INF/wsdl/CountUser.wsdl").<span style="mso-spacerun: yes">                </span><span style="mso-spacerun: yes">  </span>toURL(); //wsdl</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">文档的<span lang="EN-US">URL </span>它可以是一个远程的<span lang="EN-US">URL </span>但是本例引用本地硬盘上的一个<span lang="EN-US">wsdl</span>文件<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">其好处是提高程序的性能。<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>URL mappingURL = new File("complexType-array/WEB-INF/CountUser.xml").<span style="mso-spacerun: yes">                         </span>toURL(); //</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">映射文件的<span lang="EN-US">URL </span>需要着重说明的就是这个映射文件了，标准的<span lang="EN-US">j2ee web service API</span>实现中可不需要这玩意，但是在<span lang="EN-US">Jboss</span>的实现中不要这个就会报错cannot obtain java mapping type...，在<span lang="EN-US">jboss</span>下开发的<span lang="EN-US">web </span>服务客户端移植时需要特别注意，麻烦！<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>QName qname = new QName("http://array", "CountUserService");<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>Service service = factory.createService(wsdlURL, qname, mappingURL);//</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">通过工厂方法得到一个<span lang="EN-US">Service</span>对象，但<span lang="EN-US">createService(wsdlURL, qname, mappingURL)</span>方法是<span lang="EN-US">jboss</span>的具体实现增加一的一个方法，标准<span lang="EN-US">API</span>可没有这玩意，对于数组类型的传递只能用这个方法了，奇怪的是客户端居然需要部署在服务器端的映射文件，没劲！<span lang="EN-US"><span style="mso-spacerun: yes">        </span><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>CountUser port = (CountUser) service.getPort(CountUser.class); //</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">取得服务器端的接口。<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">(</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">三）动态调用。<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>URL wsdlURL = new File(<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">                </span>"complexType-array/WEB-INF/wsdl/CountUser.wsdl").<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">                      </span>toURL();<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>URL mappingURL = new File(<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">                </span>"complexType-array/WEB-INF/CountUser.xml").<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">                         </span>toURL();<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>QName qname = new QName("http://array", "CountUserService");//</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">表示服务名<span lang="EN-US">QName</span>对象。<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>Service service = factory.createService(wsdlURL, qname, mappingURL);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>Call call = service.createCall();<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>//</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">没什么好说的，依然要用到<span lang="EN-US">wsdl</span>文档文件，映射文件。<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>call.setOperationName(new QName(TARGET_NAMESPACE, "countUser"));//</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">指定方法名<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>call.setPortTypeName(new QName("CountUser"));//</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">指定端口名<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">("value",Constants.TYPE_LITERAL_ANYSIMPLETYPE,ParameterMode.IN);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>call.setReturnType(Constants.TYPE_LITERAL_INT);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>Object retObj = call.invoke(new Object[] {user});<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">服务器端的实现参见<span lang="EN-US"><a href="/fool/archive/2006/11/06/79319.html"><font color="#2e9ce9">j2ee web service(</font></a></span><a href="/fool/archive/2006/11/06/79319.html"><font color="#2e9ce9">一</font></a><span lang="EN-US"><a href="/fool/archive/2006/11/06/79319.html"><font color="#2e9ce9">)</font></a></span>完整的客户端代码如下：<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">package array;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">import java.net.URL;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">import javax.xml.rpc.*;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">import javax.xml.namespace.QName;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">import java.util.*;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">import java.io.File;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">import org.jboss.ws.jaxrpc.ServiceFactoryImpl;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">import org.jboss.ws.Constants;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">public class ArrayExample {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes"> </span>
						<span style="mso-spacerun: yes">   </span>public ArrayExample() {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>private static final String TARGET_NAMESPACE =<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">            </span>"http://array";<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>private CountUser getPort() throws Exception {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>ServiceFactoryImpl factory = new ServiceFactoryImpl();<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>URL wsdlURL = new File(<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">                </span>"complexType-array/WEB-INF/wsdl/CountUser.wsdl").<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">                      </span>toURL();<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>URL mappingURL = new File(<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">                </span>"complexType-array/WEB-INF/CountUser.xml").<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">                         </span>toURL();<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>QName qname = new QName("http://array", "CountUserService");<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>Service service = factory.createService(wsdlURL, qname, mappingURL);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>CountUser port = (CountUser) service.getPort(CountUser.class);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>return port;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>public void testComplexUserArray(User[] user) throws<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">            </span>Exception {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>CountUser port = getPort();<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>try {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">            </span>int returnValue = port.countUser(user);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">            </span>System.out.print(returnValue);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>} catch (Exception e) {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">            </span>throw e;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>public void DIIClient(User[] user) throws Exception {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>ServiceFactoryImpl factory = new ServiceFactoryImpl();<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>URL wsdlURL = new File(<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">                </span>"complexType-array/WEB-INF/wsdl/CountUser.wsdl").<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">                      </span>toURL();<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>URL mappingURL = new File(<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">                </span>"complexType-array/WEB-INF/CountUser.xml").<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">                         </span>toURL();<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>QName qname = new QName("http://array", "CountUserService");<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>Service service = factory.createService(wsdlURL, qname, mappingURL);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>Call call = service.createCall();<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>call.setOperationName(new QName(TARGET_NAMESPACE, "countUser"));<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>call.setPortTypeName(new QName("CountUser"));<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>call.setReturnType(Constants.TYPE_LITERAL_INT);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">      </span>
						<span style="mso-spacerun: yes">  </span>Object retObj = call.invoke(new Object[] {user});<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>System.out.println(retObj.toString());<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>public static void main(String[] args) throws Exception {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>ArrayExample arrayexample = new ArrayExample();<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>User[] user = new User[2];<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>user[0] = new User("</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">张三<span lang="EN-US">", "027-88888888", new Date());<o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>user[1] = new User("lisi", null, new Date());<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>//arrayexample.testComplexUserArray(user);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>arrayexample.DIIClient(user);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> 至此好象一个可以应用的web service服务就完成了,然而这才仅仅只是开始~~~~~~~~~<br />如果你想赐教或者讨论,欢迎加入QQ群:30406099 </o:p>
				</span>
		</p><img src ="http://www.blogjava.net/mlh123caoer/aggbug/80100.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2006-11-09 12:24 <a href="http://www.blogjava.net/mlh123caoer/archive/2006/11/09/80100.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>j2ee web service开发(一) 映射数组复杂类型 </title><link>http://www.blogjava.net/mlh123caoer/archive/2006/11/09/80099.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Thu, 09 Nov 2006 04:23:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2006/11/09/80099.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/80099.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2006/11/09/80099.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/80099.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/80099.html</trackback:ping><description><![CDATA[<font size="2">
				<font face="宋体">之所以把数组类型在调用<span lang="EN-US">web service</span>中作为参数的实现郑重的记录下来，实在是因为数组在<span lang="EN-US">j2ee web service</span>的实现不是一件容易的问题。至少用<span lang="EN-US">Jboss</span>的<span lang="EN-US">j2ee web service</span>实现时是这样<span lang="EN-US">.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?><o:p></o:p></span></font>
		</font>
		<font size="2">好象网上关于web service的比较深入一点的资料比较少,关于j2ee web service的资料就更少了.</font>
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">这里只记录了符合<span lang="EN-US">WS</span></span>
		<span lang="EN-US" style="FONT-SIZE: 10pt; mso-ascii-font-family: 宋体">—</span>
		<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">I BP</span>
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">标准的<span lang="EN-US">SOAP</span>四种消息传递模式中的<span lang="EN-US">RPC/Literal</span>消息传递模式。这个请参考书籍《<span lang="EN-US">j2ee web service </span>高级编程》一书。该书也只能是参考了，只是介绍了<span lang="EN-US">web service</span>的理论实现及一点<span lang="EN-US">jax-rpc </span>的<span lang="EN-US">API</span>，并且还有蛮多印刷错字。虽然<span lang="EN-US">jax-rpc API</span>的目标之一就是为了在各种<span lang="EN-US">java </span>的<span lang="EN-US">web service</span>实现技术中提供一个便携的手段，然而各种<span lang="EN-US">j2ee</span>服务器的<span lang="EN-US">web service</span>技术还是有些差别的，这个还是造成了程序不能直接在各种<span lang="EN-US">j2ee</span>服务器之间毫无修改的移植。在 <span lang="EN-US">apache</span>的<span lang="EN-US">axis</span>实现中，数组作为参数传递根本不值一提，借助工具很方面的就可以实现。<span lang="EN-US"><o:p></o:p></span></span>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">但是在<span lang="EN-US">jboss</span>中的<span lang="EN-US">ws</span>实现中确不是一件便利的事情。因为郁闷了很久，发点牢骚：）具体实现：<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>
				</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">作为<span lang="EN-US">web service</span>服务实现的类必须实现<span lang="EN-US">java.rmi.Remote</span>的接口<span lang="EN-US">:<o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">package array;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">import java.rmi.Remote;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">import java.rmi.RemoteException;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">public interface CountUser extends Remote {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes"> </span>
						<span style="mso-spacerun: yes">   </span>public int countUser(User[] user) throws RemoteException;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>
				</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">具体实现远程接口的类<span lang="EN-US">:<o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">package array;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">public class CountUserImpl implements CountUser {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>public int countUser(User[] user){<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>for(int i=0;i&lt;user.length;i++){<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">            </span>System.out.println("name "+user[i].getName()+"<span style="mso-spacerun: yes">  </span>phone<span style="mso-spacerun: yes">  </span>"+<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">                               </span>user[i].getPhone()+ " birthday "+user[i].getBirthDay());<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>return user.length;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">  </span>
				</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">作为数组参数传递的类<span lang="EN-US">:<o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">package array;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">import java.util.Date;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">public class User {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>private String name;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>private String phone;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>private Date birthDay;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>public User() {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>public User(String name,String phone,Date birthDay){<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>this.name=name;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>this.phone=phone;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>this.birthDay=birthDay;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>public void setName(String name) {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>this.name = name;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>public void setPhone(String phone) {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>this.phone = phone;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>public void setBirthDay(Date birthDay) {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>this.birthDay = birthDay;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>public String getName() {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">  </span>
						<span style="mso-spacerun: yes">      </span>return name;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>public String getPhone() {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>return phone;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>public Date getBirthDay() {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">        </span>return birthDay;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">使用<span lang="EN-US">Jboss_Home/bin </span>下的<span lang="EN-US">wstools</span>工具生成布署<span lang="EN-US">j2ee web service </span>必须的三个文件，<span lang="EN-US">jax-rpc</span>映射文件<span lang="EN-US">,web</span>服务描述器文件，以及<span lang="EN-US">wsdl</span>文档用于<span lang="EN-US">wstools</span>工具的配置文件<span lang="EN-US">jboss-config.xml</span>类容如下：<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">&lt;configuration xmlns="http://www.jboss.org/jbossws-tools"<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">   </span>xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">   </span>xsi:schemaLocation="http://www.jboss.org/jbossws-tools http://www.jboss.org/jbossws-tools/schema/jbossws-tool_1_0.xsd"<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">  </span>&lt;java-wsdl&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">  </span>&lt;service<span style="mso-spacerun: yes">  </span>name="ServiceBeanInterface1" style="rpc"<span style="mso-spacerun: yes">   </span>endpoint="array.ServiceBeanInterface1"/&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">      </span>&lt;namespaces target-namespace="http://array" type-namespace="http://array"/&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">     </span>&lt;mapping file="ServiceBeanInterface1.xml"/&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">     </span>&lt;webservices servlet-link="ServiceBeanInterface1"/&gt;<span style="mso-spacerun: yes">      </span><o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">  </span>
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">&lt;/java-wsdl&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">&lt;/configuration&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">使用<span lang="EN-US"> wstools -cp array.CountUser -config jboss-config.xml </span>命令可以生成布署<span lang="EN-US">web</span>服务所需的三个文件。另外还得在<span lang="EN-US">web.xml</span>文件中把<span lang="EN-US">CountUser</span>接口作为<span lang="EN-US">servlet</span>发布<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">  </span>&lt;servlet&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>&lt;display-name&gt;CountUser Servlet&lt;/display-name&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>&lt;servlet-name&gt;CountUser&lt;/servlet-name&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>&lt;servlet-class&gt;array.CountUserImpl&lt;/servlet-class&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">  </span>&lt;/servlet&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">  </span>&lt;servlet-mapping&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>&lt;servlet-name&gt;CountUser&lt;/servlet-name&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>&lt;url-pattern&gt;/CountUser&lt;/url-pattern&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">  </span>&lt;/servlet-mapping&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">  </span>&lt;servlet-mapping&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>&lt;servlet-name&gt;CountUser&lt;/servlet-name&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>&lt;url-pattern&gt;/services/*&lt;/url-pattern&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">  </span>&lt;/servlet-mapping&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">仅仅是这样倒也算很容易了，但是<span lang="EN-US">wstools</span>工具并不能在映射文件中正确实现<span lang="EN-US">User[]</span>的映射。因此还需要手工添加如下代码以实现<span lang="EN-US">User[] </span>到<span lang="EN-US">xml</span>之间的映射。<span lang="EN-US"><span style="mso-spacerun: yes">    </span><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>&lt;java-xml-type-mapping&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>&lt;java-type&gt;array.User[]&lt;/java-type&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>&lt;root-type-qname xmlns:typeNS='http://array'&gt;typeNS:User.Array&lt;/root-type-ame&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>&lt;qname-scope&gt;complexType&lt;/qname-scope&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<span style="mso-spacerun: yes">    </span>&lt;/java-xml-type-mapping&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">打包成<span lang="EN-US">war</span>文件，并且布署。服务端的实现就完成了。<a href="/Files/fool/complexType-array.rar"><font color="#2e9ce9">打包的war文件下载</font></a></span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'">
						<o:p> 使用的Jboss版本4.04 <br />因为篇幅或许还有分类的原因,客户端的实现将记录在下一篇随笔里 如果你想赐教或者讨论,欢迎加入QQ群:30406099</o:p>
				</span>
		</p><img src ="http://www.blogjava.net/mlh123caoer/aggbug/80099.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2006-11-09 12:23 <a href="http://www.blogjava.net/mlh123caoer/archive/2006/11/09/80099.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为Struts 2.0做好准备 </title><link>http://www.blogjava.net/mlh123caoer/archive/2006/11/08/79977.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Wed, 08 Nov 2006 15:04:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2006/11/08/79977.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/79977.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2006/11/08/79977.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/79977.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/79977.html</trackback:ping><description><![CDATA[<p>Struts作为MVC 2的Web框架，自推出以来不断受到开发者的追捧，得到用广泛的应用。作为最成功的Web框架，Struts自然拥有众多的优点：</p>
		<ul>
				<li>MVC 2模型的使用 
</li>
				<li>功能齐全的标志库（Tag Library） 
</li>
				<li>开放源代码 </li>
		</ul>
		<p>但是，所谓“金无赤金，人无完人”，Struts自身也有不少的缺点：</p>
		<ul>
				<li>需要编写的代码过多，容易引起“类爆炸” 
</li>
				<li>单元测试困难 </li>
		</ul>
		<p>这些缺点随着Web的发展越来越明显。这就促生了Struts 2.0，它的诞生能很好的解决上述问题。 好啦，废话就不多说了，现在就让我们感受一下的Struts 2.0的魅力吧。</p>
		<ol>
				<li>搭建开发和运行环境 
<ol><li>到Apache下载Struts 2.0包 
<p><img id="IMG1" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image001.png" /></p></li><li>打开Eclipse 3.2新建Web工程 
<p>点击菜单File\New\Project，出现如图1所示对话框<br /><img id="IMG2" alt="图1 新建工程对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image003.png" /><br />图1 新建工程对话框<br />选择Web\Dynamic Web Project，点击“Next”，出现图2对话框 </p><p><img id="IMG3" alt="图2 新建动态Web工程对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image005.png" /><br />图2 新建动态Web工程对话框<br />在“Project Name”中键入Struts2_HelloWorld，点击“New”，出现以下对话框 </p><p><img id="IMG4" alt="图3 新建服务器运行时对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image007.png" /><br />图3 新建服务器运行时对话框<br />选择“Apache\Apache Tomat v5.5”，点击“Next”，出现以下对话框 </p><p><img id="IMG5" alt="图4新建服务器运行时对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image009.png" /><br />图4新建服务器运行时对话框<br />点击“Finish”，关闭对话框。 </p></li><li>将Struts 2.0 lib下的jar文件加到工程的构建路径（build path） 
<p><img id="IMG6" alt="图5 Struts 2.0的lib目录" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image011.png" /><br />图5 Struts 2.0的lib目录<br />按ctr+a全选，复制，再转到Eclipse窗口，在“Project Explorer”子窗口中选中Struts2_HelloWorld\WebContent\WEB-INF\lib，然后粘贴。经过Eclipse自动刷新“Project Explorer”子窗口，刚才所粘贴的jar文件应该会出现在Struts2_HelloWorld\Java Resources: src\Libraries\Web App Libraries下，如图6所示： </p><p><img id="IMG7" alt="图6 Project Explorer子窗口" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image013.png" /><br />图6 Project Explorer子窗口<br /></p></li><li>打开web.xml文件，将其修改为以下代码： 
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">&lt;?</span><span style="COLOR: #ff00ff">xml version="1.0" encoding="ISO-8859-1"</span><span style="COLOR: #0000ff">?&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;!</span><span style="COLOR: #ff00ff">DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">web-app</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">display-name</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">Struts 2.0 Hello World</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">display-name</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">filter</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">filter-name</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">struts2</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">filter-name</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">filter-class</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">org.apache.struts2.dispatcher.FilterDispatcher</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">filter-class</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">filter</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">filter-mapping</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">filter-name</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">struts2</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">filter-name</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">url-pattern</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">/*</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">url-pattern</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">filter-mapping</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">welcome-file-list</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">welcome-file</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">index.html</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">welcome-file</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">welcome-file-list</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">web-app</span><span style="COLOR: #0000ff">&gt;</span></div><p></p></li><li>新建struts.xml文件 
<p>右键点击，Struts2_HelloWorld\Java Resources: src，出现如图7所示菜单<br /><img id="IMG8" alt="图7 新建Other菜单" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image015.png" /><br />图7 新建Other菜单<br />点击“Other”，出现新建对话框，如图8所示 </p><p><img id="IMG9" alt="图8 新建对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image017.png" /><br />图8 新建对话框<br />点击“Next”，出现新建文件对话框，如图9所示 </p><p><img id="IMG10" alt="图9 新建文件对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image019.png" /><br />图9 新建文件对话框<br />在“File name”中键入sturts.xml，点击“Finish”，然后将struts.xml的内容修改为：<br /></p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">&lt;!</span><span style="COLOR: #ff00ff">DOCTYPE struts PUBLIC<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        "http://struts.apache.org/dtds/struts-2.0.dtd"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">struts</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">include </span><span style="COLOR: #ff0000">file</span><span style="COLOR: #0000ff">="struts-default.xml"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">struts</span><span style="COLOR: #0000ff">&gt;</span></div><p></p></li><li>新建index.html文件 
<p>右键点击Struts2_HelloWorld\WebContent，出现如图10所示的菜单<br /><img id="IMG11" alt="图10 新建Other菜单" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image021.png" /><br />图10 新建Other菜单<br />点击“Other”，出现新建对话框，如图11所示 </p><p><img id="IMG12" alt="图11 新建对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image023.png" /><br />图11 新建对话框<br />选择Web\HTML，点击“Next”出现如图12所示的对话框 </p><p><img id="IMG13" alt="图12 新建HTML页面对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image025.png" /><br />图12 新建HTML页面对话框<br />在“File Name”中键入index.html，点击“Next”，出现如图13所示的对话框 </p><p><img id="IMG14" alt="图13 模板选择对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image027.png" /><br />图13 模板选择对话框<br />点击“Finish”，将index.html的内容修改为以下内容：<br /></p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">&lt;!</span><span style="COLOR: #ff00ff">DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">html</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">head</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">meta </span><span style="COLOR: #ff0000">http-equiv</span><span style="COLOR: #0000ff">="Content-Type"</span><span style="COLOR: #ff0000"> content</span><span style="COLOR: #0000ff">="text/html; charset=UTF-8"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">title</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">Hello World</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">title</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">head</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">body</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">h3</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">Hello World!</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">h3</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">body</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">html</span><span style="COLOR: #0000ff">&gt;</span></div><p></p></li><li>将应用程序打包到tomcat上 
<p>右键点击Struts_HelloWorld，出现如图14所示的菜单<br /><img id="IMG15" alt="图14 工程菜单" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image029.png" /><br />图14 工程菜单<br />点击“Export\WAR file”，出现如图15所示的对话框 </p><p><img id="IMG16" alt="图15 输出对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image031.png" /><br />图15 输出对话框<br />选择“Web\WAR file”，点击“Next”，出现如图16所示的对话框 </p><p><img id="IMG17" alt="图16 输出路径对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image033.png" /><br />图16 输出路径对话框<br />输入war文件的路径（如%tomcat%\webapps\Struts2_HelloWorld.war），点击“Finish”关闭对话框。 </p></li><li>启动tomcat，运行应用程序 
<p>打开你的Internet Explorer，键入http://localhost:8080/Struts2_HelloWorld/，窗口输出如图17所示<br /><img id="IMG18" alt="图17 Hello World窗口" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image035.png" /><br />图17 Hello World窗口<br /></p></li></ol></li>
				<li>第一个Struts 2.0应用程序——Hello World 
<ol><li>新建类包（package） 
<p>右键点击Struts2_HelloWorld\Java Resources: src，出现如图18所示菜单<br /><img id="IMG19" alt="图18 新建菜单" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image037.png" /><br />图18 新建菜单"<br />点击“New\Package”，出现如图19所示对话框<br /></p><p><img id="IMG20" alt="图19新建Java类包对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image039.png" /><br />图19新建Java类包对话框<br />在“Name”键入tutorial，点击“Finish”关闭对话框。 </p></li><li>新建HelloWorld.java文件 
<p>右键点击Struts2_HelloWorld\Java Resources: src\tutorial，出现如图20所示菜单<br /><img id="IMG21" alt="图20 新建菜单" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image041.png" /><br />图20 新建菜单<br />点击“New\Class”，出现如图21所示对话框 </p><p><img id="IMG22" alt="图21 新建Java类对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image043.png" /><br />图21 新建Java类对话框<br />在“Name”中键入HelloWorld，在“Superclass”中键入com.opensymphony.xwork2.ActionSupport，点击“Finish”关闭对话框。将HelloWorld.java的内容修改为：<br /></p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">package</span><span style="COLOR: #000000"> tutorial;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> com.opensymphony.xwork2.ActionSupport;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img id="Codehighlighter1_112_328_Open_Image" onclick="this.style.display='none'; Codehighlighter1_112_328_Open_Text.style.display='none'; Codehighlighter1_112_328_Closed_Image.style.display='inline'; Codehighlighter1_112_328_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_112_328_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_112_328_Closed_Text.style.display='none'; Codehighlighter1_112_328_Open_Image.style.display='inline'; Codehighlighter1_112_328_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> HelloWorld </span><span style="COLOR: #0000ff">extends</span><span style="COLOR: #000000"> ActionSupport </span><span id="Codehighlighter1_112_328_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_112_328_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> String name;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    <br /><img id="Codehighlighter1_163_181_Open_Image" onclick="this.style.display='none'; Codehighlighter1_163_181_Open_Text.style.display='none'; Codehighlighter1_163_181_Closed_Image.style.display='inline'; Codehighlighter1_163_181_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_163_181_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_163_181_Closed_Text.style.display='none'; Codehighlighter1_163_181_Open_Image.style.display='inline'; Codehighlighter1_163_181_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> String getName() </span><span id="Codehighlighter1_163_181_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_163_181_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> name;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    <br /><img id="Codehighlighter1_219_242_Open_Image" onclick="this.style.display='none'; Codehighlighter1_219_242_Open_Text.style.display='none'; Codehighlighter1_219_242_Closed_Image.style.display='inline'; Codehighlighter1_219_242_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_219_242_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_219_242_Closed_Text.style.display='none'; Codehighlighter1_219_242_Open_Image.style.display='inline'; Codehighlighter1_219_242_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> setName(String name) </span><span id="Codehighlighter1_219_242_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_219_242_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.name </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> name;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    <br /><img id="Codehighlighter1_271_326_Open_Image" onclick="this.style.display='none'; Codehighlighter1_271_326_Open_Text.style.display='none'; Codehighlighter1_271_326_Closed_Image.style.display='inline'; Codehighlighter1_271_326_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_271_326_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_271_326_Closed_Text.style.display='none'; Codehighlighter1_271_326_Open_Image.style.display='inline'; Codehighlighter1_271_326_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> String execute() </span><span id="Codehighlighter1_271_326_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_271_326_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        name </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello, </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> name </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">; <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> SUCCESS;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div><p></p></li><li>在struts.xml中添加action映射(mapping)<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">&lt;!</span><span style="COLOR: #ff00ff">DOCTYPE struts PUBLIC<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        "http://struts.apache.org/dtds/struts-2.0.dtd"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">struts</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">include </span><span style="COLOR: #ff0000">file</span><span style="COLOR: #0000ff">="struts-default.xml"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">package </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="tutorial"</span><span style="COLOR: #ff0000"> extends</span><span style="COLOR: #0000ff">="struts-default"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">action </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="HelloWorld"</span><span style="COLOR: #ff0000"> class</span><span style="COLOR: #0000ff">="tutorial.HelloWorld"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">result</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">HelloWorld.jsp</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">result</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">action</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">package</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">struts</span><span style="COLOR: #0000ff">&gt;</span></div><p></p></li><li>新建SayHello.jsp 
<p>参考“新建index.html文件”步骤，弹出如图22所示对话框<br /><img id="IMG23" alt="图22 新建对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image045.png" /><br />图22 新建对话框<br />点击“Next”, 进入下一步，如图23所示 </p><p><img id="IMG24" alt="图23 新建JSP对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image047.png" /><br />图23 新建JSP对话框<br />在“File name”键入SayHello.jsp，点击“Next”进入下一步，如图24所示 </p><p><img id="IMG25" alt="图24 模板选择对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image049.png" /><br />图24 模板选择对话框<br />点击“Finish”关闭对话框，并将SayHello.jsp的内容修改为：<br /></p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_2_47_Open_Image" onclick="this.style.display='none'; Codehighlighter1_2_47_Open_Text.style.display='none'; Codehighlighter1_2_47_Closed_Image.style.display='inline'; Codehighlighter1_2_47_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_2_47_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_2_47_Closed_Text.style.display='none'; Codehighlighter1_2_47_Open_Image.style.display='inline'; Codehighlighter1_2_47_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #000000; BACKGROUND-COLOR: #ffff00">&lt;%</span><span id="Codehighlighter1_2_47_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_2_47_Open_Text"><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">@ page contentType</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">text/html; charset=UTF-8</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span></span><span style="COLOR: #000000; BACKGROUND-COLOR: #ffff00">%&gt;</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_53_91_Open_Image" onclick="this.style.display='none'; Codehighlighter1_53_91_Open_Text.style.display='none'; Codehighlighter1_53_91_Closed_Image.style.display='inline'; Codehighlighter1_53_91_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_53_91_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_53_91_Closed_Text.style.display='none'; Codehighlighter1_53_91_Open_Image.style.display='inline'; Codehighlighter1_53_91_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #000000; BACKGROUND-COLOR: #ffff00">&lt;%</span><span id="Codehighlighter1_53_91_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_53_91_Open_Text"><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">@ taglib prefix</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">s</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> uri</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">/struts-tags</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span></span><span style="COLOR: #000000; BACKGROUND-COLOR: #ffff00">%&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;!</span><span style="COLOR: #ff00ff">DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">html</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">head</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">title</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">Say Hello</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">title</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">head</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">body</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">h3</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">Say "Hello" to: </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">h3</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">s:form </span><span style="COLOR: #ff0000">action</span><span style="COLOR: #0000ff">="HelloWorld"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            Name: </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">s:textfield </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="name"</span><span style="COLOR: #ff0000"> </span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">s:submit </span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">s:form</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">body</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">html</span><span style="COLOR: #0000ff">&gt;</span></div><p></p></li><li>新建HelloWorld.jsp(请参考上一步)，HelloWorld.jsp的内容为：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_2_47_Open_Image" onclick="this.style.display='none'; Codehighlighter1_2_47_Open_Text.style.display='none'; Codehighlighter1_2_47_Closed_Image.style.display='inline'; Codehighlighter1_2_47_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_2_47_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_2_47_Closed_Text.style.display='none'; Codehighlighter1_2_47_Open_Image.style.display='inline'; Codehighlighter1_2_47_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #000000; BACKGROUND-COLOR: #ffff00">&lt;%</span><span id="Codehighlighter1_2_47_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_2_47_Open_Text"><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">@ page contentType</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">text/html; charset=UTF-8</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span></span><span style="COLOR: #000000; BACKGROUND-COLOR: #ffff00">%&gt;</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_53_91_Open_Image" onclick="this.style.display='none'; Codehighlighter1_53_91_Open_Text.style.display='none'; Codehighlighter1_53_91_Closed_Image.style.display='inline'; Codehighlighter1_53_91_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_53_91_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_53_91_Closed_Text.style.display='none'; Codehighlighter1_53_91_Open_Image.style.display='inline'; Codehighlighter1_53_91_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #000000; BACKGROUND-COLOR: #ffff00">&lt;%</span><span id="Codehighlighter1_53_91_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_53_91_Open_Text"><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">@ taglib prefix</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">s</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> uri</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">/struts-tags</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span></span><span style="COLOR: #000000; BACKGROUND-COLOR: #ffff00">%&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;!</span><span style="COLOR: #ff00ff">DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">html</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">head</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">title</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">Hello</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">title</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">head</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">body</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">h3</span><span style="COLOR: #0000ff">&gt;&lt;</span><span style="COLOR: #800000">s:property </span><span style="COLOR: #ff0000">value</span><span style="COLOR: #0000ff">="name"</span><span style="COLOR: #ff0000"> </span><span style="COLOR: #0000ff">/&gt;&lt;/</span><span style="COLOR: #800000">h3</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">body</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">html</span><span style="COLOR: #0000ff">&gt;</span></div><p></p></li><li>重新打包发布应用程序 
<p>先停止tomcat, 再将tomcat里webapps下的Struts2_HelloWorld.war和Struts2_HelloWorld文件夹删除，参照“将应用程序打包到tomcat上”重新发布应用程序。 </p></li><li>启动tomcat，运行测试 
<p>打开Internet Explorer，键入http://localhost:8080/Struts2_HelloWorld/SayHello.jsp，窗口输出如图25所示<br /><img id="IMG26" alt="图25 SayHello.jsp" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image051.png" /><br />图25 SayHello.jsp<br />在“Name”键入字符串（如World），点击Submit，转到HelloWorld.jsp页面，如图26所示 </p><p><img id="IMG27" alt="图26 HelloWorld.jsp" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image053.png" /><br />图26 HelloWorld.jsp<br /></p></li></ol></li>
				<li>单元测试Hello World 
<p>在文章开始的时候提及，单元测试困难是Struts一大缺点。现在让我们在体验一下，在Struts 2.0中是如何进行测试的。</p><ol><li>新建JUnit单元测试 
<p>右键点击Struts2_HelloWorld\Java Resources: src\tutorial，弹出如图27所示对话框<br /><img id="IMG28" alt="图27 新建菜单" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image055.png" /><br />图27 新建菜单<br />点击“Next\Other” </p><p><img id="IMG29" alt="图28 新建对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image057.png" /><br />图28 新建对话框<br />选择“Java\JUnit\JUnit Test Case”，点击“Next” </p><p><img id="IMG30" alt="图29 新建JUnit 测试用例对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image059.png" /><br />图29 新建JUnit 测试用例对话框<br />选择“New JUnit 4 test”，在“Name”中键入HelloWorldTest，在“Class under test”键入tutorial.HelloWorld，点击“Next” </p><p><img id="IMG31" alt="图30 选择方法对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image061.png" /><br />图30 选择方法对话框<br />选中HelloWorld\execute方法，点击Finish。如果生成的HelloWorldTest.java文件的图标（Icon）出现红色交叉标志，请进行以下步骤添加JUnit 4的jar包。 </p><p>右键点击Struts2_HelloWorld，出现如图所示菜单。 <img id="IMG32" alt="图31 新建菜单" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image063.png" /><br />图31 新建菜单<br />点击“Build Path\Add Libararis”，弹出图32对话框 </p><p><img id="IMG33" alt="图32 添加库对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image065.png" /><br />图32 添加库对话框<br />选中“JUnit”，点击“Next” </p><p><img id="IMG34" alt="图33 选择版本对话框" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image067.png" /><br />图33 选择版本对话框<br />选择“JUnit 4”，点击“Finish”关闭对话框，并将HelloWorldTest.java的内容修改为：<br /></p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">package</span><span style="COLOR: #000000"> tutorial;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> org.junit.Assert.assertTrue;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> org.junit.Test;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> com.opensymphony.xwork2.ActionSupport;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img id="Codehighlighter1_162_507_Open_Image" onclick="this.style.display='none'; Codehighlighter1_162_507_Open_Text.style.display='none'; Codehighlighter1_162_507_Closed_Image.style.display='inline'; Codehighlighter1_162_507_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_162_507_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_162_507_Closed_Text.style.display='none'; Codehighlighter1_162_507_Open_Image.style.display='inline'; Codehighlighter1_162_507_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> HelloWorldTest </span><span id="Codehighlighter1_162_507_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_162_507_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    @Test<br /><img id="Codehighlighter1_199_504_Open_Image" onclick="this.style.display='none'; Codehighlighter1_199_504_Open_Text.style.display='none'; Codehighlighter1_199_504_Closed_Image.style.display='inline'; Codehighlighter1_199_504_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_199_504_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_199_504_Closed_Text.style.display='none'; Codehighlighter1_199_504_Open_Image.style.display='inline'; Codehighlighter1_199_504_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> testExecute() </span><span id="Codehighlighter1_199_504_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_199_504_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        HelloWorld hello </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> HelloWorld();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        hello.setName(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">World</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        String result </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> hello.execute();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        assertTrue(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Expected a success result!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, ActionSupport.SUCCESS.equals(result));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">final</span><span style="COLOR: #000000"> String msg </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello, World!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        assertTrue(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Expected the default message!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, msg.equals(hello.getName()));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div><p></p></li><li>运行单元测试 
<p>右键点击Struts2_HelloWorld\Java Resources: src\tutorial\HelloWorldTest.java，弹出如图34所示菜单<br /><img id="IMG35" alt="图34 运行为菜单" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image069.png" /><br />图34 运行为菜单<br />点击“Run As\JUnit Test”，出现JUnit子窗口如图35所示 </p><p><img id="IMG36" alt="图35 JUnit子窗口" src="http://www.blogjava.net/images/blogjava_net/max/16101/o_image071.png" /><br />图35 JUnit子窗口<br />图35的绿色矩形表示，所有单元测试通过。 </p></li></ol></li>
				<li>总结 
<p>上面的例子简单地演示了，Web 应用程序的基本操作，也即是，页面输入-&gt;Action处理-&gt;再输出到另外页面。Struts 2.0的简单易用、方便测试相信也会给大家留下不错的印象吧。我相信，Struts 2.0作为一个全新的Web架构，将会再次掀起Web开发的热潮。 不过，Struts 2.0还在测试中，正式版的发布还需些时日，所以文档方面可能有所欠缺。请大家继续留意<a href="/max"><font color="#1a8bc8">我的博客</font></a>，我会尽我所能为大家写更多关于Struts 2.0的文章。 </p></li>
		</ol>
		<div class="postDesc">posted on 2006-10-10 18:35 <a href="/max/"><font color="#1a8bc8">Max</font></a> 阅读(2765) <a href="/max/archive/2006/10/10/74353.html#Post"><font color="#1a8bc8">评论(36)</font></a>  <a href="/max/admin/EditPosts.aspx?postid=74353"><font color="#1a8bc8">编辑</font></a> <a href="/max/AddToFavorite.aspx?id=74353"><font color="#1a8bc8">收藏</font></a><a href="/max/services/trackbacks/74353.aspx"><font color="#1a8bc8">引用</font></a><a href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();"><font color="#1a8bc8">收藏至365Key</font></a> 所属分类: <a href="/max/category/16130.html"><font color="#1a8bc8">Struts 2.0系列</font></a></div><img src ="http://www.blogjava.net/mlh123caoer/aggbug/79977.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2006-11-08 23:04 <a href="http://www.blogjava.net/mlh123caoer/archive/2006/11/08/79977.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>常用的Struts 2.0的标志（Tag）介绍 </title><link>http://www.blogjava.net/mlh123caoer/archive/2006/11/08/79974.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Wed, 08 Nov 2006 15:01:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2006/11/08/79974.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/79974.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2006/11/08/79974.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/79974.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/79974.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在上一篇文章《为Struts 2.0做好准备》中，我过于详细地介绍了Struts 2.0开发环境和运行环境的配置，所以，本文很少涉及的以上两方面的细节。如果，您看完《为Struts 2.0做好准备》后，还有什么不明白，或者没法运行文中例子，请联系我。我的E-MAIL：Max.M.Yuan@gmail.com。		在介绍常用标志前，我想先从总体上，对Struts 1.x与Struts 2.0的标...&nbsp;&nbsp;<a href='http://www.blogjava.net/mlh123caoer/archive/2006/11/08/79974.html'>阅读全文</a><img src ="http://www.blogjava.net/mlh123caoer/aggbug/79974.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2006-11-08 23:01 <a href="http://www.blogjava.net/mlh123caoer/archive/2006/11/08/79974.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts 2.0的Action讲解 </title><link>http://www.blogjava.net/mlh123caoer/archive/2006/11/08/79973.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Wed, 08 Nov 2006 15:00:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2006/11/08/79973.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/79973.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2006/11/08/79973.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/79973.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/79973.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 有Struts 1.x经验的朋友都知道Action是Struts的核心内容，当然Struts 2.0也不例外。不过，Struts 1.x与Struts 2.0的Action模型很大的区别。																														 										Struts 1.x										Stuts 2.0																...&nbsp;&nbsp;<a href='http://www.blogjava.net/mlh123caoer/archive/2006/11/08/79973.html'>阅读全文</a><img src ="http://www.blogjava.net/mlh123caoer/aggbug/79973.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2006-11-08 23:00 <a href="http://www.blogjava.net/mlh123caoer/archive/2006/11/08/79973.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XFire：轻松简单地开发Web Services</title><link>http://www.blogjava.net/mlh123caoer/archive/2006/10/15/75257.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Sun, 15 Oct 2006 04:55:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2006/10/15/75257.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/75257.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2006/10/15/75257.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/75257.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/75257.html</trackback:ping><description><![CDATA[问一下.Net的开发者，开发Web Services有多困难?他们会被你的问题逗乐，他们会告诉你所有步骤花费的时间不会超过一分钟。再问一下Java开发者，运气好的话你会碰到上面的回答，一般情况下，你会得到一个完全不同的答案。从Web Services引入到Java中至今已经5年了，然而它仍然被认为是一门较新的技术，一个主要的原因就是使用Java实现Web Services太困难了。现在，随着新一代Web Services引擎XFire的发布，这种情况将会发生明显的变化。使用XFire，你可以把Java类方法发布为Web Services而不需要编写额外的代码。在这篇文章中，你将会看到XFire使Web Services开发变得多么容易和简单。 
<p>　　Web Services使我们能够在网络上建立分布式系统，应用程序组件可以通过任何平台、任何语言和任何方式访问。无论应用程序如何开发，使用了什么语言，以及运行在什么操作系统平台上，只要它作为Web Service，并且为协同解决问题而设计，那么你的应用程序，以任何语言开发或在任何平台上，都可以利用它的服务。这是Web Service的主要概念。</p><p>　　为了实现Web Services的平台无关性和实现访问独立性，软件行业需要遵循一些作为标准的技术。其中一些包括:</p><p>　　---XML:在Web Services环境中各层之间进行传递的默认数据格式。</p><p>　　---SOAP:封装和交换信息的默认协议。第一次被提出时，它是只取Simple Object Access Protocol(简单对象访问协议)的首字母。但是现在SOAP更多被认为是一个特定的名词，以它自己而命名，同样很多人认为这是用词不当:SOAP实际上不是用来访问对象的。另外，它也不再简单。</p><p>　　---WSDL(Web Services Description Language，Web Services描述语言):描述Web Services的语言。尽管基于XML并且可以被人理解，WSDL主要是由机器处理，由客户端程序读取和理解。</p><p>　　下面的高级层次图表，基于WWW协会发布的“Web Services Architecture”(Web Services架构)文档，显示了这些技术在实际的工作环境中是如何发挥作用:</p><p><a href="http://searchwebservices.techtarget.com.cn/TLimages/picview/?/imagelist/06/39/6fu472rkvoe2.jpg" target="_blank"><img style="BORDER-LEFT-COLOR: #000000; BORDER-BOTTOM-COLOR: #000000; BORDER-TOP-COLOR: #000000; BORDER-RIGHT-COLOR: #000000" alt="点击放大此图片" src="http://searchwebservices.techtarget.com.cn/imagelist/06/39/6fu472rkvoe2s.jpg" border="0" /></a></p><p>　　这个流程图显示了Web Services中的核心技术是如何工作的。</p><p>　　这里，Provider是提供服务的应用程序组件，Requester是使用服务的客户端程序。很多其他技术也会参与到交互中，但是这个图只显示了在Web Services环境中必需的核心技术组件。</p><p>　　XFire是一个免费的开源SOAP框架，它不仅可以极大方便地实现这样一个环境，并且可以提供许多Web Services规范中高级特征，这些特征在多数的商业或者开源工具都没有提供。你要恰当的理解这些单词:great ease and simplicity(非常轻松和简单)。你将会看到使用XFire创建Web Services是多么的简单。</p><p>　　假如你的Web应用有一个Java类，并且你想把它的一个方法发布为Web Services，当使用XFire时，你不需要编写一行额外的Java代码。只需要编辑发布描述符，然后你就会得到一个Web Services。是的，它相当地简单。我们来看一个例子。<strong>一个简单的Java类</strong></p><p>　　我们的例子是一个银行业应用程序，服务器是运行在J2SE1.4.2_07下的Apache Tomcat5.5.7。假定你已经了解如何使用Java编写Web应用程序，并知道应该如何把它部署到Apache Tomcat服务器上。我们的Web应用程序非常简单;它只做一件事——将资金从一个账户转到另外一个账户上。一个普通的Java类BankingService包含了一个叫做transferFunds()的方法来为我们完成这项工作。它需要四个输入参数:</p><ul><li>　　1、 String fromAccount 
</li><li>　　2、 String toAccount 
</li><li>　　3、 double amount 
</li><li>　　4、 String currency</li></ul><p>　　代码如下:</p><p></p><table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0"><tbody><tr><td style="WORD-WRAP: break-word" bgcolor="#f3f3f3"><p><font face="Verdana">package com.mybank.xfire.example;</font></p><p><font face="Verdana">import java.text.NumberFormat;<br />import java.text.DecimalFormat;</font></p><p><font face="Verdana">/** XFire WebServices sample implementation class. <br />*/<br />public class BankingService implements IBankingService {<br />    <br />    //Default constructor.<br />    public BankingService(){    <br />    }<br />    <br />    /** Transfers fund from one account to another.<br />    */<br />    public String transferFunds(<br />        String fromAccount, String toAccount, double amount, String currency){<br />        <br />        String statusMessage = "";<br />                      <br />        //Call business objects and other components to get the job done.<br />        //Then create a status message and return.<br />        try {<br />            NumberFormat formatter = new DecimalFormat("###,###,###,###.00");       <br />            statusMessage = "COMPLETED: " + currency + " " + formatter.format(amount)+ <br />            " was successfully transferred from A/C# " + fromAccount + " to A/C# " + toAccount;<br />        } catch (Exception e){<br />            statusMessage = "BankingService.transferFunds(): EXCEPTION: " + e.toString();<br />        }<br />        return statusMessage;<br />    }<br />    <br />}</font></p></td></tr></tbody></table><p>　　在这里你看到了什么异常的东西了吗?或许没有，除了默认的构造函数，类型是public。这是必须的。否则，XFire不能够初始化这个类。因为使用接口的设计是一个好的实践，所以我们的Java类也实现了一个称为IBankingService的接口。代码十分简单:</p><p></p><table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0"><tbody><tr><td style="WORD-WRAP: break-word" bgcolor="#f3f3f3"><p><font face="Verdana">package com.mybank.xfire.example;</font></p><p><font face="Verdana">public interface IBankingService {  </font></p><p><font face="Verdana">    public String transferFunds(<br />        String fromAccount, String toAccount, double amount, String currency);<br />        <br />}</font></p></td></tr></tbody></table><p>　　在实际实现中，这样一个方法可能包括各种类型的复杂调用、查询和处理操作。但是我们的示例代码已经最小化了，以至于我们可以集中精力在主要目标上:把这个方法发布为Web Services。</p><p>　　你可以看到BankingService是一个普通的Java类，没有任何代码告诉我们它将会在Web Services中使用。好的，这里我们不需要增加任何东西。我们所有的工作都在部署描述符里完成。</p><p>　　<strong>Web应用的部署描述符</strong></p><p>　　在Java中，Web应用程序通常需要至少一个部署描述符(叫做web.xml)对其进行配置。XFire本身是一个基于servlet的应用程序。因此，我们需要增加必要的引用到描述符文件中。然后我们还必须配置将要创建的Web Services。我们使用一个称为services.xml的新文件来完成这件事。</p><p>　　<strong>web.xml</strong></p><p>　　首先，修改web.xml。我们需要增加下面的XFire servlet相关的条目:</p><p></p><table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0"><tbody><tr><td style="WORD-WRAP: break-word" bgcolor="#f3f3f3"><p><font face="Verdana">&lt;servlet&gt;<br />        &lt;servlet-name&gt;XFireServlet&lt;/servlet-name&gt;<br />        &lt;display-name&gt;XFire Servlet&lt;/display-name&gt;<br />        &lt;servlet-class&gt;org.codehaus.xfire.transport.http.XfireConfigurableServlet<br />         &lt;/servlet-class&gt;<br />    &lt;/servlet&gt;</font></p><p><font face="Verdana">    &lt;servlet-mapping&gt;<br />        &lt;servlet-name&gt;XFireServlet&lt;/servlet-name&gt;<br />        &lt;url-pattern&gt;/servlet/XFireServlet/*&lt;/url-pattern&gt;<br />    &lt;/servlet-mapping&gt;<br />    <br />    &lt;servlet-mapping&gt;<br />        &lt;servlet-name&gt;XFireServlet&lt;/servlet-name&gt;<br />        &lt;url-pattern&gt;/services/*&lt;/url-pattern&gt;<br />    &lt;/servlet-mapping&gt;</font></p></td></tr></tbody></table><strong><font face="Verdana">services.xml</font></strong><p>　　现在我们不得不说一下我们的Web Services的由什么组成的了。这由一个叫做services.xml的文件完成，它存放在META-INF/xfire目录下，而这整个目录放在WEB-INF/classes文件夹中，它在Web应用程序的标准类路径中。这里是services.xml中的基本配置条目:</p><p></p><table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0"><tbody><tr><td style="WORD-WRAP: break-word" bgcolor="#f3f3f3"><font face="Verdana">&lt;beans xmlns="http://xfire.codehaus.org/config/1.0"&gt;<br />  <br />  &lt;service&gt;<br />    &lt;name&gt;Banking&lt;/name&gt;<br />    &lt;namespace&gt;mybank&lt;/namespace&gt;<br />    &lt;serviceClass&gt;com.mybank.xfire.example.IBankingService&lt;/serviceClass&gt;<br />    &lt;implementationClass&gt;com.mybank.xfire.example.BankingService&lt;/implementationClass&gt;<br />  &lt;/service&gt;  <br />  <br />&lt;/beans&gt;</font></td></tr></tbody></table><p> 　　让我们看看这里都包含了什么内容。Web Services的定义包含在<service>元素中，它还含有一些子元素。第一个子元素是<name>，它可以是你提供任何的合法名字。这将会被客户端程序和其它需要定位你的服务的组件用到。例如，在服务准备好以后，你将在浏览器上使用这个名字来查看WSDL。</name></service></p><p>　　<font face="Verdana">下一个子元素是&lt;namespace&gt;。任何合法的XML名字都是可以的。&lt;namespace&gt;用来唯一标识你的服务的各个参数。<br />&lt;serviceClass&gt;元素包含了Java类的名字，它指定了方法签名。在我们的例子中，它是接口IBankingService。如果Java类没有实现任何接口，你就需要把类的名字放在这里。在你的Java类或者接口中可能有几个方法。只需要一个入口把它们全部发布为Web Services。</font></p><p><font face="Verdana">　　&lt;implementationClass&gt;保存了实现方法的Java类名。这是一个可选元素。如果上一个元素&lt;serviceClass&gt;包含了一个接口，那么相应的实现类必须在这里指定。</font></p><p><font face="Verdana">　　就是这样。我们的Web Services配置完成了</font>。</p><p>　　<strong>XFire和其它类库</strong></p><p>　　现在是最后一步了，需要得到所有必需的类库。我们怎样得到它们呢?去XFire网站，下载xfire-distribution-1.0.zip，然后解压到一个本地文件夹。复制下面的jar文件和它的库文件夹到WEB-INF/lib中:</p><ul><li>　　• activation-1.0.2.jar 
</li><li>　　• commons-codec-1.3.jar 
</li><li>　　• commons-httpclient-3.0.jar 
</li><li>　　• commons-logging-1.0.4.jar 
</li><li>　　• jaxen-1.1-beta-8.jar 
</li><li>　　• jdom-1.0.jar 
</li><li>　　• log4j-1.2.x.jar 
</li><li>　　• mail-1.3.3_01.jar 
</li><li>　　• spring-1.2.x.jar 
</li><li>　　• stax-api-1.0.jar 
</li><li>　　• wsdl4j-1.5.2.jar 
</li><li>　　• wstx-asl-2.9.jar 
</li><li>　　• xbean-2.1.0.jar 
</li><li>　　• xbean-spring-2.2.jar 
</li><li>　　• xfire-all-1.0.jar 
</li><li>　　• XmlSchema-1.0.jar</li></ul><p>　　一切妥当。我们来部署和启动应用程序。为了部署示例应用，只需要复制websvc.war到Apache Tomcat的webapps文件夹中，再等待几秒钟。它将会自动启动。这个应用的全部源代码也包含在这个war文件中。我们的程序已经准备作为一个Web Service了。<strong>我们如何知道Web Service正在工作呢?</strong></p><p>　　为了了解Web Service是否正在工作，我们需要测试。首先，我们测试来看WSDL是否可用。我们在浏览器中输入URL。哪个URL?因为我们的应用程序的war文件是websvc.war，并且在services.xml中给出的服务名是Banking，WSDL的URL应该是:http://localhost:8080/websvc/services/Banking?wsdl。</p><p>　　请注意:URL的第一部分，例如，http://localhost:8080，可能会根据你的应用服务器不同而不同。无论怎样，当你输入URL后，将会看到一个XML文档，它的根元素是<?xml:namespace prefix = wsdl /?><wsdl:definitions>。这个文档叫做服务的WSDL。如果你看到了，这就是你的应用作为Web Service已经可用的第一个证明。</wsdl:definitions></p><p>　　但是这个测试是不够的。可能会发生这种情况，可以看到WSDL，但是从客户端程序可能会访问不到服务。因此为了核实服务是否可以访问了，我们必须使用一个客户端进行服务的实际调用来进行一个真正的测试。</p><p>　　<strong>开发一个客户端</strong></p><p>　　你可以使用任何的SOAP工具创建客户端，例如，.Net或者Apache Axis，有很多种方法:使用从WSDL产生的stubs，使用动态代理，等等。在例子中，我们使用一个动态代理，以一个简单的Servlet形式，叫做WsClient.java。为了保持代码两最小，所有在屏幕显示的元素都放在了doGet()方法中。对Web Service的实际调用由callWebService()方法完成，它相当地简单。和下面的类似:</p><p></p><table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0"><tbody><tr><td style="WORD-WRAP: break-word" bgcolor="#f3f3f3"><p><font face="Verdana">/* Call the Web service<br />    *<br />    */<br />    public String callWebService(<br />        String fromAccount, String toAccount, double amount, String currency) <br />        throws MalformedURLException, Exception {<br />        <br />        //Create a metadata of the service      <br />        Service serviceModel = new ObjectServiceFactory().create(IBankingService.class);        <br />        log.debug("callSoapServiceLocal(): got service model." );<br />   <br />        //Create a proxy for the deployed service<br />        XFire xfire = XFireFactory.newInstance().getXFire();<br />        XFireProxyFactory factory = new XFireProxyFactory(xfire);      <br />    <br />        String serviceUrl = "http://localhost:8080/websvc/services/Banking";<br />        <br />        IBankingService client = null;<br />        try {<br />            client = (IBankingService) factory.create(serviceModel, serviceUrl);<br />        } catch (MalformedURLException e) {<br />            log.error("WsClient.callWebService(): EXCEPTION: " + e.toString());<br />        }    <br />               <br />        //Invoke the service<br />        String serviceResponse = "";<br />        try { <br />            serviceResponse = client.transferFunds(fromAccount, toAccount, amount, currency);<br />       } catch (Exception e){<br />            log.error("WsClient.callWebService(): EXCEPTION: " + e.toString());                 <br />            serviceResponse = e.toString();<br />        }        <br />        log.debug("WsClient.callWebService(): status=" + serviceResponse);              </font></p><p><font face="Verdana">        //Return the response<br />        return serviceResponse;<br />    } </font></p></td></tr></tbody></table><p>　　这个代码是如何工作的呢?我来解释一下:首先，我们创建一个服务模型，它包含服务的说明——换句话说，就是服务的元数据。我们使用XFire的ObjectServiceFactory从IBankingService.class接口创建这个模型。</p><p>　　接着，为XFire获得一个代理工厂对象，它包含了常规的代码，也相当地简单和易懂。这一步中没有任何特定应用的东西。从这个proxyFactory，使用服务模型和服务端点URL(用来获得WSDL)，我们可以得到一个服务的本地代理。就是它了。这个代理就是实际的客户端。现在，我们可以调用它的transferFunds()方法来得到我们需要的Web Service。</p><p>　　一旦示例应用发布并启动，就可以尝试servlet URL:</p><p>　　http://localhost:8080/websvc/ws。</p><p>　　这个Servlet使用默认参数来调用Web Service和显示接收到的响应。页面的最后两行应该读取:</p><p>　　Response Received<br />　　COMPLETED: CDN$ 500.00 was successfully transferred from A/C# 11111-01234 to A/C# 99999-05678</p><p>　　现在你可以确定Web Service已经发布并且在运行中了。</p><p>　　为了尝试不同的输入值，你可以使用完整的URL，例如:</p><p>　　http://localhost:8080/websvc/ws?from=11-2345&amp;to=77-9876&amp;amt=250.00&amp;cur=EUR。</p><p>　　<strong>基本的Web Services开发步骤清单</strong></p><p>　　这个清单总结了将一个Java方法发布为Web Service所必须的步骤:</p><ul><li>　　1、 检查Java类的方法和默认构造函数确保为public 
</li><li>　　2、 增加XFire servlet相关条目到web.xml中 
</li><li>　　3、 创建services.xml，把它放到WEB-INF/classes/META-INF/xfire目录下 
</li><li>　　4、 增加XFire和第三方包到你的Web应用的WEB-INF/lib文件夹中</li></ul><p>　　这就是所有需要的步骤，是的，相当简单。</p><p>　　<strong>XFire的其他高级特性</strong></p><p>　　XFire的使用可能比较简单，但是在特性和功能性上，它却占据着领导者的位置。下面是它的高级特性:</p><ul><li>　　---本地数据绑定支持POJOs(plain-old Java objects)、XMLBeans、JAXB(Java Architecture for XML Binding)、Castor等等。数据绑定说明了Web Services的XML请求和映射到Java对象的XML响应。 
</li><li>　　---使用StAX(Streaming API for XML)处理XML文档。同DOM的基于树和SAX的事件驱动的处理方式相比，StAX使用了拉(pull)机制，它使处理更快速，内存效率更高。 
</li><li>　　---支持多种传输协议，如HTTP、JMS(Java Message Service)和JVM内部传输。 
</li><li>　　---嵌入式，这是XFire的核心功能之一。你可以把这个SOAP引擎嵌入到你的应用中，完全隐藏所有XFire特定引用，同样所有配置都是程序驱动。 
</li><li>　　---丰富的API，它使XFire可高度自定义，允许开发者在不同的阶段截获请求，并且对他们进行处理。 
</li><li>　　---兼容最新的标准例如SOAP1.1(没有加密远程工程调用，或者RPC)和1.2、WSDL1.1、the Web Services Interoperability Organization’s Basic Profile 1.0、Web Services Addressing和WS-Security。</li></ul><p>　　最重要的是，XFire属于新一代Web Services引擎。不仅仅是营销用语，“新一代”有一些重要的意义。Apache Axis是第一代Java语言的Web Services引擎，已经成为了所有后来工具的参考标准。在过去的几年里，Axis以及这些其它的工具已经在很多生产环境中进行了实地测试。从中得出的一个关键的问题就是Web Services并不最适合RPC类型的通信。对于性能和效率，面向文档的消息形式是最好的方式。但是Apache Axis和很多其他的Web Services引擎都被设计成了面向RPC的(尽管它们支持文档形式)。现在，整个行业正在开发新一代的SOAP引擎，设计为面向文档的。Apache已经宣布结束旧版本的Axis引擎开发，现在专注于Axis2，现在它的预发布版本是0.95。XFire在今年的2月份发布了它的第一个产品版本(1.0)。它的下一个版本(1.1)仅仅在几个星期之后就进行了发布。<strong>性能</strong></p><p>　　Web Services需要消耗很多资源，但是性能方面它们不是那么引人注目。XFire打破了这种趋势。它消耗更少的内存(部分因为 StAX的使用)，但是表现却比多数可比较的SOAP引擎出色。你可以在资源中提供的链接中看到比较的结果。</p><p>　　此外，XFire还提供了各种方法来进一步优化性能。一个方法是使用JVM内置传输(in-JVM transport)。如果你知道Web Services和客户端运行在同一个JVM上，你可以选择使用本地传输，它可以大幅提升性能。在示例中的客户端代码，看以下指定服务端点URL的这行:</p><p>　　String serviceUrl = "http://localhost:8080/websvc/services/Banking";</p><p>　　替换为</p><p>　　String serviceUrl = "xfire.local://Banking";</p><p>　　你会看到性能上的明显提高，因为它绕过了整个网络层。</p><p>　　<strong>局限性</strong></p><p>　　XFire有些重要的局限性你应该清楚:</p><ul><li>　　---开发Web Services的好的实践是从WSDL开始。大部分的SOAP引擎提供了从WSDL生成服务stub的工具。XFire也提供了这样一个工具。但是它是基于注释(annotations-based)的，因此需要J2SE5.0。对于仍坚持使用J2SE1.4.x的人来说，它不是一个令人拍手叫好的工具，因为我们有很多其他方式来编写客户端，一个就是文章中演示的方式。 
</li><li>　　---附件支持，它将会包含在未来发行的版本中。 
</li><li>　　---易于学习的用户向导。XFire团队在这个方面还有很多工作需要做。</li></ul><p>　　<strong>结论</strong></p><p>　　Java当前的趋势是简化技术的使用。因此，我们正看到一波基于POJO的开发成就。同时，面向服务架构(SOA，Services-oriented architecture)和Web Services已经变成了当前行业的热点话题。XFire正是在这种情况下产生的。它能够使POJO发布为最少的Web Services，而只需要付出最小化的努力。从而，它使希望使用这项技术的初级开发者的学习曲线变得平缓。同时，由于它兼容最新标准和提供了丰富的API，XFire为高级用户提供了更多的大好机会。</p><p><font face="Verdana">版权声明：Techtarget获Matrix授权发布,如需转载请联系Matrix<br />作者:Shahid Ahmed ;mydeman<br />原文:http://www.javaworld.com/javaworld/jw-05-2006/jw-0501-xfire.html<br />Matrix:http://www.matrix.org.cn/resource/article/2006-09-24/XFire_6bd1061c-4bc6-11db-978f-43b3336b7e51.html</font></p><img src ="http://www.blogjava.net/mlh123caoer/aggbug/75257.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2006-10-15 12:55 <a href="http://www.blogjava.net/mlh123caoer/archive/2006/10/15/75257.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据仓库和元数据管理</title><link>http://www.blogjava.net/mlh123caoer/archive/2006/08/14/63498.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Mon, 14 Aug 2006 08:07:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2006/08/14/63498.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/63498.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2006/08/14/63498.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/63498.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/63498.html</trackback:ping><description><![CDATA[<strong>1. 前言<br /></strong>　　在事务处理系统中的数据，主要用于记录和查询业务情况。随着数据仓库（DW）技术的不断成熟，企业的数据逐渐变成了决策的主要依据。数据仓库是一种面向决策主题、由多数据源集成、拥有当前及历史总结数据、以读为主的数据库系统，其目的是支持决策。数据仓库要根据决策的需要收集来自企业内外的有关数据，并加以适当的组织处理，使其能有效地为决策过程提供信息。数据仓库中的数据是从许多业务处理系统中抽取、转换而来，对于这样一个复杂的企业数据环境，如何以安全、高效的方式来对它们进行管理和访问就变得尤为重要。解决这一问题的关键是对元数据进行科学有效的管理。元数据是关于数据、操纵数据的进程和应用程序的结构和意义的描述信息，其主要目标是提供数据资源的全面指南。元数据不仅定义了数据仓库中数据的模式、来源以及抽取和转换规则等，而且整个数据仓库系统的运行都是基于元数据的，是元数据把数据仓库系统中的各个松散的组件联系起来，组成了一个有机的整体。<br />　　本文首先介绍了元数据的定义、作用和意义；然后讨论了数据仓库系统中元数据管理的现状和关于元数据的标准化情况；最后提出了建立元数据管理系统的步骤和实施方法。<br />　　<br />　　<b>2. 元数据</b><br />　　2.1 元数据的概念<br />　　按照传统的定义，元数据（Metadata）是关于数据的数据。在数据仓库系统中，元数据可以帮助数据仓库管理员和数据仓库的开发人员非常方便地找到他们所关心的数据；元数据是描述数据仓库内数据的结构和建立方法的数据，可将其按用途的不同分为两类：技术元数据（Technical Metadata）和业务元数据（Business Metadata）。<br />　　技术元数据是存储关于数据仓库系统技术细节的数据，是用于开发和管理数据仓库使用的数据，它主要包括以下信息：<br />　　 数据仓库结构的描述，包括仓库模式、视图、维、层次结构和导出数据的定义，以及数据集市的位置和内容；<br />　　 业务系统、数据仓库和数据集市的体系结构和模式；<br />　　 汇总用的算法，包括度量和维定义算法，数据粒度、主题领域、聚集、汇总、预定义的查询与报告；<br />　　 由操作环境到数据仓库环境的映射，包括源数据和它们的内容、数据分割、数据提取、清理、转换规则和数据刷新规则、安全（用户授权和存取控制）。<br />　　业务元数据从业务角度描述了数据仓库中的数据，它提供了介于使用者和实际系统之间的语义层，使得不懂计算机技术的业务人员也能够“读懂”数据仓库中的数据。业务元数据主要包括以下信息：使用者的业务术语所表达的数据模型、对象名和属性名；访问数据的原则和数据的来源；系统所提供的分析方法以及公式和报表的信息；具体包括以下信息：<br />　　 企业概念模型：这是业务元数据所应提供的重要的信息，它表示企业数据模型的高层信息、整个企业的业务概念和相互关系。以这个企业模型为基础，不懂数据库技术和SQL语句的业务人员对数据仓库中的数据也能做到心中有数。<br />　　 多维数据模型：这是企业概念模型的重要组成部分，它告诉业务分析人员在数据集市当中有哪些维、维的类别、数据立方体以及数据集市中的聚合规则。这里的数据立方体表示某主题领域业务事实表和维表的多维组织形式。<br />　　 业务概念模型和物理数据之间的依赖：以上提到的业务元数据只是表示出了数据的业务视图，这些业务视图与实际的数据仓库或数据库、多维数据库中的表、字段、维、层次等之间的对应关系也应该在元数据知识库中有所体现。<br />　　<br />　　2.2 元数据的作用<br />　　在数据仓库系统中，元数据机制主要支持以下五类系统管理功能：（１）描述哪些数据在数据仓库中；（２）定义要进入数据仓库中的数据和从数据仓库中产生的数据；（３）记录根据业务事件发生而随之进行的数据抽取工作时间安排；（４）记录并检测系统数据一致性的要求和执行情况；（５）衡量数据质量。<br />　　与其说数据仓库是软件开发项目，还不如说是系统集成项目[1]，因为它的主要工作是把所需的数据仓库工具集成在一起，完成数据的抽取、转换和加载，OLAP分析和数据挖掘等。如图1所示，它的典型结构由操作环境层、数据仓库层和业务层等组成。<br />　　<br />　　其中，第一层（操作环境层）是指整个企业内有关业务的OLTP系统和一些外部数据源；第二层是通过把第一层的相关数据抽取到一个中心区而组成的数据仓库层；第三层是为了完成对业务数据的分析而由各种工具组成的业务层。图中左边的部分是元数据管理，它起到了承上启下的作用，具体体现在以下几个方面：<br />　　 便于集成<br />　　 提高系统的灵活性<br />　　 保证数据的质量<br />　　 帮助用户理解数据的意义<br />　　<br />　　<b>3. 数据仓库元数据管理现状</b><br />　　元数据管理的主要任务有两个方面：一是负责存储和维护元数据库中的元数据；二是负责数据仓库建模工具、数据获取工具、前端工具等之间的消息传递，协调各模块和工具之间的工作。<br />　　由以上几节我们了解到元数据几乎可以被称为是数据仓库乃至商业智能（BI）系统的“灵魂”，正是由于元数据在整个数据仓库生命周期中有着重要的地位，各个厂商的数据仓库解决方案都提到了关于对元数据的管理。但遗憾的是对于元数据的管理，各个解决方案都没有明确提出一个完整的管理模式；它们提供的仅仅是对特定的局部元数据的管理。当前市场上与元数据有关的主要工具见图2。<br />　　<br />　　如图2所示，与元数据相关的数据仓库工具大致可分为四类：<br />　　1. 数据抽取工具：把业务系统中的数据抽取、转换、集成到数据仓库中，如Ardent的DataStage、CA（原Platinum）的Decision Base和ETI的Extract等。这些工具仅提供了技术元数据，几乎没有提供对业务元数据的支持。<br />　　2. 前端展现工具：包括OLAP分析、报表和商业智能工具等，如MicroStrategy的DSS Agent、Cognos的PowerPlay、Business Objects的BO，以及Brio等。它们通过把关系表映射成与业务相关的事实表和维表来支持多维业务视图，进而对数据仓库中的数据进行多维分析。这些工具都提供了业务元数据与技术元数据相对应的语义层。<br />　　3. 建模工具：为非技术人员准备的业务建模工具，这些工具可以提供更高层的与特定业务相关的语义。如CA的ERwin、Sysbase的PowerDesigner以及Rational的Rose等。<br />　　4. 元数据存储工具：元数据通常存储在专用的数据库中，该数据库就如同一个“黑盒子”，外部无法知道这些工具所用到和产生的元数据是如何存储的。还有一类被称为元数据知识库（Metadata Repository）的工具，它们独立于其它工具，为元数据提供一个集中的存储空间。包括微软的Repository，CA的Repository，Ardent的MetaStage和Sybase的WCC等。<br />　　<br />　　<b>4. 元数据管理的标准化</b><br />　　没有规矩不成方圆。元数据管理之所以困难，一个很重要的原因就是缺乏统一的标准。在这种情况下，各公司的元数据管理解决方案各不相同。近几年，随着元数据联盟MDC（Meta Data Coalition）的开放信息模型OIM（Open Information Model）和OMG组织的公共仓库模型CWM（Common Warehouse Model）标准的逐渐完善，以及MDC和OMG组织的合并，为数据仓库厂商提供了统一的标准，从而为元数据管理铺平了道路。<br />　　从元数据的发展历史不难看出，元数据管理主要有两种方法：<br />　　(1) 对于相对简单的环境，按照通用的元数据管理标准建立一个集中式的元数据知识库。<br />　　(2) 对于比较复杂的环境，分别建立各部分的元数据管理系统，形成分布式元数据知识库，然后，通过建立标准的元数据交换格式，实现元数据的集成管理。<img src ="http://www.blogjava.net/mlh123caoer/aggbug/63498.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2006-08-14 16:07 <a href="http://www.blogjava.net/mlh123caoer/archive/2006/08/14/63498.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SAS 数据仓库方法论</title><link>http://www.blogjava.net/mlh123caoer/archive/2006/08/14/63497.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Mon, 14 Aug 2006 07:58:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2006/08/14/63497.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/63497.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2006/08/14/63497.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/63497.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/63497.html</trackback:ping><description><![CDATA[<div style="PADDING-RIGHT: 0px; MARGIN-TOP: 10px; FONT-SIZE: 9pt; OVERFLOW-X: hidden; WIDTH: 97%; WORD-BREAK: break-all; TEXT-INDENT: 24px; LINE-HEIGHT: normal; HEIGHT: 200px; WORD-WRAP: break-word" onload="this.style.overflowX='auto';">目   录<br />A. 快速建库方法论浏览 <br />1．什么是数据仓库 <br />2．建立数据仓库的业务理由 <br />3．建立数据仓库的技术理由 <br />4．数据仓库的技术特征 <br />5．确认业务需要和数据仓库的目标 <br />6．关键成功因素 <br />B. SAS快速建立数据仓库方法论的细节 <br />1．业务驱动 <br />2．收集需求的研讨会 <br />3．快速应用开发 (RAD) <br />C．方法论的框架 <br /><br />--------------------------------------------------------------------------------<br /><br />A. 快速建库方法论浏览<br />    一个企业在开发和实施数据仓库时，使用一个高效和经验证的方法论是关键的，这一点已是十分清楚的了。考虑到这一点，多年来SAS研究、发展和改进了经验证的实施数据仓库的方法论，我们称之为快速建库方法论。本文件的这一节将描述这个方法论。<br /><br />1．什么是数据仓库?<br />    一个数据仓库通常是一个分散的数据存储，在其中信息是存为这样的一种形式，它适合于业务智能化和决策支持系统。数据可能是以不同形式存储的，它并不影响OLTP系统的运作。<br />    数据仓库的建立是用一种循环的逐步完善的过程而不是一步完善的。数据仓库通常是与解决企业不断改变的组织问题的全过程有关。<br />    数据仓库通常是围绕主题建立的。主题就是企业感兴趣的论题，比如部门、活动和操作结果。数据仓库的结构是由数据仓库应满足的应用决定的。快速提交信息是成功实施数据仓库的关键。由于这一点，就引入了象数据集市和信息集市这些概念。数据集市是数据仓库的一个子集，它通常更为概括，以满足对关心数据的查询有比数据仓库本身更快的速度。信息集市存储可用视窗器(viewer)显示的预处理的信息。<br /><br />    在信息集市中常包含以下几类信息：<br /><br />报告输出(打印的文本、图形等) <br />多媒体介质 (录象和录音)内容的记录 <br />电子表单 <br />2．建立数据仓库的业务理由<br />    数据仓库为管理者和业务用户提供真正决策支持的基础。企业为这些业务用户存储了多年的信息，但是数据仓库提供专为他们设计的有构架的信息。数据仓库实施的最初阶段往往要解决现成的业务问题(即较为被动的)，而以后的实施常是更为主动的。数据仓库的一个强项是它支持对数据的随时需要的查询和进行未计划的数据探索的需要。就是说，数据仓库给业务用户以不同方法分析数据的能力和自由度，而不受预先设定的一组报告的限制。<br /><br />3．建立数据仓库的技术理由<br />      建立数据仓库最共同的技术理由是企业现用的信息技术结构不能满意地满足业务需要。过去，信息技术集中于运作系统，它保证业务过程运行所必须的任务的自动化。但是，运作系统一般不能很好地满足决策支持的需要。一个运作系统典型的有多个事务处理(transaction)的应用构成，每个应用使部门的一个过程和功能自动化。在运作系统中，每个事务和每一分钟的业务细节都记录在与事务应用关联的数据库中。<br />     事务系统的设计要考虑将部门运作需要的细节信息有效地进入系统。有效性的要求导致应用开发者实现高度规范的数据和在存档发生之前就必须决定作为应用的一部分有多少数据可存储。虽然运作系统对日常业务活的支持是非常有效的，但他们对于运用常规的软件技术支持报表制作、决策和行政信息系统并不是很好的。他们的侧重点是在数据的存储，很少提供访问数据和将数据变为有用决策信息的工具。<br />     运作系统和数据仓库是完全不同的。内容是不同的，结构是不同的，硬件和软件的需求是不同的，管理是不同的和用户是不同的。数据仓库的存储是设计得能提供决策支持信息的。它由业务应用数据来构建，但数据要先经过提取，再进行过滤、校验并组织到反映单位需要的主题中去。<br />     数据仓库的数据是经过一段时间的收集，并用于比较、趋势分析和预测的。<br /><br />    若用运作系统存储的数据做决策支持，将会遇到以下的一些问题：<br /><br />决策要求对历史数据进行比较、趋势分析和预测。这些信息通常在运作系统中是无法得到的。 <br />数据必须从运作数据存区中提取。随着时间推移，这些提取也增长和扩大。数据的可靠性、有效性和通用性都是无法确定的，因为创建各种分析需要的复本时已生成了原始数据源的多个复本和多个不同水平的数据子集。 <br />在运作系统中的数据是按一个特殊的活动而格式化的，它并不考虑单位决策的需要。从多个运作数据库中得到的数据需要提取和处理，这使得很难顾及单位的要求。为了作出可靠的业务决策或者回答简单的业务问题，分析工作者必须花费大量的时间从不同的数据源中局部化或整合有关的信息。 <br />运作系统是经常更新的。当数据经常改变时，就难于对企业的问题作出一致的回答。而回答的经常改变会混淆决策过程。 <br />运作系统对大量细小的事务进行优化。常常一个查询导致另一个查询。业务用户活动的重复本质以及处理大量数据的需要与运作数据库的设计、目的是冲突的。 <br />    很多企业试图用访问数据和提取数据的软件工具从运作系统获得决策支持的数据，有成功的也有不成功的。无论如何，即便使用这些工具，运作系统和决策支持设计固有的矛盾总是存在的。数据仓库按其定义消除了上述的问题。事实上，这些问题帮助我们确定数据仓库的技术特征。<br /><br />4．数据仓库的技术特征<br />    数据仓库的技术特征如下:<br /><br />数据仓库的数据不是多变的。这意味着不同人员对同一信息的需求将获得相同的回答。这也意味着在您分析的过程中数据不会改变。 数据仓库的数据装载是适时和可用于预测的。 <br />数据仓库反映企业机构组织的需要。数据仓库的构件是直接反映您们单位的主题。这些主题规定得可满足企业的需要而不管运作系统的要求。 <br />数据仓库是整合的。所有业务系统的有价值信息都要整合到数据仓库的主题中去。多个业务数据源数据的差别应该在装载到数据仓库之前进行协调。 <br />数据仓库提供企业的历史回顾。多年的数据常以汇总的方式加以存储。与此对照的，典型的业务应用只存储一个较短时段的数据。 <br />数据仓库对查询功能是优化的。优化通常需要对数据预汇总，预索引和预取子集。将数据分隔和组合为许多可能的组合(分片和切块)的能力和有效地反复查询大量数据的能力是数据仓库的基本要求。 <br />最后，数据仓库必须与分析工具项匹配。装载和维护数据仓库只是过程的一部分。一个数据仓库只有具备了辅助的决策支持工具时才是完善的，这一决策支持工具应反映和利用数据仓库的结构。 <br />5．确认业务需要和数据仓库的目标<br />    如同已经看到的，使用数据仓库技术有清楚的技术理由。但是，清晰地设定数据仓库要实现的业务需要和用以评价数据仓库成功的标准这两者同样是十分重要的。在大部分情形，数据仓库是为业务部门建立的。所以数据仓库的成功依赖于对业务部门需求的了解。由于这一点，由业务部门确定数据仓库的内容是必须的。<br />    SAS快速建库方法论也提供问卷和过程，它帮助企业确定数据仓库内容和构架。它也帮助企业确定评价准则和清楚地界定数据仓库项目。清楚地明白企业的需要和目标也将帮助说明数据仓库项目与企业的关系以及数据仓库的作用和企业成功的关系。<br /><br /><br />6．关键成功因素<br />    除了对企业的业务需求和数据仓库目的有一个清晰的了解外，还需要采取下列步骤确保数据仓库项目满足这些需要和目标：<br /><br />选择公司可能的最高人员负责数据仓库项目。他对项目成功负有全职。组成包括业务决策者和IT专家的跨部门项目组。数据仓库成功的一个关键是业务专家和IT专家的密切合作，它将保证数据仓库项目的各个方面都被顾及到。 <br />获取项目成功所需要的资源投资的承诺。 <br />项目拥有权的一致意见。 <br />项目评价标准的一致意见。 <br />确保业务部门与IT部门一致地为项目成功进行努力。 <br />选择可以提供数据仓库完整解决方案的可靠和有能力的伙伴。 <br />若实施一个企业的数据仓库，应该在完成第一循环或项目的模块后，让单位的其他成员知道其成功。若这一循环正确地实现了，其成功应该让有关的每个人员清楚地看到，因为它是可见的且直接关系到企业的目标。回到列举企业任务和处理的清单并从新确定其优先程度。再选择扩展数据仓库的下一个项目。 <br />B. SAS快速建立数据仓库方法论的细节<br />    数据仓库建立的过程一直还是比较新的，还缺少实践经验，并不为IT业界广泛了解。此外，数据仓库常是这样的一个项目，它与单位的许多部门交叉，要求额外的计划，交流和管理。在这些情况下，最好汲取其它方面的经验并遵循一个合理、经验证的方法论。<br />    至此，SAS研究所开发的SAS快速建库方法论帮助企业开发一个高质量数据仓库，它可以在预算的范围内按时地满足甚至超过用户的需要和期望。它提供一个检验数据仓库开发和实施是否成功的测试框架。它是基于SAS研究所的咨询专家、合作伙伴和用户的最佳实践和经验教训，这些专家成功地实施了数据仓库。这一方法论提供了经验证的建库框架，包括过程、问卷、工作表单和模板。若企业自己开发这些，将是耗时和难于管理的。运用SAS的快速建库方法论，在实施数据仓库的往复循环的各阶段会快速地递交结果，使得在一个很短的时间段内达到一个可量化的结果。方法轮是运用快速应用开发和SAS系统原型技术的一个分段式的处理。这是一个整合的，业务驱动的处理：各用户部门在实施的各阶段都有重要的输入，为报告和分析目的而逐步但快速增长地使用数据仓库，对此IT部门应当有准备。<br />    SAS系统提供的工具(例智能化的客户机/服务器，多厂商构架等)可以帮助企业实现一个灵活和低风险的处理。相对于数据仓库对企业的潜在回报，过程的每一步的投入(过程资源、开发人员和工作人员等)是非常低的。<br /><br />    使得SAS快速建库方法论成功的三个主要因素是：<br /><br />业务或用户的关注； <br />细致的收集用户需求和项目界定的研讨会； <br />使用快速应用开发(RAD)处理。 <br />    这些特点在下一节讨论。<br /><br />1．业务驱动<br />    SAS 快速建库的方法论是一个高度地以业务为驱动的过程：<br /><br />了解数据仓库的需要和将从数据仓库中获益的业务管理者必须参加。 <br />业务用户都是项目组的成员。使用有用的技术收集、建立文档和改善关于项目参加者需求的信息。 <br />度量项目业务得益的信息应在项目的早期阶段就加以收集。 <br />重点是放在评估由数据仓库得到的业务效益和投资回报。 <br />2．收集需求的研讨会<br />    研讨会确立象目标、范围和优先这样一些项目的高水平要素。这些是重要的，因为数据仓库项目要影响许多不同的业务领域，这些领域会有不同的优先程度。研讨会也可以缩短完成项目所需要的时间，因为它使人们聚集在一起，可减少个别交谈收集信息的反复次数。<br /><br />3．快速应用开发 (RAD)<br />    一个 RAD循环是对SAS 快速建库方法论本质的一个写照，因为需要尽快第看到他们努力的结果。快速应用开发基于反复发展的循环。即将一个大项目分为小项目，或"构件"，在此每个构件服务于单个操作单元或功能区域的信息需要。每个构件是一个功能的可管理的单元，是易于理解和可以快速向企业显示价值的。<br />    运用 RAD 可以使项目开发组为企业用户设定项目的优先，为每个构件设定主题以及为每个子项目清楚地划定范围。当每个局部任务完成后，会提出和明确进一步的需求。<br />    循环式的处理有如下的好处：<br /><br />有利于应用维护。 <br />改进适应需求改变的能力。 <br />减小无法管理项目的风险。 <br />及早提供用户的反馈。 <br />及早提交用户的可度量的好处。 <br />提交高质量的解决方案。 <br />及早提供结果。 <br />C．方法论的框架<br />    SAS快速建库的方法论典型地分为概括如下的6步。这些步骤提供工作的逻辑分段和检验项目是否建立在一个坚实的基础上。评估、需求调查和总结阶段着眼于确认、理解和回顾项目目标和单位的目标。设计、构建和部署阶段基于使用RAD 手段设计、开发和配置数据仓库环境。以下的流程图提供了方法论各个阶段的一个总貌和流程。<br /><br />SAS 快速建库方法论的各个阶段在以下各节描述。<br /><br />1．评估阶段<br />    在评估阶段，对影响要求解决方案的用户的现有情况和条件进行了解。了解的目的是分析用户的问题和解决它的办法。最初的评估要确认和澄清目标，确认为澄清目标所做的研究的任何需要，这一评估将导致建议开始、延迟或取消这个项目。确定初始阶段项目组的成员和项目范围、作用和主要的提交结果。<br /><br />2．需求调查阶段<br />    在需求调查阶段，项目组收集业务和IT方面的高水平要求。对部门目标和信息需求的信息进行收集。本阶段的结果为提交一个报告，这个报告识别业务的目的、意义、信息要求和用户界面。这些需求也将用于数据仓库设计和项目的其它阶段。而且，这个阶段完成企业级的主题数据模型和数据仓库主题的选取。与收集业务需求的同时，IT需求的调研也同步地进行。并对主题驱动数据仓库的IT要求进行分析。<br /><br />3．设计阶段<br />    在选取主题方面，项目组集中于收集详细的信息要求和设计数据仓库构架，包括数据，过程和应用模型。在这一阶段，使用各种信息收集和验证的手段，包括数据建模、过程建模、座谈和原型展示。项目组评价技术构架，业务需求和信息需求。现有IT构架和要求的IT构架之间的差别是突出的，建议采用合适的数据仓库设计和构架。<br /><br />4．构建阶段<br />    在构建阶段，包括构建物理的数据仓库并组装，应用和处理的编码以及验收测试。在这一阶段数据仓库的管理者和终端用户的指导者应熟悉应用。当测试成功完成后，数据仓库就交付用户使用和维护。<br /><br />5．部署阶段<br />    在部署阶段，数据仓库展示给其他业务用户并开始进行使用应用的训练。在部署后，数据仓库管理者维护数据仓库。对提出的意见进行必要的修改。<br /><br />6．总结阶段<br />    在总结阶段，对项目的成功及其对企业的作用进行评价。总结分三步进行。第一步总结早期项目实施成功和失败的经验和公布以后努力的结果。第二步是应用配置是否如期望的实现了，如有必要须调整计划。第三步评估项目对单位的影响和得益。</div><img src ="http://www.blogjava.net/mlh123caoer/aggbug/63497.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2006-08-14 15:58 <a href="http://www.blogjava.net/mlh123caoer/archive/2006/08/14/63497.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Enterprise Library 2.0 -- Logging Application Block </title><link>http://www.blogjava.net/mlh123caoer/archive/2006/06/10/51811.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Sat, 10 Jun 2006 04:52:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2006/06/10/51811.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/51811.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2006/06/10/51811.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/51811.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/51811.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Enterprise Library 2.0 中的 Logging Application Block 在1.0版本中是Logging and Instrumentation Application Block，因为把重点放在了日志记录上，所以改名为Logging Application Block。Logging Application Block提供了统一的日志记录功能，它支持将日志写入到多种...&nbsp;&nbsp;<a href='http://www.blogjava.net/mlh123caoer/archive/2006/06/10/51811.html'>阅读全文</a><img src ="http://www.blogjava.net/mlh123caoer/aggbug/51811.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2006-06-10 12:52 <a href="http://www.blogjava.net/mlh123caoer/archive/2006/06/10/51811.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个具有DTD处理能力的解析范例</title><link>http://www.blogjava.net/mlh123caoer/archive/2006/04/20/42061.html</link><dc:creator>草儿</dc:creator><author>草儿</author><pubDate>Thu, 20 Apr 2006 00:45:00 GMT</pubDate><guid>http://www.blogjava.net/mlh123caoer/archive/2006/04/20/42061.html</guid><wfw:comment>http://www.blogjava.net/mlh123caoer/comments/42061.html</wfw:comment><comments>http://www.blogjava.net/mlh123caoer/archive/2006/04/20/42061.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mlh123caoer/comments/commentRss/42061.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mlh123caoer/services/trackbacks/42061.html</trackback:ping><description><![CDATA[<br />编译环境是jdk1.5+xerces-j-2.8<br />源码为：import java.io.*;<br />import org.xml.sax.*;<br />import org.xml.sax.helpers.XMLReaderFactory;<br />import org.apache.xerces.parsers.*;<br /> public class ParseXMLDTD<br />{<br />    public void ShowParseResult(String uri)<br />    {<br />        System.out.println("Parse"+"uri"+"File!");<br />        System.out.println("===============================");<br />        ContentHandler Chandler=new ChandlerClass1();<br />        ErrorHandler EHandler=new EHandlerClass1();<br />        DTDHandler DHandler=new DTDHandlerClass1();<br />        try<br />        {<br />            XMLReader MyParser=XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");<br />            MyParser.setContentHandler(Chandler);<br />            MyParser.setErrorHandler(EHandler);<br />            MyParser.setDTDHandler(DHandler);<br />            MyParser.setFeature("http://xml.org/sax/features/validation",true);<br />            MyParser.parse(uri);<br />        }<br />        catch(IOException e)<br />        {<br />            System.out.println("Error IOException !!!");<br />        }<br />        catch(SAXException e)<br />        {<br />            System.out.println("Error SAXException !!!");<br />        }<br />        <br />    }<br />    public static void main(String args[])<br />    {<br />        String uri=args[0];<br />        ParseXMLErrorLog ParseXMLErrorLogInstance=new ParseXMLErrorLog();<br />        ParseXMLErrorLogInstance.ShowParseResult(uri);<br />    }<br />}<br />class ChandlerClass1 implements ContentHandler<br />{<br />    private Locator locator;<br />    public void setDocumentLocator(Locator locator)<br />    {<br />        System.out.println("The Parser called setDocumentLocator()!!!");<br />        this.locator=locator;<br />        System.out.println("===============================");<br />    }<br />    public void startDocument() throws SAXException<br />    {<br />        System.out.println("The Parser called startDocument()!!!");<br />        System.out.println("===============================");<br />    }<br />    public void endDocument() throws SAXException<br />    {<br />        System.out.println("The Parser called endDocument()!!!");<br />        System.out.println("===============================");<br />    }<br />    public void processingInstruction(String target,String data)<br />    {<br />        System.out.println("The Parser called processingInstruction()!!!");<br />        System.out.println("target is {"+target+"}"+"data is {"+data+"}");<br />        System.out.println("===============================");<br />    }<br />    public void startPrefixMapping(String prefix,String uri)<br />    {<br />        System.out.println("The Parser called startPrefixMapping()!!!");<br />        System.out.println("prefix is {"+prefix+"}uri is {"+uri+"}");<br />        System.out.println("===============================");<br />    }<br />    public void endPrefixMapping(String prefix)<br />    {<br />        System.out.println("The Parser called endPrefixMapping()!!!");<br />        System.out.println("prefix is {"+prefix+"}");<br />        System.out.println("===============================");<br />    }<br />    public void startElement(String namespaceURL,String localName,String rawName,Attributes atts) throws SAXException<br />    {<br />        System.out.println("The Parser called startElement()!!!");<br />        if(!namespaceURL.equals(""))<br />        {<br />            System.out.println("nameSpaceURL is {"+namespaceURL+"}"+"rawName is {"+rawName+"}");<br />        }<br />        else<br />        {<br />            System.out.println("There is not namespace");<br />        }<br />        System.out.println("localName is {"+localName+"}");<br />        for(int i=0;i&lt;atts.getLength();i++)<br />        {<br />            System.out.println("Attribute is {"+atts.getLocalName(i)+"}is {"+atts.getValue(i)+"}");<br />        }<br />        System.out.println("===============================");<br />    }<br />    public void endElement(String namespaceURL,String localName,String rawName) throws SAXException<br />    {<br />        System.out.println("The Parser called endElement()!!!");<br />        System.out.println("localName is {"+localName+"}");<br />        System.out.println("===============================");<br />    }<br />    public void characters(char[] ch,int start,int end)<br />    {<br />        String sss=new String(ch,start,end);<br />        System.out.println("The Parser called characters()!!!");<br />        System.out.println("characters is {"+sss+"}");<br />        System.out.println("===============================");<br />    }<br />    public void ignorableWhitespace(char[] ch,int start,int end) throws SAXException<br />    {<br />        String sss=new String(ch,start,end);<br />        System.out.println("The Parser called ignorableWhitespace()!!!");<br />        System.out.println("ignorableWhitespace is {"+sss+"}");<br />        System.out.println("===============================");<br />  }<br />  public void skippedEntity(String name) throws SAXException<br />  {<br />      System.out.println("The Parser called skippedEntity()!!!");<br />        System.out.println("skippedEntity {"+name+"}");<br />        System.out.println("===============================");<br />  }<br />}<br />class EHandlerClass1 implements ErrorHandler<br />{<br />    public void warning(SAXParseException spe) throws SAXException<br />    {<br />        System.out.println("The Parser called warning()!!!!");<br />        System.out.println("Line is "+spe.getLineNumber());<br />        System.out.println("URI is "+spe.getSystemId());<br />        System.out.println("Message is "+spe.getMessage());<br />        System.out.println("===============================");<br />    }<br />    public void error(SAXParseException spe) throws SAXException<br />    {<br />        System.out.println("The Parser called error()!!!!");<br />        System.out.println("Line is "+spe.getLineNumber());<br />        System.out.println("URI is "+spe.getSystemId());<br />        System.out.println("Message is "+spe.getMessage());<br />        System.out.println("===============================");<br />    }<br />    public void fatalError(SAXParseException spe) throws SAXException<br />    {<br />        System.out.println("The Parser called fatalError()!!!!");<br />        System.out.println("Line is "+spe.getLineNumber());<br />        System.out.println("URI is "+spe.getSystemId());<br />        System.out.println("Message is "+spe.getMessage());<br />        System.out.println("===============================");<br />    }<br />}<br /><br />class DTDHandlerClass1 implements DTDHandler //声明DTDHandlerClass，此类实现DTDHandler接口<br />{<br />    public void notationDecl(String  name,String publicId,String systemId) throws SAXException<br />    {<br />        //输出符号的相关信息<br />        System.out.println("The Parser called notationDecl()!!!!");<br />        System.out.println("name is "+name);<br />        System.out.println("publicId is "+publicId);<br />        System.out.println("systemId is "+systemId);<br />        System.out.println("===============================");<br />    }<br />    public void unparsedEntityDecl(String name,String publicId,String systemId,String notationName) throws SAXException<br />    {<br />        //输出不可分析实体的相关信息<br />        System.out.println("The Parser called unparsedEntityDecl()!!!!");<br />        System.out.println("name is "+name);<br />        System.out.println("publicId is "+publicId);<br />        System.out.println("systemId is "+systemId);<br />        System.out.println("notationName is "+notationName);<br />        System.out.println("===============================");<br />    }<br />}<br /><br />采用的xml文件为：second.xml<br />&lt;?xml version="1.0" encoding="gb2312"?&gt;<br />&lt;!DOCTYPE employee_data [<br />&lt;!ELEMENT employee_inf (employee_data+)&gt;<br />&lt;!ELEMENT employee_data (name,age,sex,address,E_mail,photo)&gt;<br />&lt;!ELEMENT name (#PCDATA)&gt;<br />&lt;!ELEMENT age (#PCDATA)&gt;<br />&lt;!ELEMENT sex (#PCDATA)&gt;<br />&lt;!ELEMENT address (#PCDATA)&gt;<br />&lt;!ELEMENT E_mail (#PCDATA)&gt;<br />&lt;!ELEMENT Photo EMPTY&gt;<br />&lt;!NOTATION jpg SYSTEM "C:\windows\system32\mspaint.exe"&gt;<br />&lt;!ENTITY mm_photo SYSTEM "mm_photo.jpg" NDATA jpg&gt;<br />&lt;!ATTLIST photo picture ENTITY #IMPLIED&gt;<br />&lt;!ATTLIST photo sw_tool NOTATION (jpg) #IMPLIED&gt;<br />]&gt;<br />&lt;employee_inf&gt;<br />   &lt;employee_data&gt;<br />      &lt;name&gt;马连浩&lt;/name&gt;<br />      &lt;age&gt;24&lt;/age&gt;<br />      &lt;sex&gt;男&lt;/sex&gt;<br />      &lt;address&gt;大连交通大学&lt;/address&gt;<br />      &lt;E_mail&gt; mlh123caoer@tom.com&lt;/E_mail&gt;<br />      &lt;photo picture="mm_photo" sw_tool="jpg"/&gt;<br />   &lt;/employee_data&gt;<br />&lt;/employee_inf&gt;<br />dos输出效果为：<br />D:\2000&gt;javac ParseXMLDTD.java<br /><br />D:\2000&gt;java ParseXMLDTD second.xml<br />ParseuriFile!<br />===============================<br />The Parser called setDocumentLocator()!!!<br />===============================<br />The Parser called startDocument()!!!<br />===============================<br />The Parser called notationDecl()!!!!<br />name is jpg<br />publicId is null<br />systemId is file:///C:/windows/system32/mspa<br />===============================<br />The Parser called unparsedEntityDecl()!!!!<br />name is mm_photo<br />publicId is null<br />systemId is file:///D:/2000/mm_photo.jpg<br />notationName is jpg<br />===============================<br />The Parser called startElement()!!!<br />There is not namespace<br />localName is {employee_inf}<br />===============================<br />The Parser called ignorableWhitespace()!!!<br />ignorableWhitespace is {<br />   }<br />===============================<br />The Parser called startElement()!!!<br />There is not namespace<br />localName is {employee_data}<br />===============================<br />The Parser called ignorableWhitespace()!!!<br />ignorableWhitespace is {<br />      }<br />===============================<br />The Parser called startElement()!!!<br />There is not namespace<br />localName is {name}<br />===============================<br />The Parser called characters()!!!<br />characters is {马连浩}<br />===============================<br />The Parser called endElement()!!!<br />localName is {name}<br />===============================<br />The Parser called ignorableWhitespace()!!!<br />ignorableWhitespace is {<br />      }<br />===============================<br />The Parser called startElement()!!!<br />There is not namespace<br />localName is {age}<br />===============================<br />The Parser called characters()!!!<br />characters is {24}<br />===============================<br />The Parser called endElement()!!!<br />localName is {age}<br />===============================<br />The Parser called ignorableWhitespace()!!!<br />ignorableWhitespace is {<br />      }<br />===============================<br />The Parser called startElement()!!!<br />There is not namespace<br />localName is {sex}<br />===============================<br />The Parser called characters()!!!<br />characters is {男}<br />===============================<br />The Parser called endElement()!!!<br />localName is {sex}<br />===============================<br />The Parser called ignorableWhitespace()!!!<br />ignorableWhitespace is {<br />      }<br />===============================<br />The Parser called startElement()!!!<br />There is not namespace<br />localName is {address}<br />===============================<br />The Parser called characters()!!!<br />characters is {大连交通大学}<br />===============================<br />The Parser called endElement()!!!<br />localName is {address}<br />===============================<br />The Parser called ignorableWhitespace()!!!<br />ignorableWhitespace is {<br />      }<br />===============================<br />The Parser called startElement()!!!<br />There is not namespace<br />localName is {E_mail}<br />===============================<br />The Parser called characters()!!!<br />characters is { mlh123caoer@tom.com}<br />===============================<br />The Parser called endElement()!!!<br />localName is {E_mail}<br />===============================<br />The Parser called ignorableWhitespace()!!!<br />ignorableWhitespace is {<br />      }<br />===============================<br /><font color="#cc3300">The Parser called startElement()!!!<br />There is not namespace<br />localName is {photo}<br />Attribute is {picture}is {mm_photo}<br />Attribute is {sw_tool}is {jpg}</font><br />===============================<br />The Parser called endElement()!!!<br />localName is {photo}<br />===============================<br />The Parser called ignorableWhitespace()!!!<br />ignorableWhitespace is {<br />   }<br />===============================<br />The Parser called endElement()!!!<br />localName is {employee_data}<br />===============================<br />The Parser called ignorableWhitespace()!!!<br />ignorableWhitespace is {<br />}<br />===============================<br />The Parser called endElement()!!!<br />localName is {employee_inf}<br />===============================<br />The Parser called endDocument()!!!<br />===============================<br />设计者：mlhcaoer 邮箱：mlh123caoer@tom.com QQ:215960358<br />欢迎高手指导<br /><img src ="http://www.blogjava.net/mlh123caoer/aggbug/42061.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mlh123caoer/" target="_blank">草儿</a> 2006-04-20 08:45 <a href="http://www.blogjava.net/mlh123caoer/archive/2006/04/20/42061.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>