2007年10月14日

在进行项目开发时,遇到一些ORACLE的问题,现在提供一些解决方法,希望能给大家一点帮助
1.问题描述: 当对某个表的数据进行插入或更新等DML命令操作时,数据库出现如下异常信息:
  ORA-12096: error in materialized view log on "DB_XTWH"."T_XT_DBUSERPOOLBPOL"
  ORA-00942: table or view does not exist
    解决方法:出现这个问题的原因是物化视图日志出了问题,只要删除该物化视图日志就解决问题,删除命令为:
  drop materialized view log on 用户名.表名;
  drop materialized view log on DB_XTWH.T_XT_DBUSERPOOLBPOL;
2.问题描述:当通过DBLINK操作其中的一张表时,总是提示ORA-02085:database link SKSKJ connects to SKSKJ.US.ORACLE.COM错误信息,而名为SKSKJ的DBLINK配置是正确的。
    解决方法:把数据库的参数global_names设置为FALSE就解决问题了。
posted @ 2007-10-14 15:38 汤汤 阅读(352) | 评论 (0)编辑 收藏

2007年8月10日

[1]好好规划自己的路,不要跟着感觉走!根据个人的理想决策安排,绝大部分人并不指望成为什么院士或教授,而是希望活得滋润一些,爽一些。那么,就需要慎重安排自己的轨迹。从哪个行业入手,逐渐对该行业深入了解,不要频繁跳槽,特别是不要为了一点工资而转移阵地,从长远看,这点钱根本不算什么,当你对一个行业有那么几年的体会,以后钱根本不是问题。频繁地动荡不是上策,最后你对哪个行业都没有摸透,永远是新手!   
[2]可以做技术,切不可沉湎于技术。千万不可一门心思钻研技术!给自己很大压力,如果你的心思全部放在这上面,那么注定你将成为孔乙己一类的人物!适可而止为之,因为技术只不过是你今后前途的支柱之一,而且还不是最大的支柱,除非你只愿意到老还是个工程师!   
[3]不要去做技术高手,只去做综合素质高手!在企业里混,我们时常瞧不起某人,说他“什么都不懂,凭啥拿那么多钱,凭啥升官!”这是普遍的典型的工程师的迂腐之言。人家能上去必然有他的本事,而且是你没有的本事。你想想,老板搞经营那么多年,难道见识不如你这个新兵?人家或许善于管理,善于领会老板意图,善于部门协调等等。因此务必培养自己多方面的能力,包括管理,亲和力,察言观色能力,攻关能力等,要成为综合素质的高手,则前途无量,否则只能躲在角落看示波器!技术以外的技能才是更重要的本事!!从古到今,美国日本,一律如此!   
[4]多交社会三教九流的朋友!不要只和工程师交往,认为有共同语言,其实更重要的是和其他类人物交往,如果你希望有朝一日当老板或高层管理,那么你整日面对的就是这些人。了解他们的经历,思维习惯,爱好,学习他们处理问题的模式,了解社会各个角落的现象和问题,这是以后发展的巨大的本钱,没有这些以后就会笨手笨脚,跌跌撞撞,遇到重重困难,交不少学费,成功的概率大大降低!
[5]知识涉猎不一定专,但一定要广!多看看其他方面的书,金融,财会,进出口,税务,法律等等,为以后做一些积累,以后的用处会更大!会少交许多学费!!   
[6]抓住时机向技术管理或市场销售方面的转变!要想有前途就不能一直搞开发,适当时候要转变为管理或销售,前途会更大,以前搞技术也没有白搞,以后还用得着。搞管理可以培养自己的领导能力,搞销售可以培养自己的市场概念和思维,同时为自己以后发展积累庞大的人脉!应该说这才是前途的真正支柱!!!   
[7]逐渐克服自己的心里弱点和性格缺陷!多疑,敏感,天真(贬义,并不可爱),犹豫不决,胆怯,多虑,脸皮太薄,心不够黑,教条式思维。。。这些工程师普遍存在的性格弱点必须改变!很难吗?只在床上想一想当然不可能,去帮朋友守一个月地摊,包准有效果,去实践,而不要只想!不克服这些缺点,一切不可能,甚至连项目经理都当不好--尽管你可能技术不错!   
[8]工作的同时要为以后做准备!建立自己的工作环境!及早为自己配置一个工作环境,装备电脑,示波器(可以买个二手的),仿真器,编程器等,业余可以接点活,一方面接触市场,培养市场感觉,同时也积累资金,更重要的是准备自己的产品,咱搞技术的没有钱,只有技术,技术的代表不是学历和证书,而是产品,拿出象样的产品,就可技术转让或与人合作搞企业!先把东西准备好,等待机会,否则,有了机会也抓不住!   
[9]要学会善于推销自己!不仅要能干,还要能说,能写,善于利用一切机会推销自己,树立自己的品牌形象,很必要!要创造条件让别人了解自己,不然老板怎么知道你能干?外面的投资人怎么相信你?提早把自己推销出去,机会自然会来找你!搞个个人主页是个好注意!!特别是培养自己在行业的名气,有了名气,高薪机会自不在话下,更重要的是有合作的机会...   
[10]该出手时便出手!永远不可能有100%把握!!!条件差不多就要大胆去干,去闯出自己的事业,不要犹豫,不要彷徨,干了不一定成功,但至少为下一次冲击积累了经验,不干永远没出息,而且要干成必然要经历失败。不经历风雨,怎么见彩虹,没有人能随随便便成功!
posted @ 2007-08-10 22:26 汤汤 阅读(255) | 评论 (0)编辑 收藏

