精彩的人生

好好工作,好好生活

BlogJava 首页 新随笔 联系 聚合 管理
  147 Posts :: 0 Stories :: 250 Comments :: 0 Trackbacks

#

jUDDI,发音(Judy),是服务于WebServices 的UDDI的java实现开源包。

1 安装

1.1 下载

下载地址:http://ws.apache.org/juddi/releases.html

目前的jUDDI的最新版本是0.9rc3(Release Candidate #3 for Version 0.9),不过在这个版本中有一些的bug。

juddi0.9版本发布应该是不会久,可以参考下面这段话,是Viens Stephen(juddi主要开发者之一)在mail list中说的:we've closed 40+ issues since January 1, 2005. We'll be releasing a 0.9rc4 as soon as Axis 1.2 final is released and then releasing a 0.9 final a few weeks after that. (March 22, 2005)

1.2 数据库安装

UDDI需要有一个地方来存储注册的数据,因此首先要选择一个关系数据库安装。JUDDI可以使用任何支持ANSI standard SQL关系数据库( 例如MySQL, DB2, Sybase, JdataStore等)。本实例使用MySQL。

数据库安装完成后,在MySQL数据库中运行juddi-0.9rc3\\sql\\mysql\\create_database.sql, juddi-0.9rc3\\sql\\mysql\\insert_publishers.sql。数据库准备完成。

1.3 安装juddi及配置

首先将juddi-0.9rc3\\webapp下的juddi文件夹复制到Tomcat下的webapps中,并将 mysql-connector-java-3.1.7\\mysql-connector-java-3.1.7-bin.jar复制到Tomcat 5.0\\webapps\\juddi\\WEB-INF\\lib下。

下面就是连接数据库的配置,在Tomcat/conf/server.xml的Host element中加入:
<Context path="/juddi" docBase="juddi" debug="5" reloadable="true" crossContext="true">
<Logger className="org.apache.catalina.logger.FileLogger" prefix="localhost_juddiDB_log"
suffix=".txt" timestamp="true"/>
<Resource name="jdbc/juddiDB" auth="Container" type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/juddiDB">
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<!-- Maximum number of dB connections in pool. Make sure you
configure your mysqld max_connections large enough to handle
all of your db connections. Set to 0 for no limit. -->
<parameter><name>maxActive</name><value>100</value></parameter>
<!-- Maximum number of idle dB connections to retain in pool.
Set to 0 for no limit. -->
<parameter><name>maxIdle</name><value>30</value></parameter>
<parameter><name>maxWait</name><value>10000</value></parameter>
<!-- MySQL dB username and password for dB connections 帐号密码根据数据库安装配置修改 -->
<parameter><name>username</name><value>root</value></parameter>
<parameter><name>password</name><value>****</value></parameter>
<!-- Class name for mysql JDBC driver -->
<parameter>
<name>driverClassName</name>
<value>com.mysql.jdbc.Driver</value>
</parameter>
<!-- The JDBC connection url for connecting to your MySQL dB.
The autoReconnect=true argument to the url makes sure that the
mm.mysql JDBC Driver will automatically reconnect if mysqld closed the
connection. mysqld by default closes idle connections after 8 hours.
数据库url连接配置
-->
<parameter>
<name>url</name>
<value>jdbc:mysql://host.domain.com:3306/juddi?autoReconnect=true</value>
</parameter>
<parameter>
<name>validationQuery</name>
<value>select count(*) from PUBLISHER</value>
</parameter>
</ResourceParams>
</Context>

1.4 本地安装检查

访问http://127.0.0.1:8080/juddi/happyjuddi.jsp页面,此页面检查了jUDDI所必须的包和配置的正确性,并测试数据库连接是否成功。 如果没有红色文字,即本地安装成功,即可进行webservices的发布发现等服务。

2 测试实例



以上安装成功的是UDDI的服务器端,而进行发布、查找服务的客户端的应用则要用jUDDI、UDDI4J等包来进行开发。我们可以直接使用jUDDI自 带的测试代码来进行客户端使用的学习。

2.1 使用uddi4j测试

使用uddi4j作为客户端进行测试。

代码位置:juddi-0.9rc3\\src\\uddi4j\\org\\apache\\juddi\\uddi4j

新建立好一个工程并引入此代码,然后对代码进行必要的修改,主要是包名和配置。引入必要的包,比如:junit.jar、 uddi4j.jar、juddi.jar、soap.jar等(因为欧的代码库中有很多种代码,对应很多包,不知道其他哪些是必须的了:)。

接着是数据库的初始化,需要插入一个可以添加其他Publisher的Publisher,sql 语句: INSERT INTO PUBLISHER (PUBLISHER_ID,PUBLISHER_NAME,ENABLIED,ADMIN) VALUES ('juddi','juddi user','true','true');

调试代码后,运行TestAll测试,您可能会发现测试FAILURE很多,这些当中有些是测试代码的错误,也有可能是juddi-0.9rc3的缺陷( juddi-0.9rc3不是正式发布版)。

以下列举一些本测试案例测试失败的可能出现的修改方法:

2.1.1 加载配置文件时访问不到samples.prop

我的解决办法是将建立一个新配置文件位置,在工程目录下的:conf\\samples.prop。

在Configurator.load()方法中代码可以这样修改:
    Properties config = new Properties();
try {
config.load(new java.io.FileInputStream("./conf/samples.prop"));
}
catch (Exception e) {
System.out.println("Error loading samples property file\\n" + e);
}
解决方法很多,您可以自己思索。

2.1.2 TransportClassName配置错误

如果错误提示中有这样的报告,即可能是此错误:
org.xml.sax.SAXParseException: Element or attribute do not match QName production: QName::=(NCName':')?NCName.

在当前测试实例代码中的默认配置(samples.prop)中,TransportClassName定义成org.uddi4j.transport.ApacheSOAPTransport, 而我们使用的包是axis.jar,因此需要修改成相应的类,代码修改如下:
# -----------------------------------------------------------------------

# Transport classname. Typically defined on commandline as

# -Dorg.uddi4j.TransportClassName=xxx.

# -----------------------------------------------------------------------

#TransportClassName=org.uddi4j.transport.ApacheSOAPTransport

TransportClassName=org.uddi4j.transport.ApacheAxisTransport

# TransportClassName=org.uddi4j.transport.HPSOAPTransport

2.1.3 TestFindBusiness案例不通过

TestFindBusiness中有大小写匹配测试,但是在juddi-0.9rc3中的大小写匹配(caseSensitiveMatch)有bug,因此可以将大小写匹配的测 试案例注释掉。

2.1.4 PublisherManager的代码错误

在测试Test_save_tModel的时候_testAuthTokenExpired()中,我们测试过期验证时,在错误匹配的时候,会出现测试失败,如果捕捉这个 匹配的结果,你会发现,出错的类型是E_authTokenRequired而不是期待的E_authTokenExpired。

这是因为在我们所获得的AuthToken是空的,在根源就是在PublisherManager. getExpiredAuthToken(String, String)方法中,代码:
RegistryProxy proxy = new RegistryProxy();
proxy的实例的配置是空的。因此,我们修改这个方法变成:
  /**

* changed by xio

* @param publisher String

* @param password String

* @param testprops Properties:增加的参数,传入基本配置

* @return String

*/

public static String getExpiredAuthToken(String publisher, String password,

Properties testprops) {

Properties props = new Properties();

props.setProperty(RegistryProxy.ADMIN_ENDPOINT_PROPERTY_NAME,

testprops.getProperty("adminURL"));

props.setProperty(RegistryProxy.INQUIRY_ENDPOINT_PROPERTY_NAME,

testprops.getProperty("inquiryURL"));

props.setProperty(RegistryProxy.PUBLISH_ENDPOINT_PROPERTY_NAME,

testprops.getProperty("publishURL"));



RegistryProxy proxy = new RegistryProxy(props);

AuthToken token = null;

AuthInfo authInfo = null;

String ret = null;

try {

token = proxy.getAuthToken(publisher, password);

authInfo = token.getAuthInfo();

ret = authInfo.getValue();

System.out.println("getExpiredAuthToken:" + authInfo);

proxy.discardAuthToken(authInfo);

}

catch (Exception ex) {

ex.printStackTrace();

}

return ret;

}

2.2 使用jUDDI测试

在juddi-0.9rc3版本中自带的代码中没有客户端的使用实例,虽然附带了整个项目代码的测试代码,但是估计没什么人喜欢从这里抽取学 习客户端使用的学习。

当然,学习的实例还是有的,在cvs当前的工程代码中,有个samples的文件夹,这部分代码便是一个十分齐全的实例(有几个类没完成, 但不影响:)。

Cvs服务器数据:http://ws.apache.org/juddi/cvs.html

Wincvs的使用请网上下载阅读。

其他:在进行代码学习的同时,建议阅读webservices相关资料文档。强烈建议阅读:理解 UDDI 注册中心的 WSDL 系列 (http://www-900.ibm.com/developerWorks/cn/webservices/ws-uwsdl/part1/)

参考资料:
http://wiki.apache.org/ws/jUDDI_HOW-TOs
http://ws.apache.org/juddi/lists.html

原作者:xio@qq.com
来 源:http://xio.mblogger.cn



原文地址:http://it.13520.org/ArticleView/2005-9-7/Article_View_121697.Htm

posted @ 2006-07-18 15:04 hopeshared 阅读(2087) | 评论 (0)编辑 收藏

在过去的数年中,许多开发人员都使用了各种版本的J2EE,使服务器端软件编程的情形得到了很大的改观,现在,他们将再次挑战SOAP,在服务器端软件编程方面取得更大的进展。
SOAP服务的支持者认为:
·企业级应用服务器是服务(或事务)的集合。
·可以使用的服务应当很方便地列出来供用户浏览、搜索和访问。
·象现在的基于组件的开发模式那样,将应用服务器设计为服务的集合将鼓励开发人员采用更好的设计模式。
·这些事务能够被重新定位、负载平衡、替代等。
而对SOAP持怀疑态度的人认为,SOAP是推广CORBA和COM的又一次尝试。他们指出,要简单地访问一个对象,需要完成太多的准备性工作,而且,UDDI带来的好处也被夸大了。
那么,到底哪一种观点更合理呢?对于一些思想开放的人士而言,在决定是否采用SOAP服务前,他们一定希望了解其中的一些核心技术。
解密UDDI
我们首先来看看UDDI代表什么?UDDI是Universal Description, Discovery and Integration(统一描述、发现和集成)的缩写。UDDI的意图是作为一个注册簿,就象黄页是一个地区企业的注册簿一样。象在黄页中那样,在UDDI注册簿中,企业将在不同的目录下注册它们自己或其服务。通过浏览一个UDDI注册簿,开发人员能够查找一种服务或一个公司,并发现如何调用该服务。
除了黄页外,UDDI还使用了白页和绿页。白页是企业实体列表,绿页是调用一项服务所必需的文档。
UDDI的定义非常全面,足以适应不同种类的服务。一个UDDI服务定义可能代表一个传真服务或电话服务。作为一种注册簿,UDDI一般使用数据库一类的软件来实现,在该数据库中,存在一个允许发布或查询服务的有关信息。
UDDI数据模型
UDDI数据模型包括下面的主要元素:
·businessEntity:表示一个实际的企业。
·businessService:表示一个企业提供的服务。
·bindingTemplate:如何调用服务的说明。
·tModel>: Good luck understanding this! (Just kidding, I will explain this later.)
为了加深对UDDI数据模型的理解,我们来看看这些数据元素的UML表示法。图1是这四种主要元素之间的关系图:

从上面的图中我们可以知道,一个businessEntity(一家公司)有一个能够告诉我们更多有关公司信息的描述性URL和联系人清单,此外,businessEntity还有一个商业服务清单。每种服务可能有多种调用方法,每种调用都由一个绑定模板描述。绑定模板详细地描述了如何访问一个服务,它受益于一系列描述用户如何访问这一服务的文档。绑定模板和其必要的文档之间的联系是通过所谓的tModel完成的。在上面的图中,这种联系被简单地描述为一个绑定模板有许多tModels。在进一步地解释tModels与绑定模板的关系前,我们必须先弄清楚tModels是什么。
TModel是什么?
我们可以把tModel想象成数据库库中的一个独立的表,其中包含下面的字段:名字、描述、URL、唯一的关健字。实际上,tModel就是包括有名字和描述,那么使用数据库表表示它是否是一种浪费呢?我们下面就会讨论这一问题:
下面是一个假想的tModel数据库表中的二个实体:
键 名字 描述 URL
1 Java-class 表示一个具备完全资格的java类的名字 http://www.javasoft.com/
2 Jndi-home 表示一个JNDI名字 http://www.javasoft.com/

在将tModel比作数据库表方面,有几点值得注意。首先,tModel是一个独立的表,意味着它可以不依赖其他软件而存在;其次,tModel是查找表,提供了键与键的表示之间的转换关系。从这一点来看,tModel象词典那样,是一个引用表。在一些数据库中,这样的表也被称作是码集。
因此,如果在上面的tModel中存在下面的记录:
com.mycompany.HelloWorld, 1
com.mycompany.HelloWorldHome, 2
就意味着字符串com.mycompany.HelloWorld是一个有完整资格的Java类;而字符串com.mycompany.HelloWorldHome是一个JNDI名。

因此在一定程度上,tModels中唯一的键与“名字空间”这个概念差不多。为了进一步地说明这个问题,我们来看一下下面的数字:
904-555-1212
904-555-1213
1-56592-391-x
你能够分清这些数字的意义吗?我们需要在一个环境或名字空间中来确认,904-555-1212是电话号码,904-555-1213是传真号,1-56592-391-x是一个ISBN号。
因此在tModel数据库表中,我们将需要定义三个实体:一个是电话号码;一个是传真号码,一个是ISBN号码。
下面我们以mycompany公司公布了一条号码为1-800-my-helpline的电话支持热线,并在UDDI中注册。那么,我们的数据模型为:
company name: mycompany
Service name: helpline
tModel: key=11 (representing telephoneline), name=telephone,
description=telephone stuff, url:
some at&t url
binding:
accesspoint: 1-800-my-helpline
tModelInstanceInfo: 11

有了对tModel的基本理解后,我们就可以利用UML图表来研究绑定模板与tModels之间的关系了。我在上面曾经说过,这将使我们对绑定模板如何完成UDDI的“如何调用一项服务”的要求有一个直观的理解。

在图2中,我们讨论了一个绑定模板与tModels之间的关系。从图表中我们可以看出,一个绑定模板可以指向一个由一个tModel确定的技术规格,技术规格有二部分组成:
·规格的类型。(例如电子邮件、传真、WSDL、SOAP等。)
·确定输入和输出的文档(在SOAP服务中,这些文档可以是XML输入/输出消息格式。)
既然我们已经对tModels有了一定程度的详细了解,就该再讨论UDDI中更复杂的东西了,也就是身份包和类别包。
理解标识符包和类别包
如果说从概念上理解tModels是理解UDDI需要跨越的第一道障碍,那么理解标识符包和类别包则是需要跨越的第二道障碍。下面的例子可以帮助我们理解这二个概念。
例如,您的公司在美国开展业务需要有一个税号,如果还在另外的国家(例如墨西哥)开展业务,就需要有一个墨西哥的税号。为了能够在UDDI注册簿中获取您的公司的这些信息,在UDDI中应当包括下面的内容:
公司名字:mycompany
标识符:
美国税号:111111
墨西哥税号:2223344
其他国家税号: 333333

...其他的xml内容
<identifierBag>
<keyedReference tModelKey="US-tax-code"
keyName="taxnumber" keyValue="1111111">
<keyedReference tModelKey="Mexico-tax-code"
keyName="taxnumber" keyValue="2223344">
<keyedReference tModelKey="other-stuff"
keyName="taxnumber" keyValue="333333">
</identifiedBag>
... 其他的xml内容
现在明白tModels如何被用作名字空间了吧。为了进一步地深化对标识符包的理解,我们在下面的图中再次解释了标识符和类别包的概念:

从上面的图中我们能够看出,标识符包是一个在特定环境中的键/值对集合,这个环境从本质上说就是能够唯一地解析名字/值对儿的名字空间,它是由tModel确定的。类别包也是如此,二者之间唯一的区别就是类别包中由tModel确定的名字空间是一个预先确定好的类别。
类别包
我想将公司归类于饭店,其地理位置位于杰克逊维尔。
公司名字:mycompany
适用类:
企业类型:饭店
所在城市:杰克逊维尔
<categoryBag>
<keyedReference tModelKey="BusinessTypeClassification"
keyName="restaurant" keyValue="..">
<keyedReference tModelKey="CityClassification"
keyName="JAX" keyValue="..">
</categoryBag>
现在,我们已经搞清楚了tModels是如何用在标识符和类别包中的。从本质上说,tModels就是名字空间。

tModels也能被分类吗?
我们已经明白了企业实体是如何利用使用了类别包的。另外,UDDI也允许tModels本身被分类。
我们用分层次的文件系统进行说明。目录是用来对文件进行分类的,但目录还可以在父目录下再被分类。象硬盘上的目录那样,tModels也可以被分层次地进行组织。
下面我们来讨论名字为getUniversalTime()的服务,该服务将返回当前全球任一地方的时间。二家存在竞争关系的公司可能会提供这一服务的不同实现。商业服务只限于在公司内部使用,公司之外的用户是不可使用的:
company1:getTime()
company1:getCurrentTime()
这二者的作用相同,为了表明它们实现的是同一个被称作getUniversalTime()的服务,我们可以定义如下所示的tModel:
tModel
name:: Get Universal Time
category: uddi-org:types, wsdl
[意味着这是一个由WSDL文档定义的服务]
上面的定义表明getUniversalTime()是一个WSDL服务,可以由任何公司实现。
既然已经阐明了tModels和包之间的关系,我们下面可以看看一个tModel的UML表示:

从上面的图表中,我们可以看出tModel基本上就是一个名字和描述,另外,它也可以包含一个URL,以提供更进一步的详细资料。它可以由一个标识符包确定和由一个类别包进行分类。
我们已经知道,一个tModel所属于的类别是由UDDI━━WSDL、SOAP等预先定义好的,下面是一个uddi-org:types名字空间中预先定义类别的清单:
tModel
identifier (唯一标识符)
namespace
categorization
specification
xmlSpec
soapSpec
wsdlSpec
protocol
transport
signatureComponent
如何开始在UDDI中创建一个服务?
在开始定义服务的tModel时,要求我们为服务指定一个名字和上面所列出的服务类型中的一个。当然了,如果不喜欢上面的分类可以自己创建类别。
我们可以针对上面定义的tModel开发一个商业服务。在商业服务定义中,我们需要指定一个指向定义了服务的输入/输出的WSDL文档的URL。

在UDDI中为什么需要tModels?
在UDDI中使用tModels的目的如下:
·对商业实体进行标识和分类
·对商业服务进行标识和分类
·对tModels进行标识和分类
·将商业服务绑定到它们抽象的tModel定义上
UDDI名词的快速参考
在看有关UDDI的资料时,如果看到很深奥的术语是一件很烦人的事儿,下面我们就把一些经常用到的与UDDI有关的概念搜集起来,通过比较帮助我们对UDDI概念的理解:
接口和实现
服务绑定是一个容器,接口依赖于其实现;绑定元素详细说明了tModelInstaceInfo和instanceDetail, 我们将再通过一个例子加深对这一问题的例子。对于“获得统一时间”服务而言,细节将提供定义了输入、输出的实际的WSDL文档,绑定的访问点将提供实现服务的物理机器和端口。了解了这些,我们可以得出如下的结论:
·为一种服务定义的tModel是允许多家公司提供该服务的多个实现的界面。
·服务绑定是具体的实现。
名字空间
Java、C++和XML中都有名字空间的概念,尽管其叫法可能不同,但它们都提供了使名字有意义的环境。在UDDI中,tModel象征着“名字”。当把这个名字作为目录使用时,你的本意是,“我属于这个名字”。从这个意义上说,tModel表示的是名字空间。
技术指纹
当一种服务被注册为tModel时,我们可以注册用来与该服务通讯的协议(例如WSDL、SOAP等)。因此根据所使用的协议不同,tModel有WSDL指纹或SOAP指纹。因此tModel被认为是技术性指纹,每种指纹与一种特定的协议有关。如果说一种tModel可以代表一个“技术性指纹”,我们也可以说tModel能够表示一种“协议”。
分类
分类与类别、名字空间类似,它提供了一种环境,只有在这种环境下,一些数字和名字才有意义。例如,
白页
UDDI注册簿中的企业实体列表和根据名字搜索企业的能力。
黄页
黄页将企业实体按企业类别或其他适用的类别分类。
绿页(技术规格)
绿页有助于我们理解服务的定义和访问服务的要求,serviceBindings和tModels也有助于这一目标的实现。
JAXR
JAXR是在服务注册中使用的一种Java XML API。我们以前曾经讨论过,UDDI中的所有元素都用XML文档进行描述。从某种意义上说,嘦我们能够发送包含有服务描述的XML消息,UDDI注册簿就能够对它进行注册或更新。下面我们讨论在没有工具的情况下如何完成这一任务:
1、编写必要的服务描述XML文档。
2、理解SOAP头部,以便能够将XML文件作为一个SOAP附件发送给UDDI注册簿。
3、使用SOAP客户端Java API完成第二步中的任务。
4、通过编程的方式处理SOAP消息。
5、根据UDDI服务的描述,构造消息完成该UDDI服务的任务。
6、对每个消息,完成第2、3步中的操作。
如果使用JAXR,我们可以更好地完成这一任务。因为JAXR允许我们在发送XML消息时无需考虑SOAP头部,而且是一种严格的面向消息的协议。使用JAXR,上面的任务将简化为:
1、编写必要的服务描述XML文档。
2、使用JAXM API发送和接收XML消息,JAXR隐藏了SOAP信息。
3、根据UDDI服务构建消息完成该UDDI服务。(例如,向UDDI注册簿注册UDDI服务包含有4次信息交换过程。)这意味着我们仍然需要与XML内容打交道。
使用这种方式,我们只需处理高层次的Java API即可,这些Java API能够产生必需的消息并通过JAXR传输它们。需要指出的一点是,JAXR也用来完成该任务。
下面列出了JAXR的一些目标:
·支持业界标准的XML注册功能
·支持成员机构和企业的注册
·支持任意注册内容的存储和提交
·支持XML、非XML注册内容的管理
·支持注册内容间用户定义的结合
·支持用户定义的注册内容的多级分类
·支持基于定义的分类计划的注册内容查询
·支持基于复杂查询的注册内容查询
·支持基于关健词的注册内容查询
·支持Web服务的共享
·支持合作伙伴间商业过程的共享
·支持合作伙伴间计划的共享
·支持合作伙伴间商业文档的共享
·支持合作伙伴间贸易伙伴协议的谈判
·支持计划汇编
·支持异类分布注册
·支持参与各方发布/订阅XML消息
JAXR将不仅仅支持UDDI,还会支持其他的类似注册服务标准(例如ebXML)。


原文地址:http://www.wyt2008.com/Article/java/web/200603/Article_921.html
posted @ 2006-07-18 10:16 hopeshared 阅读(792) | 评论 (0)编辑 收藏

利用w3c的dom:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
  DocumentBuilder builder;
  
try   {
   builder 
=  factory.newDocumentBuilder();
   Document doc 
=  builder.parse( new  ByteArrayInputStream(str.getBytes())); 
  }
  catch  (ParserConfigurationException e)  {
   
//  TODO Auto-generated catch block
   e.printStackTrace();
  }
  catch  (SAXException e)  {
   
//  TODO Auto-generated catch block
   e.printStackTrace();
  }
  catch  (IOException e)  {
   
//  TODO Auto-generated catch block
   e.printStackTrace();
  }
 

利用dom4j
SAXReader saxReader = new SAXReader();
        Document document;
        
try {
            document 
= saxReader.read(new ByteArrayInputStream(str.getBytes()));
            Element incomingForm 
= document.getRootElement();
        }
 catch (DocumentException e) {
            
// TODO Auto-generated catch block
            e.printStackTrace();
        }
posted @ 2006-07-06 11:17 hopeshared 阅读(13947) | 评论 (6)编辑 收藏

日益提高的机动性和通讯的多种模式已经使个人通讯管理成为了一项非常耗费时间的任务。企业语音应用(通常指统一通讯应用)有助于提高人员的工作效率和管理复杂的多频道通信。融合的语音和数据网络使创建企业语音应用成为可能。企业语音应用采用一个单一的接口来满足所有人员的通讯需求从而简化了通讯。

  企业语音应用的例子包括自动总机、统一消息、follow-me(跟随)、一号通、语音拨号、鼠标拨号、语音门户、会议和协作应用等。部署一个企业语音应用的最初投资一般包括运行这些应用的平台和应用程序本身。这些应用包括一台服务器、电话或者VoIP接口硬件或者软件和一个语音应用平台)。

  最近向开放的、基于标准的解决方案过渡的趋势对降低平台的成本做出了很大的贡献。语音应用程序能够安装在运行标准操作系统(Windows或者Linux)的标准英特尔服务器上和基于标准的使用VoiceXML、CCXML和MRCP的语音/媒体平台上。企业有时候为了减少老式系统每年的维护成本将用新的、开放的、标准的系统替换那些老式专有的系统。

  根据应用的复杂性和所需要的个性化处理的数量,语音应用的成本有很大的差别。对于许多应用来说(如自动总机或者一个会议应用),这种语音应用多数都是捆绑式的服务,而且使用的价格比较合理,至少要比前几年的成本低很多。

  这些较低的成本、因为语音和数据网络的融合而大量节省的成本、以及在整个企业范围内提供这些应用等因素结合在一起将对企业更有吸引力并且能节省更多的成本。无线网络(包括局域网和广域网)能够更方便地让人们在移动中使用同样的应用程序。

  如果你已经拥有一个融合的网络并且正在设法证明一个企业语音应用的实例是合理的,这个实例在几乎所有的应用实例中都能很容易地做到。例如,一个每周7天每天24小时提供话务员服务并且成本不到4万美元的自动总机可以通过节省一个话务员的工资和福利待遇来证明是合理的。

  在一个雇员采取计时工资制度的企业中,例如律师事务所或者咨询服务公司,更高效率的通讯可以显著提高办公效率,因此,部署企业语音应用毫无疑问是取胜的重要的条件。例如,Sage Research研究公司总裁Kathryn Korostoff引述的一项调查结果称,一半以上的接受调查的企业表示,由于增加使用了协作会议、统一消息和找人式的消息(find-me-style messaging)等电话功能,每个雇员每个星期的工作效率能够提高4个小时。在一个有100名雇员如此提高了办公效率的公司中,每年就可以获得2000个小时额外的生产率。一家律师事务所每年就可以重新获得2000个小时的工时,从而增加40万美元的收入(按照每小时200美元计算)。

  即使这种节省没有导致计时工资的小时数量的增加,它也会显著提高一个机构的效率,使这个机构更好地对用户做出反应和做出决策,并且能够更快地完成项目。在这些情况下,成本的合理性是以比较软的生产率节省为基础的,但是,这个好处仍然是很明显的。精明的机构认识到这方面是有可证明的好处的,这个好处就是可以消除这些无效率和实施企业语音解决方案以改善拖累这个机构的具体的商务流程。

  总之,在今后的几年里,你将会看到大多数机构部署语音应用。基于标准的硬件和软件的入门级解决方案的成本比较低是合理的,融合的网络的节省和生产率的提高很容易证明它的合理性。企业雇员很快就将把语音应用当成一种他们固有的权利,就像他们现在使用电话、PC和互联网一样。

  翻译:东缘


中文:http://searchnetworking.techtarget.com.cn/NetInformation/137/2463637.shtml
英文:http://searchvoip.techtarget.com/tip/1,289483,sid66_gci1195600,00.html

posted @ 2006-06-30 17:29 hopeshared 阅读(540) | 评论 (0)编辑 收藏

刚刚被一个比较麻烦的问题所困扰。这个问题就是如何判断数据中某张表是否存在,如果不存在则创建它。

恩,我先用了最笨的方法,就是写个select从表中读数据,捕获异常的同时就知道了改表没有创建。

此法不通,因为这个时候的异常似乎被认定为了系统错误,于是后面创建表的代码被忽略了。

大部分人的做法类似于select system.table where tabblename='***',反正我曾经用类似的句子查询过DB2,是成功的。

但是,我现在面对的不是DB2,而是7个不同的数据库,基本上常用的都包括了。是不是每类数据库都有上面的查询语句呢?是否查询语句相似呢?于是我挑了hsqldb,也是当前的默认数据库,来寻找解决办法。

很遗憾,我没有找到类似前面的句子。正当我打算放弃的时候发现了下面的代码,这段代码是我从一个国外的论坛中找到的,尽管我不知道它是不是万能钥匙,但是他这次对我而言确成了万能的:

java.sql.Connection con = getYourConnection();
   
ResultSet rs 
= con.getMetaData().getTables(nullnull"yourTable"null);
if (rs.next()) {
//yourTable exist
}
else {
//yourTable not exist
}

 

posted @ 2006-06-28 17:12 hopeshared 阅读(3016) | 评论 (3)编辑 收藏

仅列出标题
共30页: First 上一页 6 7 8 9 10 11 12 13 14 下一页 Last