两只青蛙相爱了,结婚后生了一个蛤嫫,公青蛙见状大怒说:贱人,怎么回事 母青蛙哭
着说:他爹,认识你之前我整过容。
小驴问老驴:为啥咱们天天吃干草,而奶牛顿顿精饲料 老驴叹到:咱爷们比不了,
我们是靠跑腿吃饭,人家是靠胸脯吃饭!
鸭子和螃蟹赛跑,一起到达终点,难分胜负,裁判说:你们来个剪刀石头布吧 鸭子大
怒:妈的,算计我?我一出是布,他总是剪刀。
狗对熊说:嫁给我吧,嫁给我你会幸福。熊说:才不嫁呢,嫁给你只会生狗熊,我要
嫁给猫,生熊猫那才尊贵呢!
老鳖调戏河蚌,被咬,老鳖忍痛拖着河蚌来回爬,青蛙见了敬佩的说:乖乖,鳖哥混
大了,出入都加着公文包。
蜜蜂狂追蝴蝶,蝴蝶却嫁给了蜗牛。蜜蜂不解:他哪里比我好 蝴蝶回答:人家好歹
有自己的房子,哪像你住在集体宿舍
Ping 探测是Windows系统中最常用的工具之一,它同时也是“网络流氓”寻找下手
目标的最常用的工具,当“网络流氓”一次发送的数据包大于或等于65532K时,系统
就很有可能死机,通过Ping 命令可以制造ICMP风暴,堵塞网络,所以Ping 命令对
于系统的危害不可小覤,那么我们在Windows 2000系统中,在没有防火墙保护的状态
下,如何屏蔽Ping探测,避免系统被“网络流氓”盯上呢?你可以通过以下方法来
实现。
步骤1 点击“网上邻居”,选择“属性”再指向要配置的“网卡”,再用右键选取
“属性”,再依次点“TCP/IP”->“高级”->“选项”->“TCP/IP筛选”。
步骤 2 接着在TCP端口编辑框中点击“只允许”,在下面加上需要开的端口,一般
打开80、20、21、25端口,应用于浏览网页,上传文件、收发邮件便行了。
步骤 3 编辑UDP端口,选择“全部不允许”,最右边的一个编辑框是定义IP协议过
滤的,我们选择只允许TCP协议通过,点“确定”关闭设置框。
上面设置了“只允许TCP协议通过”,只可惜微软在这里的IP协议过滤并不包括ICMP
协议 ,所以还需要在IP安全机制(IP Security)上着手。
步骤1 打开“本地安全策略”,选择“IP安全策略”,再指向“管理IP筛选器”,
在IP过滤规则:ICMP_ANY_IN,源地址选“任何IP ”,目标地址选“我的IP地址”(
本机),协议类型是“ICMP”,切换到“管理过滤器操作”,增加一个名为“Deny”
的操作,操作类型为“阻止”。
步骤2 接着再用右键选取本机的IP安全策略,选择“新建IP安全策略”,建立一个
名称为“ICMP Filter”的过滤器,通过增加过滤规则向导,我们把刚刚定义的
ICMP_ANY_IN过滤策略指定给“ICMP Filter”。
最后在操作选框中选择我们刚刚定义的Deny 操作,退出向导窗口,右击“ICMP
Filter”并启用它,现在任何地址进入的ICMP报文就都会被丢弃了。
在本地安全策略里启用新的过滤策略后,就会有一个关闭所有进入ICMP报文的过滤
策略和丢弃所有报文的过滤操作了。通过此番设置后,您就再也不用担心“网络流
氓”对系统进行骚扰了。
第二种方法:使用下面的软件。
Steganos Internet Anonym Pro 6
这是一套功能强大的网路身份隐藏工具软件,所以请使用在正当的防卫用途。我们
在网路上浏览网页或是下载各式各样的文件的同时,有成千上万的人使用监视用或
是入侵用的软件正在虎视眈眈的预备攻击我们,而这套软件就是用来防止如此攻击
或是窥视的工具软件,你可以透过这套软件很简单的隐藏自已的身份(ip)或是将我
们所经过的网站讯息、Cookkies、暂存文件都消除,所以你可以如有网路隐形人一
般的出入所有的网路,而不留痕迹
经过试用发现,自己的ip是1秒钟变化一次,哈哈,用显示ip的网站测试,我一会在
英国,一会儿在加拿大,真是好用啊!!
安装注意:安装后不要急于测试,先关闭所有的浏览器,然后重新打开。如果还没
有效果,那么重新启动,保证见效。
注册码:123-114-115-107-054
人要学会放弃,在落泪以前转身离去,留下简单的背影;
学会放弃,将昨天埋在心底,留下最美的回忆;
学会放弃,让彼此都能有个更轻松的开始,
遍体鳞伤的爱并不一定就刻骨铭心。
感情就像一条橡皮筋,你牵一头,我牵一头,
两人互相承诺永不分开。后来有一天,有一个人违背了承诺,
松开了手,伤得最深的是那个死拉着感情不放的人!
有时候希望得太多,反而会生出许多的烦恼。
其实,生活并不需要这些无谓的执著,
没有什么绝对不能割舍。
你要想生活得轻松,就要学会放弃。
谁说喜欢一样东西就一定要得到它。
有时候,有些人,为了得到他喜欢的东西,
殚精竭虑,费尽心机,更甚者可能会不择手段,
以至走向极端。
在漫长的人生旅途,我们每个人
都有可能遇到这样或那样的烦心的事
情,常言道:“人生不如意事十有八
九。”
在现实生活中,确实有许多事情令我们头疼:看见昔日与自己一同玩一同上学的“鼻涕王”,今天却驾着轿车来到你家里串门,还带着不知是同情还是讽刺的话说: “你怎么还住平房呀?”心中涌起的那种心酸与无奈;某同事出来工作才几年,但是懂得迎合领导的各种口味和需要,职位“步步高升”,而自己虽然埋头苦干地干了十年有余,成绩不凡,却被说成:“没有活力.不适应新时期的社会需要”的那种愤愤不平;自己少吃剑用.勒紧裤带子挨了半年,买来了一辆摩托车,却一不小被人偷走了的那种阵痛气愤......
这时,我们何不也采用换位思考来化解这种不如意呢?
别人天天以车代步,缺乏锻炼,而我天天步行去上班,身体
肯定比他强;当令导的应酬多.责任重.压力大,自己做一个
普普通通的小职员,踏踏实实做好本分工作,多舒坦.多惬意!
贼子只偷走了我的车子,还没有偷走我的全部,值得庆幸......
人是一种奇怪的动物,当心理不平衡的时,
会“死牛一边颈”,会因遭受了某个小小的挫折
或不公平待遇而做出得不偿失的事情来,甚致严
重的后果;但是当他向有利于自己的一面想时,
心中的那股强烈的怨气便会消解,进而心平气和
地处理问题,免去了一时冲动的过激行为。所以
当我们遇到挫折或不快时,不妨来点阿Q精神,
这也不失为一个好的缓冲办法。
换个角度,海阔天空!凡事都向有利于自己的一面想,保持乐观.豁达的心态,那么我们的生活就会变得和谐美好。
一个企业的开始意味着一个良好的信誉的开始。有了信誉,自然就会有财路,这是必须具备的商业道德。就像做人一样,要忠诚、有义气。对于自己每说出的一句话,做出的每一个承诺,一定要牢牢记在心里,并且一定要能够做到。
JDK 是整个Java的核心,包括了Java运行环境(Java Runtime Envirnment),一堆Java工具和Java基础的类库(rt.jar)。不论什么Java应用服务器实质都是内置了某个版本的JDK。因此掌握 JDK是学好Java的第一步。最主流的JDK是Sun公司发布的JDK,除了Sun之外,还有很多公司和组织都开发了自己的JDK,例如IBM公司开发的JDK,BEA公司的Jrocket,还有GNU组织开发的JDK等等。其中IBM的JDK包含的JVM(Java Virtual Machine)运行效率要比Sun JDK包含的JVM高出许多。而专门运行在x86平台的Jrocket在服务端运行效率也要比Sun JDK好很多。但不管怎么说,我们还是需要先把Sun JDK掌握好。
1、 JDK的下载和安装
JDK又叫做J2SE (Java2 SDK Standard Edition),可以从Sun的Java网站上下载到,http://java.sun.com/j2se/downloads.html。
下载好的JDK是一个可执行安装程序,默认安装完毕后会在C:\Program Files\Java\目录下安装一套JRE(供浏览器来使用),在C:\j2sdk1.4.2下安装一套JDK(也包括一套JRE)。然后我们需要在环境变量PATH的最前面增加java的路径C:\j2sdk1.4.2\bin。新建环境变量CLASSPATH,增加路径.;C:\j2sdk1.4.2\lib\dt.jar;C:\j2sdk1.4.2\lib\tools.jar。这样JDK就安装好了。
2、 JDK的命令工具
JDK的最重要命令行工具:
java: 启动JVM执行class
javac: Java编译器
jar: Java打包工具
javadoc: Java文档生成器
这些命令行必须要非常非常熟悉,对于每个参数都要很精通才行。对于这些命令的学习,JDK Documentation上有详细的文档。
二、 JDK Documentation
Documentation 在JDK的下载页面也有下载连接,建议同时下载Documentation。Documentation是最最重要的编程手册,涵盖了整个Java所有方面的内容的描述。可以这样说,学习Java编程,大部分时间都是花在看这个Documentation上面的。我是随身携带的,写Java代码的时候,随时查看,须臾不离手。
三、 Java应用的运行环境
Java的应用可以简单分为以下几个方面:
1、 Java的桌面应用
桌面应用一般仅仅需要JRE的支持就足够了。
2、 Java Web应用
Java的Web应用至少需要安装JDK和一个web容器(例如Tomcat),以及一个多用户数据库,Web应用至少分为三层:
Browser层:浏览器显示用户页面
Web层:运行Servlet/JSP
DB层:后端数据库,向Java程序提供数据访问服务
3、 Java企业级应用
企业级应用比较复杂,可以扩展到n层,最简单情况会分为4层:
Browser层:浏览器显示用户页面
Client层:Java客户端图形程序(或者嵌入式设备的程序)直接和Web层或者EJB层交互
Web层:运行Servlet/JSP
EJB层:运行EJB,完成业务逻辑运算
DB层:后端数据库,向Java程序提供数据访问服务
4、 Java嵌入式应用
Java嵌入式应用是一个方兴未艾的领域,从事嵌入式开发,需要从Sun下载J2ME开发包,J2ME包含了嵌入式设备专用虚拟机KVM,和普通的JDK中包含的JVM有所不同。另外还需要到特定的嵌入式厂商那里下载模拟器。
书籍篇
学习一门新的知识,不可能指望只看一本,或者两本书就能够完全掌握。需要有一个循序渐进的阅读过程。
很多人学习Java是从《Thinking in Java》这本书入手的,但是这本书是不适合初学者的。正确的使用这本书的方法应该是作为辅助的读物。《Thinking in Java》并不是在完整的介绍Java的整个体系,而是一种跳跃式的写作方法,是一种类似tips的方法来对Java很多知识点进行了深入的分析和解释。
对于初学者来说,最好是找一本Java入门的书籍,但是比较完整的循序的介绍Java的语法,面向对象的特性,核心类库等等,在看这本书的同时,可以同步来看《Thinking in Java》,来加深对Java的理解和原理的运用,同时又可以完整的了解Java的整个体系。
在所有的Java书籍当中,其实真正最最有用处是JDK的Documentation!几乎你想获得的所有的知识在Documentation 里面全部都有,其中最主要的部分当然是Java基础类库的API文档,是按照package来组织的,对于每一个class都有详细的解释,它的继承关系,是否实现了某个接口,通常用在哪些场合,还可以查到它所有的public的属性和方法,每个属性的解释,意义,每个方法的用途,调用的参数,参数的意义,返回值的类型,以及方法可能抛出的异常等等。可以这样来说,所有关于Java编程方面的书籍其实都不过是在用比较通俗易懂的语言,和良好的组织方式来介绍 Documentation里面的某个package里面包含的一些类的用法而已。所以万变不离其宗,如果你有足够的能力来直接通过 Documentation来学习Java的类库,那么基本上就不需要看其他的书籍了。除此之外,Documentation也是编程必备的手册。有了 Documentation,什么其他的书籍都不需要了。
过程篇
学习Java的第一步是安装好JDK,写一个Hello World程序。其实JDK的学习没有那么简单,关于JDK有两个问题是很容易一直困扰Java程序员的地方:一个是CLASSPATH的问题,其实从原理上来说,是要搞清楚JRE的ClassLoader是如何加载Class的;另一个问题是package和import问题,如何来寻找类的路径问题。把这两个问题摸索清楚了,就扫除了学习Java和使用JDK的最大障碍。
第二步是学习Java的语法。Java的语法是类C++的,基本上主流的编程语言不是类C,就是类C++的,没有什么新东西,所以语法的学习,大概就是半天的时间足够了。唯一需要注意的是有几个不容易搞清楚的关键字的用法,public,protected,private,static,什么时候用,为什么要用,怎么用,这可能需要有人来指点一下。《Thinking in Java》这本书上面是讲了这些概念的。
第三步是学习Java的面向对象的编程语言的特性的地方。比如继承,构造器,抽象类,接口,方法的多态,重载,覆盖,Java的异常处理机制。可以多看看《Thinking in Java》这本书,对面向对象的讲解非常透彻。
第四步就是开始熟悉Java的类库。Java的基础类库其实就是JDK安装目录下面jre\lib\rt.jar这个包。学习基础类库就是学习rt.jar。基础类库里面的类非常非常多。据说有3000多个。但是真正对于我们来说最核心的只有4个,分别是
java.lang.*;
java.io.*;
java.util.*;
java.sql.*;
这四个包的学习,每个包的学习都可以写成一本厚厚的教材。比较好的学习方法是这样的:
首先要通读整个package的框架,了解整个package的class,interface,exception的构成,最好是能够找到介绍整个包框架的文章。这些专门介绍包的书籍的前几章应该就是这些总体的框架内容介绍。
对包整体框架的把握并不是要熟悉每个类的用法,记住它有哪些属性,方法。想记也记不住的。而是要知道包有哪些方面的类构成的,这些类的用途是什么,最核心的几个类分别是完成什么功能的。你们要了解,Java给我们提供了哪些类,每个类是用在什么场合,当我遇到问题的时候,我知道哪个类,或者哪几个类的组合可以解决我的问题,That′s all!,当我们具体写程序的时候,只要你知道该用哪个类来完成你的工作就足够了。编码的时候,具体的方法调用,是边写代码,边查 Documentation,所有的东西都在Documentation里面,不要求你一定记住,实际你也记不住 3000多个类的总共将近10万个方法调用。所以对每个包的总体框架的把握就变得极为重要。
第五步,通过上面的学习,如果学的比较扎实的话,就打好了Java的基础了,剩下要做的工作是扫清Documentation里面除了上面4个包之外的其他一些比较有用处的类。相信进展到这一步,Java的自学能力已经被培养出来了,可以到了直接学习Documentation的水平了。除了要做GUI编程之外,JDK里面其他会有用处的包是这些:
java.text.*;
java.net.*;
javax.naming.*;
这些包里面真正用的比较多的类其实很少,只有几个,所以不需要花很多时间。
方法篇
Java 作为一门编程语言,最好的学习方法就是写代码。当你学习一个类以后,你就可以自己写个简单的例子程序来运行一下,看看有什么结果,然后再多调用几个类的方法,看看运行结果,这样非常直观的把类给学会了,而且记忆非常深刻。然后不应该满足把代码调通,你应该想想看如果我不这样写,换个方式,再试试行不行。记得哪个高人说过学习编程就是个破坏的过程,把书上的例子,自己学习Documentation编写的例子在运行通过以后,不断的尝试着用不同的方法实现,不断的尝试破坏代码的结构,看看它会有什么结果。通过这样的方式,你会很彻底的很精通的掌握Java。
举个例子,我们都编过Hello World程序:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
很多初学者不是很理解为什么main方法一定要这样来定义public static void main(String[] args),能不能不这样写?想知道答案吗?很简单,你把main改个名字运行一下,看看报什么错误,然后根据出错信息进行分析;把main的 public取掉,再试试看,报什么错误;static去掉还能不能运行;不知道main方法是否一定要传一个 String[]数组的,把String[]改掉,改成int[],或者String试试看;不知道是否必须写args参数名称的,也可以把args改成别的名字,看看运行结果如何。
虽然这样比较费时间,不过一个例子程序这样反复破坏几次之后。就对这个相关的知识彻底学通了。有时候甚至故意写一些错误的代码来运行,看看能否得到预期的运行错误。这样对于编程的掌握是及其深刻的。
另外,自己在学习过程中,写的很多的这种破坏例程,应该有意识的分门别类的保存下来,在工作中积累的典型例程也应该定期整理,日积月累,自己就有了一个代码库了。遇到类似的问题,到代码库里面 Copy & Paste ,Search & Replace,就好了,极大提高了开发速度。最理想的情况是把一些通用的例程自己再抽象一层,形成一个通用的类库,封装好。那么可复用性就更强了。
所以其实不是特别需要例程的,自己写的破坏例程就是最好的例子,如果你实在对自己写的代码不放心的话,强烈推荐你看看JDK基础类库的Java 源代码。在JDK安装目录下面会有一个src.zip,解开来就可以完整的看到整个JDK基础类库,也就是rt.jar的Java源代码,你可以参考一下 Sun是怎么写Java程序的,规范是什么样子的。打开相应的类的源代码,通过看源代码,所有的问题都会一扫而空。
资源篇
1、 http://java.sun.com/ ;(英文)
Sun的Java网站,是一个应该经常去看的地方。不用多说。
2、 http://www-900.ibm.com/developerWorks/cn/ ;
IBM的developerWorks网站,英语好的直接去英文主站点看。这里不但是一个极好的面向对象的分析设计网站,也是Web Services,Java,Linux极好的网站。强烈推荐!!!
3、 http://www.java-cn.com/ ;(中文)
JAVA 中文站,目前国内资料最全、会员最多的JAVA技术网站,人气极高。有《JAVA电子书库》、《JAVA视频库》(国内唯一)、《JAVA技术文摘库》、《JAVA源代码库》、《JAVA工具库》、《招聘求职广场》等主要栏目,还有一些专家栏目。目前会员有5万多,VIP会员近1000人。无论是菜鸟还是老鸟,都能在此网站中找到自己所需要的东东!! 最强烈推荐!!!!!!
4、 http://www.javaworld.com/ ;(英文)
关于Java很多新技术的讨论和新闻。想多了解Java的方方面面的应用,这里比较好。
11、 http://sourceforge.net/ ;
SourgeForge是一个开放源代码软件的大本营,其中也有非常非常丰富的Java的开放源代码的著名的软件。
第二级:高人,有天赋,技术过人但没有过人的商业头脑,通常此类人不是顶尖黑客就是技术总监之流。
第三级:牛人,技术精湛,熟悉行业知识,敢于创新,有自己的公司和软件产品。
第四级:工头,技术精湛,有领导团队的能力,此类人大公司项目经理居多。
第五级:技术工人,技术精湛,熟悉行业知识但领导能力欠加,此类人大多为系分人员或资深程序员,基本上桀骜不逊,自视清高,不愿于一般技术人员为伍,在论坛上基本以高手面目出现。
第六级:熟练工人,技术有广度无深度,喜欢钻研但浅尝辄止。此类人大多为老程序员,其中一部分喜欢利用工具去查找网上有漏洞的服务器,干点坏事以获取成绩感。如果心情好,在论坛上他们会回答菜鸟的大部分问题。此级别为软件业苦力的重要组成部分。
第七级:工人,某些技术较熟练但缺乏深度和广度,此类人大多为程序员级别,经常在论坛上提问偶尔也回答菜鸟的问题。为软件产业苦力的主要组成部分。
第八级:菜鸟,入门时间不长,在论坛上会反复提问很初级的问题,有一种唐僧的精神。虽然招人烦但基本很可爱。只要认真钻研,一两年后就能升级到上一层。
第九级:大忽悠,利用中国教育的弊病,顶着一顶高学历的帽子,在小公司里混个软件部经理,设计不行,代码不行,只会胡乱支配下属,拍领导马屁,在领导面前胡吹海侃,把自己打扮成技术高手的模样。把勾心斗角的办公室文化引入技术部门,实在龌龊!
第十级:驴或傻X,会写SELECT语句就说自己精通ORALCE,连寄存器有几种都不知道就说自己懂汇编,建议全部送到日本当IT产业工人,挣了日本人的钱还严重打击日本的软件业!
其中又以前两级和后两级最为难得,其余级别只要努力,皆有可能达到。
同学们,这是我写的一个计算器的源代码,希望可以给你们以启迪。
另外,这仅仅是一个参考,还有很大的提升空间,具体怎么提升请自己仔细思考后把它改写出来,用EMAIL的形式发给我。
一个优秀的程序员就是通过不断的读别人写的经典代码,重写别人的代码(相当于小学时候默写课文那样),然后修改和优化别人的代码,并能凭自己的能力独立(也就是说,不拘泥于别人的思想和套路,而非不跟别人协作,一个懂得协作并非常默契的团队才是程序员发挥自己个人能力的天堂,个人英雄主义是不适用于程序开发的)写出自己的优秀代码。
好了,不罗嗦了,自己研究代码吧:
Calculator.java
//用于算术运算的抽象类,由ComputeCalculator类进行继承
public abstract class Calculator {
public Calculator() {
}
public abstract void add(); //加法方法
public abstract void minus(); //减法方法
public abstract void multiply(); //乘法方法
public abstract void divide(); //除法方法
public abstract void paramPass(char param); //算术符号
}
ComputeCalculator.java
//Calculator的子类,用于实现具体算法
public class ComputeCalculator extends Calculator {
public double ary0; //定义一个变量用于第一个参数
public double ary2; //定义一个变量用于第二个参数
public char ary1; //定义一个变量用于运算符号
public ComputeCalculator(double DoubleNum1, double DoubleNum2) {
this.ary0 = DoubleNum1;
this.ary2 = DoubleNum2;
}
public void paramPass(char param) {
this.ary1 = param;
switch (ary1) { //运算符号合法性的判断,如果合法则进行相应的运算
case '+': //加法运算
add();
break;
case '-': //减法运算
minus();
break;
case '@': //乘法运算
multiply();
break;
case '/': //除法运算
divide();
break;
default: //运算符号不合法
System.out.println("您输入的运算符号错误,请将第二个参数改为+、-、@、/四种运算符号中的一种!");
}
}
public void add() { //加法运算方法
System.out.println("计算结果为:" + ary0 + " + " + ary2 + " = " +
(ary0 + ary2));
}
public void minus() { //减法运算方法
System.out.println("计算结果为:" + ary0 + " - " + ary2 + " = " +
(ary0 - ary2));
}
public void multiply() { //乘法运算方法
System.out.println("计算结果为:" + ary0 + " * " + ary2 + " = " +
(ary0 * ary2));
}
public void divide() { //除法运算方法
if (ary2 == 0) { //除数为0的情况
System.out.println("被除数为0,无法进行计算");
} else { //正常的除法运算
System.out.println("计算结果为:" + ary0 + " / " + ary2 + " = " +
(ary0 / ary2));
}
}
}
Js.java
//main()方法所在类,程序入口点,也是对前面两个类的调用和逻辑处理
public class Js {
public Js() {
}
public static void main(String[] args) {
try { //异常处理
double a; //定义一个变量用于接收第一个参数
double c; //定义一个变量用于接收第三个参数
char ch[] = (args[1]).toCharArray(); //定义一个变量用于接收第二个参数
Calculator compute ; //调用类,以进行计算
a = Double.parseDouble(args[0]); //接收第一个参数,并进行数据类型转换
if (a >= Double.MIN_VALUE && a <= Double.MAX_VALUE) { //判断参数内容是否合法
c = Double.parseDouble(args[2]); //接受第三个参数,并进行数据类型转换
if (c >= Double.MIN_VALUE && c <= Double.MAX_VALUE) { //判断参数内容是否合法
compute = new ComputeCalculator(a, c);
compute.paramPass(ch[0]); //对第二个参数进行合法性判断
} else { //如果第三个参数不合法,则提示错误
System.out.println("您输入的格式错误,请将第三个参数改为阿拉伯数字");
}
} else { //如果第一个参数不合法,则提示错误
System.out.println("您输入的格式错误,请将第一个参数改为阿拉伯数字");
}
} catch (Exception e) { //处理异常
System.out.println("第1个参数应该为0到9之间的阿拉伯数字");
System.out.println("第2个参数应该为运算符号(+、-、@、/)");
System.out.println("第3个参数应该为0到9之间的阿拉伯数字");
System.out.println("请重新输入数据并计算");
}
}
}
/*转贴请保留以下信息*/
作者:张杰
URL:http://spaces.msn.com/members/newbdez33/
http://www.phpboom.com/
由于工作需要,需要使用PHP实现对网站内大量数量进行全文检索,
而且目前最流行的全文检索的搜索引擎库就是Lucene了,
它是Apache Jakarta的一个子项目,并且提供了简单实用的API,
用这些API,就可以对任何基本文本的数据(包括数据库)进行全文检索。
因为PHP本身就支持调用外部Java类,所以先用Java写了一个类,
这个类通过调用Lucene的API,实现了两个方法:
* public String createIndex(String indexDir_path,String dataDir_path)
* public String searchword(String ss,String index_path)
其中createIndex是创建索引方法,
传入了两个参数分别是indexDir_path(索引文件的目录),dataDir_path(被索引的文件目录),返回被索引的文件列表字符串,
另一个是searchword,通过传入的关键字参数(ss)对索引进行检索,index_path就是索引文件的目录。返回所有检索到的文件。
这里是源代码,很简单,大家可以参考一下:TxtFileIndexer.java
而PHP程序就调用这两个方法,实现对Lucene的调用,从而达到全文检索的目的。
PHP的调用方法如下:
先创建一个我们写的TxtFileIndexer类的实例,
$tf = new Java('TestLucene.TxtFileIndexer');
然后就按正常PHP类的调用方法的方式进行调用,首先创建索引:
$data_path = "F:/test/php_lucene/htdocs/data/manual"; //定义被索引内容的目录
$index_path = "F:/test/php_lucene/htdocs/data/search"; //定义生成的索引文件存放目录
$s = $tf->createIndex($index_path,$data_path); //调用Java类的方法
print $s; //打印返回的结果
这次再试试检索:
$index_path = "F:/test/php_lucene/htdocs/data/search"; //定义生成的索引文件存放目录
$s = $tf->searchword("here is keyword for search",$index_path);
print $s;
另外要注意Java类的路径,可以在PHP里设置
java_require("F:/test/php_lucene/htdocs/lib/"); //这是个例子,我的类和Lucene都放到这个目录下
这样就可以了,是不是很简单。
PHP源代码:test.php
接下来我把环境配置说一下,
首先需要有Java SDK,是必须的,我使用的是1.4.2版的,其它版本应该也没问题。
PHP5,试过PHP4,应该可以。
由于PHP5带的Java扩展没调通,并且以前用过调用Java效率很低,很慢,所以使用了 Php/Java Bridge 这个项目。
1.下载JavaBridge
URL:http://sourceforge.net/projects/php-java-bridge/
目前版本是
php-java-bridge_3.0.8_j2ee.zip
解包后把
JavaBridge\WEB-INF\cgi\java-x86-windows.dll
JavaBridge\WEB-INF\lib\JavaBridge.jar
复制到 c:\php\ext 目录下,并把
java-x86-windows.dll 改名为 php_java.dll
2.修改php.ini(例)
extension=php_java.dll
[Java]
java.class.path = "C:\php\ext\JavaBridge.jar;F:\test\php_lucene\htdocs"
java.java_home = "C:\j2sdk1.4.2_10"
java.library.path = "c:\php\ext;F:\test\php_lucene\htdocs"
3.重启Apache即可。
4.可以找一些文件进行索引
在test.php里可以修改索引文件和数据文件的路径。
TxtFileIndexer.java的37行限制了只索引html后缀的文件,有需要也可以修改。
根据目前的情况(JavaBridge支持Linux和Freebsd),完全可以在
linux或freebsd/apache2/php4/lucene/JavaBridge
环境下运行。
本文章可能会随时更新,另外这里可以访问:
用PHP调用Lucene包来实现全文检索
我的MSN是 z33
欢迎技术探讨:)
package test;
public class Vector{
public Vector(){
System.out.println(
"my.Vector");
}
}
在C:\DOC下有一个TEST目录,生成Vector.class 。Vector.java和Vector.class都置于TEST
目录内。
然后我再编译下面的语句:
import test.*;
public class LibTest{
public static void main(String[] args){
Vector v=new Vector();
}
}
则出现如现错误:
C:\DOC\TEST javac LibTest.java
LibTest.java:5: cannot access Vector
bad class file: .\Vector.class
class file contains wrong class: test.Vector
Please remove or make sure it appears in the correct subdirectory of the classpa
th.
Vector l=new Vector();
^
1 error
然而我把import test.*;改为import.Vector;则能成功编译。望各位大虾帮忙解决。
在CLASSPATH中加上.;.代表当前目录,如果不加,编译器在编译LibTest.java时,找test包就不会在当前目录内找,因为找不到,加上就可以了。
加上也不行啊。早就加了。就是不行。
classpath=.;C:\DOC
本人解决方法:
注意目录结构
作为package, test.java 应放C;\doc\test目录中
Libtest.java放在c:\doc下,
classpath设为".;c:\doc\;"
然后
1. c:\doc>javac test\*.java
2. c:\doc>javac *.java
3. c:\doc>java Libtest //ok
D:\Javawork\jt>javac LibTest.java
LibTest.java:4: cannot access Vector
bad class file: .\Vector.java
file does not contain class Vector
Please remove or make sure it appears in the correct subdirectory of the classpa
th.
Vector v = new Vector();
^
1 error
(你的文件没有问题,主要是你的classpath里面有了test目录的java文件。。。)
出现这个问题,你要注意各个文件放的目录,千万不要在不同的目录里面里面有重复的文件。。。。
千万要注意编译顺序啊。。。
不知道说清楚了没有。。。。。要是看到我操作就好了。,。
testme.html
code:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />
<title>
ajax
</title>
<script language="javascript">
function createRequest(){
if(typeof XMLHttpRequest!="undefined") {
return new XMLHttpRequest();
}else if(typeof ActiveXObject!="undefined"){
var xmlHttp_ver = false;
var xmlHttp_vers = ["MSXML2.XmlHttp.5.0","MSXML2.XmlHttp.4.0","MSXML2.XmlHttp.3.0","MSXML2.XmlHttp","Microsoft.XmlHttp"];
if(!xmlHttp_ver){
for(var i=0;i<xmlHttp_vers.length;i++){
try{
new ActiveXObject(xmlHttp_vers[i]);
xmlHttp_ver = xmlHttp_vers[i];
break;
}catch(oError){;}
}
}
if(xmlHttp_ver){
return new ActiveXObject(xmlHttp_ver);
}else{
throw new Error("Could not create XML HTTP Request.");
}
}else{
throw new Error("Your browser doesn't support an XML HTTP Request.");
}
}
var xmlHttp;
function sendPostRequest()
{
xmlHttp = createRequest();
var shownum=document.getElementById("shownum").value;// html页面中一个id为shownum的input表单
var url = "http://localhost/phpwork/phpajaxtest.php";//要发送到的URL
var queryString = "shownum" + "=" + shownum;
//向服务端发送请求
xmlHttp.open("post", url, true);//这里的第三个参数为true为异步方式处理
xmlHttp.onreadystatechange = showData;//异步方式处理,当状态改变时会调用onreadystatechange属性指定的回调函数showData
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");//这一句是用post方法发送的时候必须写的
xmlHttp.send(queryString);//发送你构建成的数据,如果为“get”方法时,这里可以写成xmlHttp.send(NULL);
}
function showData()
{
var msg=document.getElementById("status");
//第4步
if(xmlHttp.readyState==4)
{
if(xmlHttp.status==200)
{
//只有当readyState为4并且status为200时,才表示符合要求
//下面这一句话,就相当于上面说的第5步,处理返回的结果
msg.innerHTML = xmlHttp.responseText;
}
}
else
{
switch(xmlHttp.readyState)
{
case 0:
msg.innerHTML="未初始化...";
break;
case 1:
msg.innerHTML="加载中...";
break;
case 2:
msg.innerHTML="连接完成...";
break;
case 3:
msg.innerHTML="交换数据...";
break;
default:
break;
}
}
}
</script>
</head>
<body>
<div>要发送的数据:<input name="shownum" type="text" id="shownum" value="root">
<input type="button" name="search" value="发送" onClick="sendPostRequest()">
(输入root,xdy108)</div>
<div id="status"></div>
</body>
</html>
phpajaxtest.php
code:
<?php require_once('Connections/conn.php'); ?>
<?php
$colname_Recordset1 = "-1";
if (isset($_POST['shownum'])) {
$colname_Recordset1 = (get_magic_quotes_gpc()) ? $_POST['shownum'] : addslashes($_POST['shownum']);
}
mysql_select_db($database_conn, $conn);
$query_Recordset1 = sprintf("SELECT `Host`, `User`, Password, Select_priv FROM `user` WHERE `User` = '%s'", $colname_Recordset1);
$Recordset1 = mysql_query($query_Recordset1, $conn) or die(mysql_error());
$row_Recordset1 = mysql_fetch_assoc($Recordset1);
$totalRows_Recordset1 = mysql_num_rows($Recordset1);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>无标题文档</title>
</head>
<body>
<table border="1">
<tr>
<td>Host</td>
<td>User</td>
<td>Password</td>
<td>Select_priv</td>
</tr>
<?php do { ?>
<tr>
<td><?php echo $row_Recordset1['Host']; ?></td>
<td><?php echo $row_Recordset1['User']; ?></td>
<td><?php echo $row_Recordset1['Password']; ?></td>
<td><?php echo $row_Recordset1['Select_priv']; ?></td>
</tr>
<?php } while ($row_Recordset1 = mysql_fetch_assoc($Recordset1)); ?>
</table>
</body>
</html>
<?php
mysql_free_result($Recordset1);
?>
conn.php
code:
<?php
# FileName="Connection_php_mysql.htm"
# Type="MYSQL"
# HTTP="true"
$hostname_conn = "localhost";
$database_conn = "mysql";
$username_conn = "root";
$password_conn = "12345";
$conn = mysql_pconnect($hostname_conn, $username_conn, $password_conn) or trigger_error(mysql_error(),E_USER_ERROR);
?>
user.sql
code:
# phpMyAdmin SQL Dump
# version 2.5.7
# http://www.phpmyadmin.net
#
# 主机: localhost
# 生成日期: 2006 年 12 月 13 日 05:58
# 服务器版本: 5.0.19
# PHP 版本: 5.1.2
#
# 数据库 : `mysql`
#
# --------------------------------------------------------
#
# 表的结构 `user`
#
CREATE TABLE `user` (
`Host` char(60) collate utf8_bin NOT NULL default '',
`User` char(16) collate utf8_bin NOT NULL default '',
`Password` char(41) character set latin1 collate latin1_bin NOT NULL default '',
`Select_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Insert_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Update_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Delete_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Create_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Drop_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Reload_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Shutdown_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Process_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`File_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Grant_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`References_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Index_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Alter_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Show_db_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Super_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Create_tmp_table_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Lock_tables_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Execute_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Repl_slave_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Repl_client_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Create_view_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Show_view_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Create_routine_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Alter_routine_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Create_user_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`ssl_type` enum('','ANY','X509','SPECIFIED') character set utf8 NOT NULL default '',
`ssl_cipher` blob NOT NULL,
`x509_issuer` blob NOT NULL,
`x509_subject` blob NOT NULL,
`max_questions` int(11) unsigned NOT NULL default '0',
`max_updates` int(11) unsigned NOT NULL default '0',
`max_connections` int(11) unsigned NOT NULL default '0',
`max_user_connections` int(11) unsigned NOT NULL default '0',
PRIMARY KEY (`Host`,`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges';
#
# 导出表中的数据 `user`
#
INSERT INTO `user` VALUES ('localhost', 'root', '*00A51F3F48415C7D4E8908980D443C29C69B60C9', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', '', '', '', '', 0, 0, 0, 0);
INSERT INTO `user` VALUES ('localhost', 'xdy108', '001002', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', '', '', '', '', 0, 0, 0, 0);
发现输入xdy108,root的时候能无刷新返回,否则如xdy,ro等就会无返回结果,其原因是用了:WHERE `User` = '%s'", $colname_Recordset1);没有用like.
如下图:
code:
import java.sql.*;
public class MysqlConn {
static{
try {
Class .forName("sun.jdbc.odbc.JdbcOdbcDriver");
System.out.print("Sucess loading JDBC_ODBC Bridge Drive...");
}
catch (Exception e){
System.out.print("Erro loading JDBC-ODBC Bridge Driver...\n");
e.printStackTrace();
}
}
public static void main(String[] args) {
try{
Connection con1=DriverManager.getConnection("jdbc:odbc:choa_samples","root","12345");
}
catch(SQLException e){
e.printStackTrace();
}
}
}