2007年6月13日

现有项目组用SUN JDK1.5中自带的示例:jnlp-servlet作为WEBSTART版本管理的SERVLET。它可以很好的实现JNLP相关资源(JAR,图片等)的基于版本的管理和增量更新。并有几个类似 $ $codebase, $ $name的可替换关键字。(原来写了一个简单的servlet,可以实现软编码,但没法提供灵活的版本控制)

但现有项目的需求更高一些,即,JNLP中需要传更多的参数,比如,服务端IP,端口,上下文,用户登录的SESSIONID等,由于jnlp-servlet有源代码,我们很快修改了JnlpFileHandler和specializeJnlpTemplate方法,并加入了这几个自定义关键字( $ $host, $ $port, $ $newcontext, $ $sessionid)。JNLP如下所示:

<?xml version="1.0" encoding="utf-8"?>

<jnlp spec="1.0 " codebase=" $ $codebase" href=” $ $name”>

<information>

<title>My System</title>

<vendor>CFR</vendor>

<icon href="indexbannerleft.jpg" kind="splash" />

<homepage href="index.html"/>

<description>My System</description>

<description kind="short">CFR Inc..</description>

</information>

<security><all-permissions/></security>

<resources>

<j2se version="1.4" initial-heap-size="32m"/>

<jar href="myapp.jar" version="1.1"/>

<nativelib href="swt-lib.jar" version="1.1"/>

</resources>

<resources os="Windows"><jar href="swt.jar" version="1.1"/></resources>

<resources os="Windows"><jar href="jface.jar" version="1.0"/></resources>

<resources os="Windows"><jar href="osgi.jar" version="1.0"/></resources>

<resources os="Windows"><jar href="runtime.jar" version="1.0"/></resources>

<application-desc main-class="com.cfr.app.main">

<argument> $ $session</argument>

<argument> $ $host</argument>

<argument> $ $port</argument>

<argument> $ $newcontext</argument>

<argument>0</argument>

<argument>aa</argument>

</application-desc>

</jnlp>

其中,SESSIONID是用其内部的request得到。

一切好象即简单和明了,工作正常,但很快就发现了严重的问题。

首先说说该应用的使用模式如下:

1、 用户从网页登录系统,然后在里面点击:http://host:port/myapp/swt/index.jnlp链接。

2、 启动应用(因为应用是跟当前登录SESSION直接相关的)

按照设计本意,此时,用户的应用应通过JNLP中的参数得到了该用户登录后的SESSIONID才对,但事实并非如此。这种情况只出现在WEBSTART第一次下载的时候,以后当用户重新打开浏览器登录后(此时当然是一个新的SESSION),在页面中启动WEBSTART后,发现,该SESSIONID还是以前的,并没有想象中的将新SESSIONID传了进来。

后来还是看看JnlpFileHandler中的源代码,发现主要在getJnlpFile(客户端是JRE1.5以下时调用)和getJnlpFileEx(客户端是JDK1.5以上时用)进行了相关实现。原来,它每生成一个JNLP,就将其缓存在HASHMAP中,下一次请求,如果请求的URL相关并且文件的timestamp(就是Web服务器中的jnlp文件的修改时间,可想而知,除了升级,这个文件一般不会变)一样,就从缓存中取,这样一来,我们也可以推测,按照上面的设计,如果有一个用户下载了应用,其它用户从其它机器下载到的JNLP还是第一个用户的JNLP,这是一个更加严重的问题。

由于URL是一样的,现在考虑更改时间戳,即在getJnlpFile中显式的将timesstamp改为当前的时间:

long lastModified = new java.util.Date().getTime();

这样,任何一次请求都不会从缓存中获得,而是重新生成一个,好象这能很好的解决这个问题了吧?

但事实远没有想象的那么简单。这跟WEBSTART与服务端的交互过程有关系。

WEBSTART要通过多次从服务端交互才会真正下载JNLP文件,这主要是验证一些时间等相关的属性(具体我没有看代码)。大至是三次才会真正的把JNLP下载下来(其实服务端会生成三次,真正下载的是第三个),由于我们的SESSIONID是从SERVLET内部的REQUEST中直接得到,这样一来,实际上只有第一个请求的SESSIONID是正确的(因为它是直接从浏览器中进入的),其它两个都是WEBSTART用URLConnection建立的连接,SESSIONID都是新生成的,而下载的恰恰又是第三个,这样一来,又黄了!!!

接下来的想法是自己设法传SESSIONID,而不是从当前REQUEST中取。所以,就刚才启动WEBSTART的链接改为如下形式:

<a href="/myapp/swt/index.jnlp?sessionid=<%=request.getSession().getId()%>">启动客户端程序</a>

这样,生成的URL会是:

http://localhost:8899/myapp/swt/index.jnlp?sessionid=F8864B2CDF60AE371CD6DFC189E80C78

按照前面的JNLP文件,下载下来的JNLP第一行是:

<jnlp spec="1.0 " codebase="http://127.0.0.1:8899/myapp/swt/" href=” http://localhost:8899/myapp/swt/index.jnlp?sessionid=F8864B2CDF60AE371CD6DFC189E80C78”>

既然有了SESSIONID(这意味着每个请求的URL都不会一样!),我们就用不着将时间戳改为当前时间了,还按原来的做就行了。

到此为止,好像问题解决的很彻底哦!但不要高兴的太早!!!!!

我们同样做实验:

1、 将WEBSTART应用清空

2、 登录系统,下载安装应用并运行,一切OK!

3、 退出该系统

4、 打开新的浏览器并登录

5、 点相应的链接启动WEBSTART应用

6、 怪了:SESSIONID怎么还是前面的一个呢?

 查看jnlp-servlet日志,刚才说了,要经过多次握手才会实际的下载JNLP,从流程中发现,客户端发的请求,第一个是对的即是http://localhost:8899/myapp/swt/index.jnlp?sessionid=F8864B2CDF60AE371CD6DFC189E80C78

 SESSION是最新的,但第二个请求,SESSION怎么就是以前的呢?

原来,WEBSTART在经过第一次握手之后,发现本地有该应用,就用该应用JNLP中的href字段发送下面的请求,导致了刚才的问题。

后面的解决办法说起来就没什么了,直接去掉href字段就行了,如下片段:

<?xml version="1.0" encoding="utf-8"?>

<jnlp spec="1.0 " codebase=" $ $codebase">

这样,每次都用新的URL去请求了!!

说来说去,只是过程,其它代码中改得并不多,主要是增加了SESSION参数。

在以后动态更改应用的MAIN类时,思路也差不多。

其它人需地做的改动:

更改JNLP,去掉href项

换成新的jnlp_servlet

清除当前已安装的应用。

将链接改为有SESSIONID为参数的链接。

转载:文章来自于http://java.linuxjiaocheng.com/applet-api/sdk-tutorial/xml-jsp-programming2601.html
posted @ 2007-06-13 19:05 汤汤 阅读(762) | 评论 (0)编辑 收藏

2007年6月11日

LDAP介绍 4
1.1. LDAP是什么 4
1.2. LDAP是电话簿 4
1.3. LDAP是不是数据库 4

2. LDAP的特点 5
2.1. LDAP的优势 5
2.1.1 跨平台 5
2.1.2 费用及维护 5
2.1.3 复制技术 5
2.1.4 允许使用ACI 5
2.2. LDAP存储什么数据 6
2.3. 什么时候该用LDAP存储数据 6
3. LDAP的基本模型 7
3.1 信息模型:描述LDAP的信息表示方式 7
3.2 命名模型:描述LDAP中的数据如何组织 7
3.3 功能模型:描述LDAP中的数据操作访问 7
3.4 安全模型:描述LDAP中的安全机制 8
3.4.1 身份认证 8
3.4.2 通讯安全 8
3.4.3 访问控制 8


4. LDAP数据结构 9
4.1 树状组织 9
4.2 条目和条目认证 9
4.3 数据样式(schema) 9
4.4 对象类型(objectClass) 9
4.5 过滤器和语法 10
4.6 树移植 10
4.7 LDIF交换文件 10
4.8 JAVA或CORBA对象串行化存储 10


1.1. LDAP是什么
LDAP是轻量目录访问协议,英文全称是Lightweight Directory Access Protocol,一般都简称为LDAP。它是基于X.500标准的,但是简单多了并且可以根据需要定制。与X.500不同,LDAP支持TCP/IP,这对访问Internet是必须的。LDAP的核心规范在RFC中都有定义,所有与LDAP相关的RFC都可以在LDAPman RFC网页中找到。
简单说来,LDAP是一个得到关于人或者资源的集中、静态数据的快速方式。
LDAP是一个用来发布目录信息到许多不同资源的协议。通常它都作为一个集中的地址本使用,不过根据组织者的需要,它可以做得更加强大。
1.2. LDAP是电话簿
LDAP其实是一电话簿,类似于我们所使用诸如NIS(Network Information Service)、DNS (Domain Name Service)等网络目录,也类似于你在花园中所看到的树木。
1.3. LDAP是不是数据库
不少LDAP开发人员喜欢把LDAP与关系数据库相比,认为是另一种的存贮方式,然后在读性能上进行比较。实际上,这种对比的基础是错误的。LDAP和关系数据库是两种不同层次的概念,后者是存贮方式(同一层次如网格数据库,对象数据库),前者是存贮模式和访问协议。LDAP是一个比关系数据库抽象层次更高的存贮概念,与关系数据库的查询语言SQL属同一级别。LDAP最基本的形式是一个连接数据库的标准方式。该数据库为读查询作了优化。因此它可以很快地得到查询结果,不过在其它方面,例如更新,就慢得多。
从另一个意义上 LDAP是实现了指定的数据结构的存贮,它是一种特殊的数据库。但是LDAP和一般的数据库不同,明白这一点是很重要的。 LDAP对查询进行了优化,与写性能相比LDAP的读性能要优秀很多。
就象Sybase、Oracle、Informix或Microsoft的数据库管理系统(DBMS)是用于处理查询和更新关系型数据库那样,LDAP服务器也是用来处理查询和更新LDAP目录的。换句话来说LDAP目录也是一种类型的数据库,但不是关系型数据库。要特别注意的是,LDAP通常作为一个hierarchal数据库使用,而不是一个关系数据库。因此,它的结构用树来表示比用表格好。正因为这样,就不能用SQL语句了。
2. LDAP的特点
2.1. LDAP的优势
2.1.1 跨平台
LDAP最大的优势是:可以在任何计算机平台上,用很容易获得的而且数目不断增加的LDAP的客户端程序访问LDAP目录。而且也很容易定制应用程序为它加上LDAP的支持。
LDAP协议是跨平台的和标准的协议,因此应用程序就不用为LDAP目录放在什么样的服务器上操心了。实际上,LDAP得到了业界的广泛认可,因为它是Internet的标准。产商都很愿意在产品中加入对LDAP的支持,因为他们根本不用考虑另一端(客户端或服务端)是怎么样的。LDAP服务器可以是任何一个开发源代码或商用的LDAP目录服务器(或者还可能是具有LDAP界面的关系型数据库),因为可以用同样的协议、客户端连接软件包和查询命令与LDAP服务器进行交互。与LDAP不同的是,如果软件产商想在软件产品中集成对DBMS的支持,那么通常都要对每一个数据库服务器单独定制。
2.1.2 费用及维护
不象很多商用的关系型数据库,你不必为LDAP的每一个客户端连接或许可协议付费。
大多数的LDAP服务器安装起来很简单,也容易维护和优化。
2.1.3 复制技术
LDAP服务器可以用"推"或"拉"的方法复制部分或全部数据,例如:可以把数据"推"到远程的办公室,以增加数据的安全性。复制技术是内置在LDAP服务器中的而且很容易配置。如果要在DBMS中使用相同的复制功能,数据库产商就会要你支付额外的费用,而且也很难管理。
2.1.4 允许使用ACI
LDAP允许你根据需要使用ACI(一般都称为ACL或者访问控制列表)控制对数据读和写的权限。例如,设备管理员可以有权改变员工的工作地点和办公室号码,但是不允许改变记录中其它的域。ACI可以根据谁访问数据、访问什么数据、数据存在什么地方以及其它对数据进行访问控制。因为这些都是由LDAP目录服务器完成的,所以不用担心在客户端的应用程序上是否要进行安全检查。
2.2. LDAP存储什么数据
LDAP对于这样存储这样的信息最为有用:也就是数据需要从不同的地点读取,但是不需要经常更新。例如,这些信息存储在LDAP目录中是十分有效的:
l 公司员工的电话号码簿和组织结构图
l 客户的联系信息
l 计算机管理需要的信息,包括NIS映射、email假名,等等
l 软件包的配置信息
l 公用证书和安全密匙
2.3. 什么时候该用LDAP存储数据
大多数的LDAP服务器都为读密集型的操作进行专门的优化。因此,当从LDAP服务器中读取数据的时候会比从专门为OLTP优化的关系型数据库中读取数据快一个数量级。也是因为专门为读的性能进行优化,大多数的LDAP目录服务器并不适合存储需要需要经常改变的数据。例如,用LDAP服务器来存储电话号码是一个很好的选择,但是它不能作为电子商务站点的数据库服务器。
如果下面每一个问题的答案都是"是",那么把数据存在LDAP中就是一个好主意。
l 需要在任何平台上都能读取数据吗?
l 每一个单独的记录项是不是每一天都只有很少的改变?
l 可以把数据存在平面数据库(flat database)而不是关系型数据库中吗?换句话来说,也就是不管什么范式不范式的,把所有东西都存在一个记录中(差不多只要满足第一范式)。
最后一个问题可能会唬住一些人,其实用平面数据库去存储一些关系型的数据也是很一般的。例如,一条公司员工的记录就可以包含经理的登录名。用LDAP来存储这类信息是很方便的。一个简单的判断方法:如果可以把保数据存在一张张的卡片里,就可以很容易地把它存在LDAP目录里。
3. LDAP的基本模型
3.1 信息模型:描述LDAP的信息表示方式
在LDAP中信息以树状方式组织,在树状信息中的基本数据单元是条目,而每个条目由属性构成,属性中存储有属性值;LDAP中的信息模式,类似于面向对象的概念,在LDAP中每个条目必须属于某个或多个对象类(Object Class),每个Object Class由多个属性类型组成,每个属性类型有所对应的语法和匹配规则;对象类和属性类型的定义均可以使用继承的概念。每个条目创建时,必须定义所属的对象类,必须提供对象类中的必选属性类型的属性值,在LDAP中一个属性类型可以对应多个值。
在LDAP中把对象类、属性类型、语法和匹配规则统称为Schema,在LDAP中有许多系统对象类、属性类型、语法和匹配规则,这些系统Schema在LDAP标准中进行了规定,同时不同的应用领域也定义了自己的Schema,同时用户在应用时,也可以根据需要自定义Schema。这有些类似于XML,除了XML标准中的XML定义外,每个行业都有自己标准的DTD或DOM定义,用户也可以自扩展;也如同XML,在LDAP中也鼓励用户尽量使用标准的Schema,以增强信息的互联互通。
在Schema中最难理解的是匹配规则,这是LDAP中为了加快查询的速度,针对不同的数据类型,可以提供不同的匹配方法,如针对字符串类型的相等、模糊、大于小于均提供自己的匹配规则。
3.2 命名模型:描述LDAP中的数据如何组织
LDAP中的命名模型,也即LDAP中的条目定位方式。在LDAP中每个条目均有自己的DN和RDN。DN是该条目在整个树中的唯一名称标识,RDN是条目在父节点下的唯一名称标识,如同文件系统中,带路径的文件名就是DN,文件名就是RDN。
3.3 功能模型:描述LDAP中的数据操作访问
在LDAP中共有四类10种操作:查询类操作,如搜索、比较;更新类操作,如添加条目、删除条目、修改条目、修改条目名;认证类操作,如绑定、解绑定;其它操作,如放弃和扩展操作。除了扩展操作,另外9种是LDAP的标准操作;扩展操作是LDAP中为了增加新的功能,提供的一种标准的扩展框架,当前已经成为LDAP标准的扩展操作,有修改密码和StartTLS扩展,在新的RFC标准和草案中正在增加一些新的扩展操作,不同的LDAP厂商也均定义了自己的扩展操作。
3.4 安全模型:描述LDAP中的安全机制
LDAP中的安全模型主要通过身份认证、安全通道和访问控制来实现。
3.4.1 身份认证
在LDAP中提供三种认证机制,即匿名、基本认证和SASL(Simple Authentication and Secure Layer)认证。匿名认证即不对用户进行认证,该方法仅对完全公开的方式适用;基本认证均是通过用户名和密码进行身份识别,又分为简单密码和摘要密码认证;SASL认证即LDAP提供的在SSL和TLS安全通道基础上进行的身份认证,包括数字证书的认证。
3.4.2 通讯安全
在LDAP中提供了基于SSL/TLS的通讯安全保障。SSL/TLS是基于PKI信息安全技术,是目前Internet上广泛采用的安全服务。LDAP通过StartTLS方式启动TLS服务,可以提供通讯中的数据保密性、完整性保护;通过强制客户端证书认证的TLS服务,同时可以实现对客户端身份和服务器端身份的双向验证。
3.4.3 访问控制
虽然LDAP目前并无访问控制的标准,但从一些草案中或是事实上LDAP产品的访问控制情况,我们不难看出:LDAP访问控制异常的灵活和丰富,在LDAP中是基于访问控制策略语句来实现访问控制的,这不同于现有的关系型数据库系统和应用系统,它是通过基于访问控制列表来实现的,无论是基于组模式或角色模式,都摆脱不了这种限制。
在使用关系型数据库系统开发应用时,往往是通过几个固定的数据库用户名访问数据库。对于应用系统本身的访问控制,通常是需要建立专门的用户表,在应用系统内开发针对不同用户的访问控制授权代码,这样一旦访问控制策略变更时,往往需要代码进行变更。总之一句话,关系型数据库的应用中用户数据管理和数据库访问标识是分离的,复杂的数据访问控制需要通过应用来实现。
而对于LDAP,用户数据管理和访问标识是一体的,应用不需要关心访问控制的实现。这是由于在LDAP中的访问控制语句是基于策略语句来实现的,无论是访问控制的数据对象,还是访问控制的主体对象,均是与这些对象在树中的位置和对象本身的数据特征相关。
在LDAP中,可以把整个目录、目录的子树、制定条目、特定条目属性集或符合某过滤条件的条目作为控制对象进行授权;可以把特定用户、属于特定组或所有目录用户作为授权主体进行授权;最后,还可以定义对特定位置(例如IP地址或DNS名称)的访问权。


4. LDAP数据结构
LDAP是实现了指定的数据结构的存贮,它包括以下可以用关系数据库实现的结构要求:树状组织、条目认证、类型定义、许可树形记录拷贝。
4.1 树状组织
无论是X500还是LDAP都是采用树状方式进行记录。每一个树目录都有一个树根的入口条目,子记录全部是这一根条目的子孙。这是目录与关系数据类型最大的区别(关系数据库的应用结构也可实现树状记录)。因此,把目录看作是更高级的树状数据库也未尝不可,只不过除此外,它不能实现关系存贮的重要功能。
4.2 条目和条目认证
LDAP是以条目作为认证的根据。ROOT的权限认证与目录本身无关,但除此外所有条目的认证权限由条目本身的密码进行认证。LDAP可以配置成各种各样不同的父子条目权限继承方式。
每一个条目相当于一个单一的平面文本记录,由条目自身或指定的条目认证进行访问控制。因此,LDAP定义的存贮结构等同于一批树状组织的平面数据库,并提供相应的访问控制。
条目中的记录以名-值对的形式存在,每一个名值对必须由数据样式schema预定义。因此,LDAP可以看作是以规定的值类型以名值对形式存贮在一系列以树状组织的平面数据库的记录的集合。
4.3 数据样式(schema)
数据样式schema是针对不同的应用,由用户指定(设计)类和属性类型预定义,条目中的类(objectclass)和属性必须在在LDAP服务器启动时载入内存的schema已有定义。因此,AD活动目录中的条目记录就必须符合Active Directory的schema中。如果已提供的schema中的定义不够用,用户可以自行定义新的schema.
http://ldap.akbkhome.com/index.php中可以看到常用的schema。
4.4 对象类型(objectClass)
因为LDAP目录可以定制成存储任何文本或二进制数据,到底存什么要由你自己决定。LDAP目录用对象类型(objectclass)的概念来定义运行哪一类的对象使用什么属性。在几乎所有的LDAP服务器中,你都要根据自己的需要扩展基本的LDAP目录的功能,创建新的对象类型或者扩展现存的对象类型。
条目中的记录通过objectclass实现分类,objectClass是一个继承性的类定义,每一个类定义指定必须具备的属性。如某一条目指定必须符合某个类型,则它必须具备超类所指定的属性。
通过objectclass分类,分散的条目中的记录就实际上建立了一个索引结构,为高速的读查询打下了基础。Objectclass也是过滤器的主要查询对象。
4.5 过滤器和语法
LDAP是一个查询为主的记录结构,无论是何种查询方式,最终都由过滤器缺点查询的条件。过滤器相当于SQL中的WHERE子句。任何LDAP的类过滤和字符串都必须放在括号内,如(objectclass=*),指列出所有类型的记录(不过分类)。
可以使用=,>=,<=,~=(约等于)进行比较,如(number<=100)。合并条件是最怪的,必须把操作符放在两个操作对象的前面而不是中间,单一操作对象用括号括起来。如
l A与B,不是A&B,而是(&(A)(B))。
l 或使用"|"表示;
l 非使用"!"表示。
l 对于"与",或"或"在操作符后可以跟多个条件表达式,但非后则只参是单个表达式。
详见RFC1558。
4.6 树移植
LDAP最重要的特性和要求并不是读性能,而是扩展性。这一特性是通过树移植和树复制实现的。按LDAP的RFC要求,LDAP目录应该可以任意地在不同的目录间连接、合并并实现自动复制,及自动性同步。这意味着用户可以在任一LDAP中访问条目,而不用管其中某一部分是否复制自全世界另一目录中的记录,同时另一目录中的记录同样在正常运作。
这一特性如果在关系数据库中实现,意味着要使用程序化的非规范化预复制。类似于汇总帐目的设计。
4.7 LDIF交换文件
LDIF是LDAP约定的记录交换格式,以平面文本的形式存在,是大部分LDAP内容交换的基础,如拷贝、添加、修改等操作,都是基于LDIF文件进行操作。
4.8 JAVA或CORBA对象串行化存储
网络高效率的访问加上JAVA的跨平台能力,当把JAVA或CORBA对象串行化后存储到LDAP目录上时,可以产生非同一般的集成效果--实际上,这正是EJB和.NET的网络定位基础技术。
使用JAVA或CORBA对象存储时,必须首先让LDAP服务支持该对象定义,也就是说包含qmail.schema或corba.schema。
JAVA必须存储在objectclass=javacontainer的条目中,而且必须带有cn属性,这意味着除非该JAVA类专门实现了DirContext接口,对于大多数JAVA类来说,只能采用DirContext代替Context实现bind的添加操作。取出JAVA类相对要简单得多,只需使用context.lookup()获得该对象的句柄,然后强制造型成所需要的对象就可以了,如:
Person p=(Person)contex.lookup("cn=elvis,dc=daifu,dc=com");
这个句法在EJB的程序中,是经常用到的。
使用CORBA的跨语言性质,使用CORBA存储对象比JAVA更加诱人,这意味着所存储的对象可以被任何语言编写的客户端访问。其实,微软的.net说到底也非常简单,无非是把COM对象存储到微软自家的目录ActiveDirectory里面,从而可以在网络范围内使用任何微软平台的语言进行对象访问而已。众所周知,COM就是与CORBA相对的微软规范。
使用对象串行化技术,可以把常用对象如某个打印机,某个客户直接存储到LDAP中,然后快速获取该对象的引用,这样,就比把对象信息存储到关系数据库中,分别取出属性,然后再初始化对象操作的做法,效率要高得多了。这是LDAP目前比普通关系数据库存储要优秀的地方,而对象数据库还不成熟。



转载于http://blog.sina.com.cn/u/4b53d0b3010005lj
posted @ 2007-06-11 18:28 汤汤 阅读(455) | 评论 (0)编辑 收藏

2006年1月11日

方法一:
      1.关闭Eclipse,将插件的安装压缩文件解压缩到某个目录。
      2.打开Eclipse,点击主菜单的“帮助”→ “软件更新” →“管理配置”子菜单,打开产品配置对话框。选中Eclipse SDK单击右键选择“添加” →“扩展位置”了菜单。在打开的浏览文件对话框中,选择插件的安装文件目录。

方法二:

1.将插件的安装压缩文件解压缩到某个目录。

2.Eclipse的安装目录下建立一名为“links”的文件夹,然后在“links”文件夹下建立一件扩展名为“.links”的文件。文件的内容是:path=插件的安装压缩文件的位置。

注意:路径中的“\”换成“\\”,否则插件将不能成功安装。

备注:不同版本的插件需要安装在特定版本的Eclipse下。

 

posted @ 2006-01-11 14:43 汤汤 阅读(6633) | 评论 (0)编辑 收藏

2006年1月9日

JAVA中没有提供特定的文件拷贝方法,但可以通过文件输入输出流对文件进行逐字节拷贝。
而在编写代码时,要处理以下几个异常:
1.如果拷贝的源文件不存在。
2.源文件和目标文件的类型不同(也就是扩展名不同),将导致源文件和目标文件的内容不一致。
3.在读写文件时,可能会发生异常。

下面是一个自定的文件拷贝类的例子。

import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import javax.swing.JOptionPane;

/**
 *程  序:文件拷贝
 *文件名:FileCopy
 *平 台:windows 2000
 *编译器:JDK1.5.0
 *描 述:该类是抽象类,通过调用方法copy对两个同类型文件进行拷贝
 *   参 数:目标文件名,源文件名。
 **/


public abstract class FileCopy {

    /*拷贝文件*/
    public static boolean copy(String resultFile, final String sourceFile) {
        boolean isCopy = false;
        //判断目标文件名和源文件名类型是否相同(即扩展名是否相同)
        if (!isEqualsType(resultFile, sourceFile)) {
            JOptionPane.showMessageDialog(null, "目标文件和源文件的类型不同,不能拷贝!");
            return false;
        } else {
            //类型相同
            File readFile = new File(sourceFile);
            File writeFile = new File(resultFile);

            //判断源文件是否存在
            if (readFile.exists() && readFile.isFile()) {
                //如果目标文件已经存在,询问是否覆盖
                if (writeFile.exists()) {
                    int state = JOptionPane.showConfirmDialog(null,
                            "目标文件" + resultFile + "已经存在,是否覆盖?");
                    if (state != JOptionPane.YES_OPTION) {
                        return false;
                    }
                }
                FileInputStream readStream = null;
                FileOutputStream writeStream = null;
                try {
                    readStream = new FileInputStream(readFile);
                    writeStream = new FileOutputStream(writeFile);
                    while (readStream.available() > 0) {
                        int content = readStream.read();
                        writeStream.write(content);
                    }
                    JOptionPane.showMessageDialog(null, "文件拷贝成功!");
                    isCopy = true;
                } catch (IOException ioErr) {
                    JOptionPane.showMessageDialog(null, "源文件读取错误!请检查文件");
                } catch (Exception err) {
                    JOptionPane.showMessageDialog(null, "文件拷贝错误!请检查目标文件内容是否正确!");
                } finally {
                    try {
                        readStream.close();
                        writeStream.close();
                    } catch (IOException ioErr) {
                        isCopy = false;
                    }
                }
            }
            //不存在,则返回false
            else {
                JOptionPane.showMessageDialog(null, "源文件" + sourceFile + "不存在!");
            }
            return isCopy;
        }
    }

    /**
     *判断目标文件和源文件的类型是否相同
     *即判断扩展名是否相同
     **/
    private static boolean isEqualsType(String resultFile, String sourceFile) {
        int resultDot = resultFile.lastIndexOf('.');
        int sourceDot = sourceFile.lastIndexOf('.');
        String resultType = "";
        String sourceType = "";
        if (resultDot > 0) {
            resultType = resultFile.substring(resultDot + 1, resultFile.length());
        }
        if (sourceDot > 0) {
            sourceType = sourceFile.substring(sourceDot + 1, sourceFile.length());
        }
        return resultType.equals(sourceType);
    }

}

posted @ 2006-01-09 18:02 汤汤 阅读(1678) | 评论 (0)编辑 收藏
仅列出标题