java学习总结(基础加web)
Java考试题
Java基础部分
1、请简要描述oop的主要特征,并谈谈对这些特征的理解。
Oop主要特征:抽象,封装,继承,多态;抽象:忽略与当前主题无关的部分,抓住重点
封装:使用方法将类的属性隐藏起来,控制用户对类的修改和数据访问的程度,
继承:子类继承父类的方法和属性,使程序结构清晰,提高挨骂复用,一种isa的关系。多态:不同对象对统一消息进行回应。一种多种同名方法共存
2、char型变量中能不能存贮一个中文汉字?为什么?
能,java中编码方式是unicode,char占2个字节,一个汉字刚好两个字节所以可以
3、shorts1=1;s1=s1+1;有什么错?shorts1=1;s1+=1;有什么错?
错,需要强制转型为short,+=是java定义的运算符故编译是jvm会自动处理
4、请说明break,continue,return的作用。
Break,可用于switch分支一条case语句结束以后,可用于跳出循环Contiue:用于跳出里层循环
Return:也可用于终止循环,有返回类型的方法是用与返回
5、用abstract修饰符修饰的类和方法有什么特点?
修饰的类为抽象类,包含有抽象方法,
修饰的方法,为抽象方法只有方法体而没有具体实现
6、protect修饰的方法与不加任何修饰的方法有什么不同?
加上为修饰后访问为同一包中和该类的子类,不加为默认的包访问权限。
7、什么是对象?什么是类?它们之间有什么关系
对象:具有某些属性和行为的名词,类:具有相同属性以及相同行为的一组对象,关系:对象是类的实例化
8、请描述对象的初始化顺序。
对象初始化顺序:加载类,分配内存空间,清零,加载变量然后方法。先父类静态变量,父类静态块,子类静态成员变量,子类静态块,父类非静态变量,父类构造函数,子类非静态变量,子类构造函数
9、什么是继承?继承的特性可给面向对象编程带来什么好处?
继承:子类继承父类的方法和属性,使程序结构清晰,提高代码复用,一种isa的关系。
10、什么是方法的覆盖?与方法的重载有何不同?方法的覆盖与属性的隐藏有何不同?
方法覆盖:子类重写与父类同名的方法,拥有相同的参数名和返回值,多态的一种体先,重载:具有相同的方法名但是有不同的返回类型或参数。
属性隐藏:子类定义与父类同名的属性,父类的属性就会被隐藏。
11、请简述接口和抽象类的区别。并分别举例说明应用场景。
接口:接口中全是抽象方法,若一个类实现这个接口就必须是先接口中所有的方法。关键字implements和interface抽象类:用关键字abstract修饰,包含抽象方法(仅有方法体而没有具体实现),可以包含普通方法和构造方法,使用时不能用new创建实例
12、说出ArrayList,Vector,LinkedList的存储性能和特性
ArrayList和Vector都是集合,按数组的方式存储,查找比较快,vector是线程安全的,但效率上低于arraylist,Linkedlist:链式集合双向链表,按序号索引数据进行向前向后遍历,所以插入和删除数据最快。
13、请说明Collection和Collections的区别。
Collection是一个j集合的接口,set和list都实现这个接口
Collection:是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作
14、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?
hashset我们自己区分的时候利用迭代器iterator,内部利用hashcode然后equals方法实现区分是否重复。
15、Error和Exception它们继承自哪个类?有什么区别?
继承Throwable这个类,
区别:error错误,一般来说很难回复,如内存溢出,exception,则为程序正常运行时永远不会发生的的异常,程序员需要处理。
16、什么情况出现NullPointerException异常?怎样处理?
使用一个对象是,对象为null,在适用对象前进行判断
17、请列举Java类中的方法修饰符,并简述其含义。
18、try{}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前
还是后?
会,在return前
19、Java中如何读写文件,请写出Java代码实现读写文件的基本过程。20、常见的xml解析方式有哪些?区别是什么?
Sax,dom:dom一次性全部读取xml文件,创建一个一颗文档树,故读取大文件是熟读缓慢
21、简要描述数据库连接池的工作机制,并列出使用数据库连接池的优点。
程序运行时,创建一定数量的池连接,比在以后维持不少于这个数量的连接。提高程序运行的效率
22、对于一个Linux命令,可以通过哪些方法了解其具体的使用方法。
Help,info,man,使用格式helpls;lshelp;infols;manls;
23、Linux系统中,请简要描述文件和目录的访问权限的9个权限位的作用,请列举修改权限的命令。
Xxxxxxxxx;前三位表示所有者的可读可写可操作权限,中间所有者的所在用户组;后三位是其他用户,Chmod777要更改权限的对象。
24、数据库中,什么叫视图(View),什么叫索引(Index)?什么情况下会用到索引,视图的主要作用有哪些。
视图:一张虚拟的逻辑表。并不包含实际的数据,相当于一个窗口,可通过该窗口对数据进行查询和修改。作用:使复杂查询变得容易,提供数据独立性,限制数据访问。索引:帮助查找数据。用指针加速取回数据。
Javaweb部分
1、请简述对J2EE的理解。
由sun公司提供的一种企业级基于组件的java开发规范。J2EE定义了13种组件如servlet,jsp,jdbc等。2、简要描述对mvc的理解,并举例说明在项目中的实现思路
Mvc是一种开发模式,优点:耦合性低,可维护性高。,分别代表三个单词:Modle,Veiw,Control,模型层控制程序的业务逻辑,视图层,是接受用户输入和显示数据给用户与用户交互,控制层:控制程序走向,模型层与视图层的中间桥梁。3、Javascript有什么特点?并说明其主要用途。
Javascript:一种脚本语言,是基于事件的面向对象语言,弱数据类型,安全,运行速度快,有强大的函数库,
主要用途:客户端验证用户输入,给用户动态的提示。美化页面。4、什么是servlet容器?它的作用是什么?
Servlet容器:用于创建和维护servlet,提供一个运行环境给servlet的东西。5、请描述servlet的生命周期以及在每个阶段所调用的方法。
实例化:有容器进行。初始化:调用init()方法。处理请求:根据请求方式的不同调用service()中的不同方法如:doget,dopost。销毁:调用destroy方法。6、怎样在web.xml文件中注册一个servlet?
主要两大块:
7、请描述在servlet中forward和redirect的区别与联系。
Forword:请求转发,服务器跳转,一次请求,地址栏不改变,request对象中的信息不丢失。Redirect:请求重定向,客户端跳转,两次请求,地址栏改变,request对象中的信息丢失。8、请描述jsp的执行过程。
Jsp执行经过两个阶段:1、转译阶段,将jsp转译为servlet,
2、编译servlet,生成.class文件,
3、调用.class文件生成html页面显示给用户。
9、如何执行一个线程安全的JSP?
10、Jsp的9个内置对象是什么?他们分别有什么作用。
Jsp九大内置对象:page,request,response,session,application,pagecontext,config,exception,out。四个域对象:out输出信息,e:处理异常,config:拿到一些配置信息。11、请列举出至少5个request对象的常用的方法。12、Jsp的四个域对象是什么?他们的“域”指的是什么?
Page,requerst,session、,application,域表示有效时间,及在什么范围内有效。13、请列列举四个jsp指令,并说明它们的含义。
Page:设置页面属性,taglib,:标签指令,include:包含指令。14、Jsp有哪些动作?作用是什么?
15、请描述Jsp和servlet的区别与联系。
。。。。。。。。
16、请说出在jsp中静态包含和动态包含技术的异同点。
静态是先包含再执行,动态为先执行在编译。
17、在JSP开发过程中,对于同一个用户的会话,要想在不同的页面之间共享数据,可以有几种选择?请一一列举
Request,session,application,cookie,重写地址栏,隐藏域。18、请说明过滤器的工作原理以及重要的接口。
过滤器:当一个请求到达是过滤器会进行拦截,服务器响应消息时也会同样拦截。根据编写的故偶滤器确定是否放行和是否要做相应的处理。重要接口:filter,filterchain,filterconfig。19、什么是监听器?它的作用是什么,请举例说明。
监听器是:专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时。监听域对象自身的创建和销毁的事件监听器监听域对象中的属性的增加和删除的事件监听器
监听绑定到HttpSession域中的某个对象的状态的事件监听器
20、使用http传输协议将客户端的请求传送至服务器端最常用的是哪两种方式,他们的区别是什么。
Get,post,
Get:方式相对来说速度较快,当传输的数据量要小于1kb,传输的信息会在地址栏显示,安全性存在隐患。Post:比get方式安全,传递的数据量也比之要大。21、简述struts2的工作流程。
Struts2:核心为一个过滤器,当一个请求到达的时候,服务器对之进行拦截,参考struts.xml文件,寻找到对应配置的action,寻找到action类,对请求做出相应的处理。处理完后返回一个String,参考struts.xml文件中的配置的result显示相应的页面给用户
22、Struts2配置文件struts.xml中有哪些常用的配置项,它们分别有什么作用?23、请说明在ognl表达式中#、$、%的作用。
Ognl表达式:#是取非valuestack中的值时使用,如request.还有操作集合是时也可以用到。
$配置文件中那取action中的值是会使用到。国际化资源文件中引用ognl表达式%当强制声明为ognl表达式或字符串是会使用到
24、写出3组常见的Struts标签,并简述其作用。
25、valuestack是什么?它的作用是什么?在页面中怎样访问?
Struts的值栈,存放一些请求响应信息,直接访问。26、请简要描述Struts2中拦截器的主要作用、配置及执行流程。
拦截器,servlet中的过滤器相似,当客户端请求到达是经过拦截器,响应是也会经过,是一种aop的思想。配置:interceptor
Servlet是线程不安全的,采用多线程的方式调用service方法。CGI就是单线程,所以servlet比之效率高。Servlet实现单线程的方法:实现singleThreadmodel。
创建线程的两种方式:继承Thread这个类,或实现runnable这个接口,启动线程:statrt(),启动后会调用run方法。Sleep和wait()区别:sleep不会释放锁。Wait()释放锁,必须有notify()唤醒。多线程中实现线程安全:利用关键字synchronized,一把锁,实现同步。死锁的条件:互斥条件,不可剥夺资源,循环等待,请求与保持条件。反射:加载驱动,Class.forName(“类的完整类名”)通过一个class对象拿到其相应的方法属性。组件:就是对数据和方法进行了简单封装。
扩展阅读:Java web入门实战总结[呕心呖血之作]
1.Java基础增强
1.1Eclipse使用最佳实践1.1.1常用快捷键
Ctrl+1Ctrl+D:
快速修复(最经典的快捷键,就不用多说了)删除当前行
复制当前行到下一行(复制增加)复制当前行到上一行(复制增加)
当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了)当前行和上面一行交互位置(同上)前一个编辑的页面
下一个编辑的页面(当然是针对上面那条来说了)显示当前选择资源(工程,or文件or文件)的属性
Ctrl+Alt+↓Ctrl+Alt+↑Alt+↓Alt+↑Alt+←Alt+→Alt+Enter
Shift+Enter在当前行的下一行插入空行(这时鼠标可以在当前行的任一位置,不一定是最后)Shift+Ctrl+Enter在当前行插入空行(原理同上条)Ctrl+QCtrl+LCtrl+MCtrl+/Ctrl+OCtrl+TCtrl+WCtrl+KCtrl+E
定位到最后编辑的地方
定位在某行(对于程序超过100的人就有福音了)最大化当前的Edit或View(再按则反之)注释当前行,再按则取消注释快速显示OutLine
快速显示当前类的继承结构关闭当前Editer
参照选中的Word快速定位到下一个
快速显示当前Editer的下拉列表(如果当前页面没有显示的用黑体表示)
Ctrl+Shift+X把当前选中的文本全部变味小写Ctrl+Shift+YCtrl+Shift+F
把当前选中的文本全部变为小写格式化当前代码
下面的是重构的时候用得到的:Alt+Shift+R
重命名(是我自己最爱用的一个了,尤其是变量和类的Rename,比手工方法能节省很多劳动力)
Alt+Shift+M
抽取方法(这是重构里面最常用的方法之一了,尤其是对一大堆泥团代码有用)
Alt+Shift+CAlt+Shift+L
修改函数结构(比较实用,有N个函数调用了这个方法,修改一次搞定)抽取本地变量(可以直接把一些魔法数字和字符串抽取成一个变量,尤其是多处调用的时候)
Alt+Shift+FAlt+Shift+IAlt+Shift+VAlt+Shift+Z
把Class中的local变量变为field变量(比较实用的功能)合并变量(可能这样说有点不妥Inline)移动函数和变量(不怎么常用)重构的后悔药(Undo)
1.1.2模块分离
在实际的开发中,尽量让工作空间(workspace)和项目(Project)分离开来,开发中使用统一的编码,一般都设置成UTF-8(window->preference->general->workspace)
在开发过程中,要把项目源码包和测试的源码包分离开来,因为测试代码是不需要发布的,另外,要把测试代码和项目代码的编译输出目录分离开来。
1.1.3调试断点
关于Eclipse的调试,设置断点,可以通过Run->removeallbreakpoint移除所有的断点这个主要是在web开发的时候,tomcat自动会停在断点的地方,这个时候就需要移除所有断点。
1.2Java基础知识1.2.1静态导入
示例:
importstaticorg.junit.Assert.*这里表示把Assert类的所有静态方法引入,在本文件中如果要使用Assert的静态方法就可以不用Assert了。
1.2.2可变参数
publicstaticintsum(Stringaction,int...params){}这里就表示可变参数,可变参数必须是最后面的,因为如果不放在后面,就无法区分后面的参数到底是什么了。
//Dosomethinghere1.2.3foreach
这种方式的循环,强调的是元素本身,其底层是有迭代器(Iterator)实现的,需要进行对象的同步,所以在效率上比普通的for循环要低。
在使用foreach循环的时候,与奥注意的是修改问题,因为同步的关系,这可能会带来
一些问题,一般来说,建议如果在需要修改元素的情况下,使用普通的for循环。
1.2.4拆箱&装箱
需要注意的是:
对于:Integera=128;Integerb=128;
在-127到128之间的话,a==b是true,否则是false即a、b引用一样,请看下面的例子:
Integera=128;Integerb=128;
System.out.println(a==b);//falsea=-128;b=-128;
System.out.println(a==b);//true
a=-129;b=-129;
System.out.println(a==b);//falsea=127;b=127;
System.out.println(a==b);//true
1.2.5反射
获取Class的几种方式:假设有类:edu.zhku.cian.User(1)直接使用类名类获取
Classclazz=User.class;
这种方式用一种缺陷,就是它不会执行静态代码块,别的方式都会执行静态的代码块(2)使用Class.forName获取,这是最常用的
Classclazz=Class.forName("edu.zhku.cian.User");
会抛出ClassNotFoundException
(3)通过对象的getClass()方法来获取
Useruser=newUser();
Classclazz=user.getClass();
注意:反射只能是反映静态的字节码信息,是无法获得运行时信息的,例如泛型,由于字节码是去类型化的,所以在运行时步伐动态获得泛型类型信息。
1.2.6Annotation-注解
需要掌握的知识:
(1)注解的扫描(2)注解的属性
1.2.7泛型
作用:
使之类型安全,把运行时的错误提前到编译期间,让错误提前暴露。关于
Employeecloned=(Employee)e.clone();
(6)静态导入(7)控制台输入
JDK5.0先前的版本没有Scanner类,只能使用JOptionPane.showInputDialog类代替。
5.0:1.4:
Stringinput=JOptionPane.showInputDialog(prompt);intn=Integer.parseInt(input);doublex=Double.parseDouble(input);s=input;
Scannerin=newScanner(System.in);System.out.print(prompt);intn=in.nextInt();doublex=in.nextDouble();Strings=in.nextLine();
(8)格式化输出、
JDK5.0以前的版本没有print方法,只能使用NumberFormat.getNumberInstance来代替
(9)内容面板代理
在JDK5.0先前的版本中,JFrame,JDialog,JApplet等类没有代理add和setLayout方法
(10)StringBuilder
JDK5.0引入了StringBuilder类,这个类的方法不具有同步,这使得该类比StringBuffer
类更高效。
(11)Annotation注解
注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,以后,javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事。标记可以加在包,类,字段,方法,方法的参数以及局部变量上。
看java.lang包,可看到JDK中提供的最基本的annotation。(12)枚举类型
2.XML
2.1XML基础2.1.1XML概述
xml是通用数据交换格式,不受知识产权的限制。详见:E:\\itcast\\review\\0002_Enhance_xml
2.1.2Properties类
加载properties文件的几种方式:(方式1-4都是要到classpath下面找资源)属性文件的后缀名可以是任意的//方式一:
InputStreaminStream=LoadConfigTest.class.getResourceAsStream("/config/config.properties");properties.load(inStream);//方式二:
inStream=this.getClass().getResourceAsStream("/config/config.properties");properties.load(inStream);//方式三:inStream=
LoadConfigTest.class.getClassLoader().getResourceAsStream("config/config.properties");//方式四:
inStream=this.getClass().getClassLoader().getResourceAsStream("config/config.pro");properties.load(inStream);//方式五:使用绝对路径inStream=
newFileInputStream(newFile(..\\\\config.properties"));
7properties.load(inStream);
详见项目:E:\\itcast\\review\\0002_Enhance_xml------------edu.zhku.cian.pro.LoadConfigTest
2.1.3XML语法
xml文档声明
空行和换行的处理,注意下面两段:
1)2)
广州广州
这里的1和2是不同的,在2中还包含了两个换行,分别是和广州之间的,以
及广州和之间的。
2.1.4xml编码问题
在进行文档声明的时候:
如果声明的是utf-8,那么文件本省的编码也应该是utf-8,在weindow操作系统下默认
新建的xml文件是ASCII编码的。
如果出现乱码问题,可以用记事本打开这个文件,然后另存为,把编码改成你的文档声
明的编码,如在本例子中的是utf-8。
2.1.5CDATA
(1)CDATA区全称为characterdata,以“”结束,在两者之间嵌入不想被解析程序解析的原始数据,解析器不对CDATA区中的内容进行解析,而是将这些数据原封不动地交给下游程序去处理。
(2)CDATA区中的起始和结束处有和没有空格和换行字符是有区别的
2.1.6特殊字符
&<>""
&<>"'
2.1.7格式良好的XML文件
遵守XML基本语法规则和规范的XML文档就可以称之为“Well-formedXML”,中文意思就是“格式良好的XML”。
2.1.8XML约束模式语言
先后出现的XML约束模式语言有XMLDTD、XDR、SOX、XMLSchema等等,其中应用最广泛和具有代表意义的是XMLDTD和XMLSchema
2.1.9有效的XML
一个遵守XML的基本语法规则、且符合为它指定的某个XML约束模式的XML文档就可以称之为“ValidXML”文档,中文意思就是“有效的XML”文档。
2.1.10DTD
全称DocumentTypeDefinition,DTD文件的编码应该要和xml文件的编码及其xml声明的编码一致,否则不可用。
1.如何在xml中引入外部的dtd,dtd上面的声明都是指向网络上面dtd文件的地址,因为我们不能够上网,无法让eclipse帮我从网络上面下载dtd,就需要将网络地址映射到本地dtd地址上面从而对xml进行验证.如何映射呢?
2.1在抒写xml之前要把dtd文件中的xml生命拷贝到当前xml中
网络地址
2.2在eclipse中..
通过网络地址映射本地dtd
window---preferences---xml---xmlCatalog--AddLocation中填写本地dtd文件的地址KeyType中选择URIkey中填写网络dtd的地址通过xml声明中dtd的id
window---preferences---xml---xmlCatalog--AddLocation中填写本地dtd文件的地址KeyType中选择PublicIDkey中填写dtd的Id
2.11XMLSchema与DTD的比较
XMLSchema符合XML语法结构。
DOM、SAX等XMLAPI很容易解析出XMLSchema文档中的内容。XMLSchema则采用与XML文档同样的合法性验证机制。XMLSchema对名称空间支持得非常好。
XMLSchema比XMLDTD支持更多的数据类型,并支持用户自定义新的数据类型。XMLSchema定义约束的能力非常强大,可以对XML实例文档作出细致的语义限制。XMLSchema基本上满足了关系模式在数据描述上的需要。XMLSchema不能像DTD一样定义实体,比DTD更复杂。
2.2XML解析2.2.1DOM解析
DOMDocumentObjectModel,W3C标准,基于信息层次,基于树或基于对象,一
次性加载到内存中。
优点:编程容易,易于添加和修改树的元素,遍历能力强。
缺点:需要加载整个文档到内存,对计算机性能和内存要求高,尤其是大文档应用场景:由于遍历能力强,DOM解析器常用于xml文档需要频繁更改的服务中。
DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。DOM以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。
2.2.2SAX解析
基于事件的,不需要将数据存储在内存中,分析能够立即开始,对于大型XML文档来说是很好的优点,一般比DOM要快
SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX还比它的替代者DOM快许多。
选择DOM还是选择SAX?对于需要自己编写代码来处理XML文档的开发人员来说,选择DOM还是SAX解析模型是一个非常重要的设计决策。DOM采用建立树形结构的方式访问XML文档,而SAX采用的事件模型。
DOM解析器把XML文档转化为一个包含其内容的树,并可以对树进行遍历。用DOM
11优点:对内存要求低,扩展能力好
缺点:编码很困难,基于事件模型,很难处理同一个文档不同地方的数据
解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用navigationAPIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用DOM解析器的时候需要处理整个XML文档,所以对性能和内存的要求比较高,尤其是遇到很大的XML文件的时候。由于它的遍历能力,DOM解析器常用于XML文档需要频繁的改变的服务中。
SAX解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag.特别是当开发人员只需要处理文档中所包含的部分数据时,SAX这种扩展能力得到了更好的体现。但用SAX解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。
2.2.3JDOM解析
JDOM的目标:使用20%(或更少)的精力解决80%(或更多)Java/XML问题。JDOM的目的是成为JAVA特定文档模型,简化与XML的交互并且比使用DOM实现更快,是第一个Java特定模型。
JDOM的目的是成为Java特定文档模型,它简化与XML的交互并且比使用DOM实现更快。由于是第一个Java特定模型,JDOM一直得到大力推广和促进。正在考虑通过“Java规范请求JSR-102”将它最终用作“Java标准扩展”。从201*年初就已经开始了JDOM开发。
JDOM与DOM主要有两方面不同。首先,JDOM仅使用具体类而不使用接口。这在某
12JDOM自身不包含解析器,它通常使用SAX2解析器来解析和验证输入XML文档。JDOM和DOM的不同:
(1)JDOM仅使用具体类而不使用接口,简化了API,限制了灵活性
(2)API大量使用了Collections类,简化了那些已经熟悉这些类的Java开发者的使用
JDOM综合了DOM和SAX解析方式,兼具两者有点,克服两者缺点。
些方面简化了API,但是也限制了灵活性。第二,API大量使用了Collections类,简化了那些已经熟悉这些类的Java开发者的使用。
JDOM文档声明其目的是“使用20%(或更少)的精力解决80%(或更多)Java/XML
问题”(根据学习曲线假定为20%)。JDOM对于大多数Java/XML应用程序来说当然是有用的,并且大多数开发者发现API比DOM容易理解得多。JDOM还包括对程序行为的相当广泛检查以防止用户做任何在XML中无意义的事。然而,它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情况下的错误)。这也许是比学习DOM或JDOM接口都更有意义的工作。
JDOM自身不包含解析器。它通常使用SAX2解析器来解析和验证输入XML文档(尽
管它还可以将以前构造的DOM表示作为输入)。它包含一些转换器以将JDOM表示输出成SAX2事件流、DOM模型或XML文本文档。JDOM是在Apache许可证变体下发布的开放源码。
2.2.4DOM4J解析
实例代码:E:\\itcast\\review\\0002_Enhance_xml针对Java开发者的易用性和直观操作。
虽然DOM4J代表了完全独立的开发结果,但最初,它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能,包括集成的XPath支持、XMLSchema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,它通过DOM4JAPI和标准DOM接口具有并行访问功能。
为支持所有这些功能,DOM4J使用接口和抽象基本类方法。DOM4J大量使用了API中的Collections类,但是在许多情况下,它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是,虽然DOM4J付出了更复杂的API的代价,但是它提供了比JDOM大得多的灵活性。
虽然DOM4J代表了完全独立的开发结果,但最初,它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能,包括集成的XPath支持、XMLSchema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,它通过DOM4JAPI和标准DOM接口具有并行访问功能。从201*下半年开始,它就一直处于开发之中。
为支持所有这些功能,DOM4J使用接口和抽象基本类方法。DOM4J大量使用了API中的Collections类,但是在许多情况下,它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是,虽然DOM4J付出了更复杂的API的代价,但是它提供了比JDOM大得多的灵活性。
在添加灵活性、XPath集成和对大文档处理的目标时,DOM4J的目标与JDOM是一样的:针对Java开发者的易用性和直观操作。它还致力于成为比JDOM更完整的解决方案,实现在本质上处理所有Java/XML问题的目标。在完成该目标时,它比JDOM更少强调防止不正确的应用程序行为。
DOM4J是一个非常非常优秀的JavaXMLAPI,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML,特别值得一提的是连Sun的JAXM也在用DOM4J.
2.2.5解析方式的比较
(1)DOM4J性能最好,连Sun的JAXM也在用DOM4J.目前许多开源项目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文件。如果不考虑可移植性,那就采用DOM4J.
(2)JDOM和DOM在性能测试时表现不佳,在测试10M文档时内存溢出。在小文档情况下还值得考虑使用DOM和JDOM.虽然JDOM的开发者已经说明他们期望在正式发行版前专注性能问题,但是从性能观点来看,它确实没有值得推荐之处。
另外,DOM仍是一个非常好的选择。DOM实现广泛应用于多种编程语言。它还是许
多其它与XML相关的标准的基础,因为它正式获得W3C推荐(与基于非标准的Java模型
相对),所以在某些类型的项目中可能也需要它(如在JS中使用DOM)。
(3)SAX表现较好,这要依赖于它特定的解析方式-事件驱动。一个SAX检测即将到来的XML流,但并没有载入到内存(当然当XML流被读入时,会有部分文档暂时隐藏在内存中)。
3.Tomcat
3.1Tomcat工作原理3.1.1Servlet容器
Servlet容器的作用是负责处理客户的请求,过程如下:
用户请求-->Servlet容器获取请求-->分发请求(调用相应的Servlet)-->返回用户结果
3.1.2Servlet工作模式
1.2.1独立的Servlet容器----Tomcat的默认工作模式
1.2.2进程内的Servlet容器1.2.3进程外的Servlet容器
3.1.3TomcatWeb应用简介
TomcatWeb应用由一些Servlet、HTML、java类、jsp页面和其他资源构成。一
个TomcatWen应用与Tomcat中的Context元素对应,也就是,一个Context定义了一个TomcatWeb应用。
3.1.4Tomcat安装和启动
名词解释:
--JDKJavaDevelopToolKit
Java开发包,包含了很多Java开发工具(java.exe,
javac.exe......)
--JRE
JavaRuntimeEnvironmentJava运行环境,这是java运行的基础
Java虚拟机,jre目录下的bin目录中server和client
--JVMJavaVitualMachine
目录,这个是jvm.dll的真正所在,jvm.dll启动后会使用explict的方法
安装与启动Tomcat步骤:1、安装JDK
设置环境变量:JAVA_HOMED:\\Program\\Study\\Java\\jdk1.6.0_32
CLASSPATH%JAVA_HOME%\\jre\\lib\\rt.jar;.;PATH
%JAVA_HOME%\\bin
--JIT
JavaInTimeJava即时编译器,是JVM的一部分,属于内核部分
2、安装Tomcat
直接在官网下载,解压缩即可
3、启动与关闭Tomcat
启动:
(1)在命令行模式下切换到Tomcat解压缩目录:
F:\\Videos\\itcast\\personal\\tomcat\\apache-tomcat-6.0.35\\bin
运行startup:F:\\Videos\\itcast\\personal\\tomcat\\apache-tomcat-6.0.35\\bin>startup
(2)直接双击startup.bat关闭:
(1)在命令行模式下切换到Tomcat解压缩目录:
F:\\Videos\\itcast\\personal\\tomcat\\apache-tomcat-6.0.35\\bin
运行startup:F:\\Videos\\itcast\\personal\\tomcat\\apache-tomcat-6.0.35\\bin>shutdown
(2)直接双击shutdown.bat
相关参数意义:
目录conf下的server.xmlContext标签:
>reloadable="true|false"docBase="webpath"workDir="catch"
//表示在运行时在classes和lib文件夹下自动加载类
//应用程序的根目录//表示缓存文件存放位置
3.2TomcatWeb项目部署3.2.1安装Tomcat为系统服务
实现可以通过windows的service.msc打开的界面进行服务的管理。DOS-->cd到Tomcat/bin目录下,里面有一个service.bat文件,运行该文件即可,如下命令格式:
运行命令:serice.batinstalltomcat6
(其中tomcat6是服务的名字,可以任意取)
3.2.2卸载Tomcat系统服务
卸载该服务:
serviceuninstalltomcat6(其中tomcat6是服务的名字,可以任意取)
3.2.3Web项目结构
/web应用的根目录,该目录下的所有文件都是可访问到额该目录及其子目录下的文件在浏览器中是不可访问的,web.xml包含wen应用的配置属性,这些属性由ServletAPI定义
/WEB-INF/classes/WEB-INF/lib
存放web应用的所有classes文件存放类文件打包后的jar文件
/WEB-INF
注意:为了部署方便,还目录下的所有文件可以压缩为zip文件再更改扩展名为war。可以根据需要在根目录下建立不同资源文件的子目录:如js/image
3.2.4Web项目部署
(1)将整个项目复制到Tomcat安装目录下的webapps目录下
(2)直接在server.xml中进行配置
在server.xml的前面添加一个Web应用环境:例如:
如果项目的目录结构如下:--example----WEB-INF------lib------web.xml----index.html
其中的example,就是项目的根路径
那么访问index.html的格式::8080/example/index.html
第一个参数指定虚拟目录访问路径:如上面这样子,访问的格式如下:
:8080/hello/index.html
第三个表示启用热部署,可选,如果path="",表示直接根目录下就能访问,即默认项
目:
:8080/index.html
3.2.5虚拟主机映射
所解决的问题:在一个Tomcat下可以使用多个默认WEB项目,即每一个虚拟主机对应一个默认项目
(1)在计算机上配置虚拟主机(不同操作系统不同,具体可参见百度)
windows下配置虚拟主机:
dos-->cdC:\\Windows\\System32\\drivers\\etc
下面有一个hosts文件,打开这个文件,添加:
127.0.0.1127.0.0.1127.0.0.1
(2)在server.xml中配置虚拟主机
在原有的标签后面添加一个Host标签:
(3)启动Tomcat服务器
服务器启动之后我们就可以使用下面这个URL来访问我们的应用了
:8080/index.html:8080/index.html:8080/index.html
3.3HTTP协议详解3.3.1什么是HTTP协议
(1)web浏览器和web服务器之间是一问一答的的交互过程,而要想正确的进行交互,就
必须遵循一定的规则,这个规则就是我们所熟悉的HTTP协议规范。
(2)HTTP是HypertextTransferProtocol(超文本传输协议)的缩写,它是TCP/IP协议子
集中的一个应用层协议,用于定义web浏览器和web服务器之间数据交换的过程及数据本身。
(3)HTTP协议的版本HTTP/1.0、HTTP/1.1、HTTP-NG
(4)深入理解HTTP协议,对管理和维护复杂的WEB站点、开发具有特殊用途的WEB服
务器程序具有直接影响。
3.3.2建立TCP连接
TCP传输连接建立过程中需要解决三个基本问题:
TCP协议采用的是客户/服务器模式,主动发起建立连接请求的称之为客户,等待
1)确定通信的每一方是否存在
2)允许双方协商通信参数,如最大报文段长度,最大窗口长度以及服务质量等3)分配传输实体可以使用的资源,如缓冲区大小
并接收连接建立请求的进程为服务器。
传输连接建立需要经过以下三个步骤(即所谓的"三次握手"):
假设主机[A]为客户进程,主机[B]为服务进程,现在[A]要与[B]建立传输连接。1)第一次握手
2)第二次握手
[B]-->同意[A]与自己建立连接
-->[B]向[A]发出应答报文段
-->[SYN=1,ACK=1,SEQ=4800(同样需要分配一个序号)]-->【AN=1201(确认号,即请求报文中的SEQ+1,
表示序号为1200的报文段已经正确接收
下一次应该发送序号SEQ=1201的报文段,因此AN有捎带确认的作用)】
[A]-->发送连接请求报文段到[B]
这就好像是[A]对[B]说:我希望开始一次新的会话
-->[SYN=1,ACK=0,SEQ=1200(这个是给这个报文段分配一个序号)]
这就好像[B]对[A]说:好吧,让我们交谈吧
3)第三次握手
[A]-->接收到[B]的应答报文段
这就好像[A]对[B]说:很高兴你愿意交谈,我们开始吧!
-->在此发送一个建立传输连接确认报文段
-->[SYN=1,ACK=1,SEQ=1201,AN=4801(即应答报文段的SEQ+1)]
经过这三次的握手之后就建立好了[A]和[B]之间的连接,即向应用层报告连接已经建立
好了。
目的:看完上面的["三次握手"]之后,你也许知道这三次握手的目的了:
采用三次握手的目的是为防止传输连接过程中出现错误(传输延迟等原因)。
3.3.3释放TCP连接
在用户数据传输结束时,需要释放传输连接,才易于传输连接的任何一方都可以释放连接。
释放传输连接需要四个步骤(亦即【四次握手】)
当关闭客户进程到服务进程的连接时,服务端进程到客户端的进程可能还没释放,使用
四次握手的方式来确保连接都关闭。
1)第一次握手
[A]-->发送释放连接请求报文段
-->[FIN=1,ACK=0,SEQ=2500]
[A]希望释放此次连接
2)第二次握手
[B]-->同意释放连接
-->发出应答报文段
-->[ACK=1,AN=2501,SEQ=6000]
[B]此时知道[A]的想法释放此次连接
3)第三次握手
[B]-->我没数据需要传输了
-->释放服务端到客户端的连接-->向[A]发出释放连接请求报文段-->[FIN=1,ACK=0,SEQ=6001]
同意释放这次连接
4)第四次握手
[A]-->接收到[B]的请求释放连接报文段
-->再次发送释放连接应答报文段-->[ACK=1,SEQ=2501,AN=6002]
释放这次连接
3.3.4HTTP1.0会话方式
四个步骤:
建立连接--》发出请求信息--》回送相应信息--》关闭连接
HTTP1.0
浏览器和web服务器之间的连接过程是短暂的,每次的连接处理一个请求和响应,对
于每一个页面的访问都需要建立一个独立的连接。
3.3.5HTTP1.1会话方式
HTTP1.1的特点:
1)在一个连接上可以传送多个HTTP请求和响应2)多个请求和响应可以重叠执行
3)增加了更多的请求头和响应头
过程:
建立连接
-->发送第1个请求-->发送第2个请求-->......
-->发送第n个请求-->回送第1次响应-->回送第2次响应-->......
-->回送第n次响应-->关闭连接
3.3.6HTTP请求消息
请求消息的结构:
一个请求行、若干消息头、以及实体内容,其中的一些消息头和实体内容都是可选的,
消息头和实体内容之间要用空行隔开。
举例:请求行:消息头:
Accept:*/*
Accept-Language:en-usConnection:Keep-AliveHost:localhost
Referer:User-Agent:Mozilla/4.0Accept-Encoding:gzip,deflate
GET/books/java.htmlHTTP/1.1
空行:----------
GET请求方式的请求消息中不能包含消息实体(AJAX)
3.3.7HTTP响应消息
响应消息的结构:
一个状态行、若干消息头、以及实体内容,其中的一些消息头和实体内容都是可选的,
消息头和实体内容之间要用空行隔开。
举例:状态行:消息头:
Server:Microsoft-IIS/5.0
Date:Thu,13Jul201*05:46:53GMTContent-Length:2291Content-Type:text/htmlCache-control:private
HTTP/1.1200OK
一个空行:实体内容:
3.3.8HTTP消息头
(1)使用消息头,可以实现HTTP客户机与服务器之间的条件请求和应答,消息头相当于服务器和浏览器之间的一些暗号指令
(2)每个消息头包含一个头字段名称,然后依次是冒号、空格、值、回车和换行符。
举例:Accept-Language:en-us
(3)消息头字段名是不区分大小写的,但习惯上将每个单词的第一个字母大写(4)整个消息头部分中的各行消息头可按任何顺序排列
(5)消息头又可以分为通用信息头、请求头、响应头、实体头等四类
(6)许多请求头字段都允许客户端在值部分指定多个可接受的选项,多个项之间以逗号分隔。
举例:Accept-Encoding:gzip,compress
(7)有些头字段可以出现多次,例如,响应消息中可以包含有多个“Warning”头字段。
3.3.9HTTP典型响应码
200(正常)
表示一切正常,返回的是正常请求结果。
206(部分内容)
客户发送了一个带有Range头(要求服务器只返回文档中的部分内容)的GET请求,
服务器按要求完成了这个请求。302/307(临时重定向)
指出被请求的文档已被临时移动到别处,此文档的新的URL在Location响应头中给出。
304(未修改)
表示客户机缓存的版本是最新的,客户机应该继续使用它。
401(未经授权)
表示客户机访问的是一个受口令和密码保护的页面,结合使用一个WWW-Authenticate
响应头提示客户机应重新发出一个带有Authorization头的请求消息。404(找不到)
服务器上不存在客户机所请求的资源。
500(内部服务器错误)
服务器端的CGI、ASP、JSP等程序发生错误。
4.IO
4.1概述
IO流用来处理设备之间的数据传输Java对数据的操作是通过流的方式Java用于操作流的对象都在IO包中流按操作对象分为两种:字节流与字符流。
先有字节流,后有字符流。为什么要出现字符流呢?流按流向分为:输入流,输出流。
4.2IO常用基本类
字节流的抽象基类:
InputStream,OutputStream。字符流的抽象基类:
Reader,Writer。
注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
如:InputStream的子类FileInputStream。如:Reader的子类FileReader。
4.3字符流4.3.1创建文件
创建流对象,建立数据存放文件
FileWriterfw=newFileWriter(“Test.txt”);调用流对象的写入方法,将数据写入流
fw.write(“text”);
关闭流资源,并将流中的数据清空到文件中。
fw.close();
不写close方法会有什么结果呢?---没有被销毁,消耗内存
如果想在原有文件上继续加入新的数据呢?---建立文件的时候,第二参数:trueFileWriterfw=null;try{fw=newFileWriter("Test.txt");fw.write("text");}catch(IOExceptione){System.out.println(e.toString());
}finally{if(fw!=null)try{fw.close();}catch(IOExceptione){System.out.println(e.toString());}}4.3.2读取文件
建立一个流对象,将已存在的一个文件与流进行关联。
FileReaderfr=newFileReader(“Test.txt”);创建一个临时存放数据的数组。
char[]ch=newchar[1024];
调用流对象的读取方法将流中的数据读入到数组中。
fr.read(ch);思考:
在加载文件时候是否是将文件全部加载进流-----不是,先读取部分到缓冲区为什么定义数组,要定义多大呢?-----缓冲区,一般是1024FileReaderfr=null;try{fr=newFileReader("c:\\\\test.txt");char[]buf=newchar[1024];intnum=0;while((num=fr.read(buf))!=-1){System.out.println(newString(buf,0,num));}}catch(IOExceptione){System.out.println("read-Exception:"+e.toString());}finally{if(fr!=null){try{fr.close();}
}}catch(IOExceptione){System.out.println("close-Exception:"+e.toString());}4.3.3注意事项
定义文件路径时,可以用“/”或者“\\\\”。
在创建一个文件时,如果目录下有同名文件将被覆盖。
在读取文件时,必须保证该文件已存在,否则出异常FileNotFoundException。
练习:Copy一个文本文件。
思路:可以使用字节流,也可以使用字符流,看需求,从输入流读取到输出流即可。
4.3.4字符流的缓冲区
缓冲区的出现提高了对数据的读写效率。对应类:
BufferedWriterBufferedReader
缓冲区要结合流才可以使用。在流的基础上对流的功能进行了增强。
4.3.5IO装饰模式
对原有类进行了功能的改变,增强。装饰模式的基本格式。
它与继承有什么不同?--------使用的是组合了解BufferedReader的原理。
4.4字节流4.4.1概述
基本操作与字符流类相同
但它不仅可以操作字符,还可以操作其他媒体文件例程:
Copy一个Jpg文件。
4.4.2字节流的缓冲区
同样是提高了字节流的读写效率。通过换成区,可以降低与磁盘的IO操作次数。练习:
通过几种方式对MP3的进行拷贝,比较它们的效率。使用模板方法设计模式自定义MyBufferedInputStream
体现缓冲思想。
read方法返回int类型的原因。
4.4.3转换流
转换流的由来
字符流与字节流之间的桥梁(编码转换)方便了字符流与字节流之间的操作转换流的应用
字节流中的数据都是字符时,转成字符流操作更高效。例程:标准输入输出。
System类中的字段:in,out。
它们各代表了系统标准的输入和输出设备。默认输入设备是键盘,输出设备是显示器。System.in的类型是InputStream.
System.out的类型是PrintStream是OutputStream的子类FilterOutputStream的子类.标准输入输出流示例:
例:获取键盘录入数据,然后将数据流向显示器,那么显示器就是目的地。通过System类的setIn,setOut方法对默认设备进行改变。
System.setIn(newFileInputStream(“1.txt”));//将源改成文件1.txt。System.setOut(newPrintStream(“2.txt”));//将目的改成文件2.txt因为是字节流处理的是文本数据,可以转换成字符流,操作更方便。BfferedReaderbufr=
newBufferedReader(newInputStreamReader(System.in));
BufferedWriterbufw=
newBufferedWriter(newOutputStreamWriter(System.out));
4.4.4流的应用
流是用来处理数据的。
处理数据时,一定要先明确数据源,与数据目的地(数据汇)。数据源可以是文件,可以是键盘。
数据目的地可以是文件、显示器或者其他设备。
而流只是在帮助数据进行传输,并对传输的数据进行处理,比如过滤处理.转换处理等。
4.4.5字符流继承结构
4.4.6字节流继承结构
4.5File4.5.1File类
用来将文件或者文件夹封装成对象方便对文件与文件夹进行操作。
File对象可以作为参数传递给流的构造函数。
了解File类中的常用方法以及跨平台的分隔符separator。
4.5.2递归
函数自己调用自己。
注意:递归时一定要明确结束条件。应用场景:
当某一功能要重复使用时。练习:
列出一个文件夹下所有的子文件夹以及子文件(递归调用,结束主要区分是文件夹还是文件)思考:
1,删除一个目录的过程是如何进行的?(先把文件夹下的文件删除在把文件夹删除)2,复制一个目录的过程呢?(不存在目录就创建,否则遍历文件夹,并复制文件)
4.6IO中的其他类
操作基本数据类型
DataInputStream与DataOutputStream操作字节数组
ByteArrayInputStream与ByteArrayOutputStream操作字符数组
CharArrayReader与CharArrayWrite操作字符串
StringReader与StringWriter
4.7其它流4.7.1打印流
PrintWriter与PrintStream
这两个打印流的构造函数可以接收的类型。文件的字符串路径。String文件对象。File
字节输出流。InputStream
对于PrintWriter因为是字符流,还可以接收字符输出流。Writer对于字符串路径和文件对象,可以指定字符集参数。对于字节输出流和字符输出流,可以接收自动刷新参数。
注意:该布尔型参数为true,对于println,printf,format三个方法进行自动刷新。
4.7.2序列流
SequenceInputStream
构造函数:
SequenceInputStream(Enumerationen)
SequenceInputStream(InputStrreama,InputStreamb)作用:可以对两个或者两个以上的流进行合并应用:可以用于将多个文件合并成一个文件。
4.8字符编码4.8.1概述
字符流的出现为了方便操作字符。更重要是的加入了编码转换。通过子类转换流来完成。InputStreamReaderOutputStreamWriter
在两个对象进行构造的时候可以加入字符集
4.8.2编码表由来
计算机只能识别二进制数据,早期由来是电信号。为了方便应用计算机,让它可以识别各个国家的文字。就将各个国家的文字用数字来表示,并一一对应,形成一张表。这就是编码表。
4.8.3常见编码表
ASCII:美国标准信息交换码。
用一个字节的7位可以表示。ISO8859-1:拉丁码表。欧洲码表
用一个字节的8位表示。GB2312:中国的中文编码表。
GBK:中国的中文编码表升级,融合了更多的中文文字符号。Unicode:国际标准码,融合了多种文字。
所有文字都用两个字节来表示,Java语言使用的就是unicodeUTF-8:最多用三个字节来表示一个字符。
4.8.4转换流的编码应用
可以将字符以指定编码格式存储。可以对文本数据指定编码格式来解读。指定编码表的动作由构造函数完成。例程:
将“你好”两个字符查指定的utf-8的码表,获取对应的数字,并写入到text.txt文件中。
OutputStreamWriterosw=newOutputStreamWriter(newFileOutputStream(“text.txt”),”utf-8);osw.write(“你好”);osw.close();
读取硬盘上的文件数据,将获取到的数据查指定utf-8的码表来解析该数据。InputStreamReaderisr=newInputStreamReader(newFileInputStream(“text.txt”),”utf-8);char[]buf=newchar[10];intnum=isr.read(buf);
Strings=newString(buf,0,num);System.out.println(s);
传入编码表的方法都会抛出不支持编码异常(UnsupportedEncodingException);
4.8.5字符编码
编码:字符串字节数组解码:字节数组字符串
原则:编错了,无解;编对了,解错了,可解。
5、网络编程
5.1概述5.1.1网络模型
OSI参考模型和TCP/IP参考模型
5.1.2网络通讯要素
(1)IP地址
网络中设备的标识不易记忆,可用主机名
本地回环地址:127.0.0.1主机名:localhost(2)端口号
用于标识进程的逻辑地址,不同进程的标识
有效端口:0~65535,其中0~1024系统使用或保留端口。(3)传输协议
通讯的规则
常见协议:TCP(可靠连接),UDP(非可靠连接)
5.2TCP和UDP5.2.1UDP
将数据及源和目的封装成数据包中,不需要建立连接每个数据报的大小在限制在64k内因无连接,是不可靠协议不需要建立连接,速度快
5.2.2TCP
建立连接,形成传输数据的通道。在连接中进行大数据量传输
通过三次握手完成连接,是可靠协议(详见->3.3.2)必须建立连接,效率会稍低
5.3Socket5.3.1Socket概述
Socket就是为网络服务提供的一种机制。通信的两端都有Socket。
网络通信其实就是Socket间的通信。数据在两个Socket间通过IO传输。
5.3.2UDP传输
DatagramSocket与DatagramPacket建立发送端,接收端。建立数据包。
调用Socket的发送接收方法。关闭Socket。
发送端与接收端是两个独立的运行程序。发送端:
在发送端,要在数据包对象中明确目的地IP及端口。DatagramSocketds=newDatagramSocket();byte[]by=“hello,udp”.getBytes();DatagramPacketdp=newDatagramPacket(by,0,by.length,InetAddress.getByName(“127.0.0.1”),10000);ds.send(dp);ds.close();接收端:
在接收端,要指定监听的端口:
DatagramSocketds=newDatagramSocket(10000);byte[]by=newbyte[1024];DatagramPacketdp=newDatagramPacket(by,by.length);ds.receive(dp);Stringstr=newString(dp.getData(),0,dp.getLength());System.out.println(str+"--"+dp.getAddress());ds.close();
UDP聊天程序:
通过键盘录入获取要发送的信息。将发送和接收分别封装到两个线程中。
5.3.3TCP传输
Socket和ServerSocket建立客户端和服务器端
建立连接后,通过Socket中的IO流进行数据的传输关闭socket
同样,客户端与服务器端是两个独立的应用程序。
5.3.4Tcp传输最容易出现的问题
客户端连接上服务端,两端都在等待,没有任何数据传输。通过例程分析:
因为read方法或者readLine方法是阻塞式。解决办法:自定义结束标记
使用shutdownInput,shutdownOutput方法。
5.4示例5.4.1示例程序一
说明:网络的运用
*对于这部分的程序,必须注意:
*必须服务端和客户端一起编译运行才能测试程序.通常Server代表服务端Client代表客户端
*部分运用到io流的概念,可以通过前面的笔记配合复习
*该程序是简单的通讯和客户端发送功能的演示.
*注意的地方是Socket是客户端的类ServerSocket是服务端的类
*服务端创建了接收端口.同样,客户端也必须发送相对应的端口和服务器的IP.
*这个时候,服务端利用服务端里面的Socket类定义accept监听的方法,他负责监听客户端的IP和端口的发送
*我们可以在服务端用一句打印输出来判定客户端是否链接上.
*由于客户端链接上后,确定能发送数据.所以必须利用客户端的一个方法getOutputStream.
*同样,我们把该套接字外面套上管道,用writeUTF方法发送.
*为了确定能接收到客户端的信息,服务端必须同样建立getInputStream方法,同时也包上管道,利用readUTF方法等待接收*就此所有通讯代码完成*/
客户端:TCPClient.java
importjava.net.*;importjava.io.*;publicclassTCPClient{publicstaticvoidmain(String[]args)throwsException{Sockets=newSocket("127.0.0.1",6611);//发送的地址和端口OutputStreamos=s.getOutputStream();//返回此套接字的输出流。DataOutputStreamdos=newDataOutputStream(os);//建立管道输出dos.writeUTF("客户端发送给服务器数据");//以utf-8为了省空间输入dos.flush();dos.close();s.close();}}
服务端:TCPServer.java
importjava.net.*;importjava.io.*;publicclassTCPServer{publicstaticvoidmain(String[]args)throwsException{ServerSocketss=newServerSocket(6611);//接收的地址和端口while(true){//相当于分配好的端口,后面有个监听器,在两个之间有个插座,当端口和插座连上,就通知监听端Sockets=ss.accept();//侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。//这个是服务端特有的监听客户端的一个方法,他必须死循环,应为他不知道有多少客户端要连他,只能是有一个客户端连他,他就accept监听一次//如果没有客户端链接,就一直等待。。。。直到链接就给监听方法,然后继续等待。。System.out.println("客户端链接成功!");//这段话是测试客户端是否链接上服务端//返回此套接字的输入流
DataInputStreamdis=newDataInputStream(s.getInputStream());//建立输入管道System.out.println(dis.readUTF());//这个也是阻塞方式的,必须等对方写东西过来dis.close();s.close();//关闭此套接字}}}5.4.2示例程序二
客户端:TestSocketClient.java
importjava.net.*;importjava.io.*;publicclassTestSockClient{publicstaticvoidmain(String[]args){InputStreamis=null;OutputStreamos=null;try{Socketsocket=newSocket("localhost",5888);//创建发送地址端口is=socket.getInputStream();//定义输入套接字os=socket.getOutputStream();//定义输出套接字DataInputStreamdis=newDataInputStream(is);//包装管道DataOutputStreamdos=newDataOutputStream(os);dos.writeUTF("客户端");//客户端程序要先写,和服务端先读保持一致Strings=null;if((s=dis.readUTF())!=null);//等客户端写完就要开始读服务端的了,应为服务端开始写了System.out.println(s);//输出服务端的数据dos.close();dis.close();socket.close();}catch(UnknownHostExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}}}
服务端:TestSocketServer.java/****tcp网络同样可以相互发送.*/
importjava.io.*;importjava.net.*;publicclassTestSockServer{publicstaticvoidmain(String[]args){InputStreamin=null;OutputStreamout=null;try{ServerSocketss=newServerSocket(5888);//服务器定义端口Socketsocket=ss.accept();//第一监听端in=socket.getInputStream();//定义输入套接字out=socket.getOutputStream();//定义输出套接字DataOutputStreamdos=newDataOutputStream(out);//包装管道DataInputStreamdis=newDataInputStream(in);//包装管道Strings=null;if((s=dis.readUTF())!=null){//这里,服务端先等待读客户端的方法System.out.println(s);System.out.println("from:"+socket.getInetAddress());//获取地址System.out.println("Port:"+socket.getPort());//获取端口号.是随机分配的}dos.writeUTF("你好,这里是服务端发送的数据");//结束读之后开始写dis.close();dos.close();socket.close();}catch(IOExceptione){e.printStackTrace();}}}
5.4.3示例程序三
说明:使用线程接收到请求,然后使用一个线程对应于一个客户端
客户端:ChatClient.java
importjava.io.*;importjava.net.*;importjava.awt.*;importjava.awt.event.*;publicclassChatClientextendsFrame{TextAreata=newTextArea();
TextFieldtf=newTextField();publicvoidlaunchFrame()throwsException{this.add(ta,BorderLayout.CENTER);this.add(tf,BorderLayout.SOUTH);tf.addActionListener(newActionListener(){publicvoidactionPerformed(ActionEventae){try{StringsSend=tf.getText();if(sSend.trim().length()==0)return;ChatClient.this.send(sSend);tf.setText("");ta.append(sSend+"\\n");}catch(Exceptione){e.printStackTrace();}}});this.addWindowListener(newWindowAdapter(){publicvoidwindowClosing(WindowEvente){System.exit(0);}});setBounds(300,300,300,400);setVisible(true);tf.requestFocus();}Sockets=null;publicChatClient()throwsException{s=newSocket("127.0.0.1",8888);launchFrame();(newThread(newReceiveThread())).start();}
publicvoidsend(Stringstr)throwsException{DataOutputStreamdos=newDataOutputStream(s.getOutputStream());dos.writeUTF(str);}publicvoiddisconnect()throwsException{s.close();}publicstaticvoidmain(String[]args)throwsException{BufferedReaderbr=newBufferedReader(newInputStreamReader(System.in));ChatClientcc=newChatClient();Stringstr=br.readLine();while(str!=null&&str.length()!=0){cc.send(str);str=br.readLine();}cc.disconnect();}classReceiveThreadimplementsRunnable{publicvoidrun(){if(s==null)return;try{DataInputStreamdis=newDataInputStream(s.getInputStream());Stringstr=dis.readUTF();while(str!=null&&str.length()!=0){//System.out.println(str);ChatClient.this.ta.append(str+"\\n");str=dis.readUTF();}}catch(Exceptione){e.printStackTrace();
}}}}服务端:ChatServer.java
importjava.net.*;importjava.util.*;importjava.io.*;importjava.awt.*;importjava.awt.event.*;publicclassChatServerextendsFrame{TextAreata=newTextArea();publicvoidlaunchFrame(){add(ta,BorderLayout.CENTER);setBounds(0,0,200,300);this.addWindowListener(newWindowAdapter(){publicvoidwindowClosing(WindowEvente){System.exit(0);}});setVisible(true);}ServerSocketserver=null;CollectioncClient=newArrayList();publicChatServer(intport)throwsException{server=newServerSocket(port);launchFrame();}publicvoidstartServer()throwsException{
while(true){Sockets=server.accept();cClient.add(newClientConn(s));ta.append("NEW-CLIENT"+s.getInetAddress()+":"+s.getPort());ta.append("\\n"+"CLIENTS-COUNT:"+cClient.size()+"\\n\\n");}}classClientConnimplementsRunnable{Sockets=null;publicClientConn(Sockets){this.s=s;(newThread(this)).start();}publicvoidsend(Stringstr)throwsIOException{DataOutputStreamdos=newDataOutputStream(s.getOutputStream());dos.writeUTF(str);}publicvoiddispose(){try{if(s!=null)s.close();cClient.remove(this);ta.append("Aclientout!\\n");ta.append("CLIENT-COUNT:"+cClient.size()+"\\n\\n");}catch(Exceptione){e.printStackTrace();}}publicvoidrun(){try{DataInputStreamdis=newDataInputStream(s.getInputStream());Stringstr=dis.readUTF();
}while(str!=null&&str.length()!=0){System.out.println(str);for(Iteratorit=cClient.iterator();it.hasNext();){ClientConncc=(ClientConn)it.next();if(this!=cc){cc.send(str);}}str=dis.readUTF();//send(str);}this.dispose();}catch(Exceptione){System.out.println("clientquit");this.dispose();}}}publicstaticvoidmain(String[]args)throwsException{ChatServercs=newChatServer(8888);cs.startServer();}6、Servlet
6.1Servlet基础6.1.1什么是Servlet
Servlet是一种用Java语言编写的Web应用组件
Servlet主要用于动态网页输出,扩展了Web服务器的功能Servlet由Servlet容器进行管理
6.1.2Servlet的优点
(1)可移植性高:
可在不同的操作系统平台和不同应用服务器平台下移植。(2)功能强大:
Servlet可以使用JavaAPI核心的所有功能包括Web访问、图像处理、多线程、JDBC等。(3)模块化:
每一个Servlet可以执行一个特定的任务,并且可以将它们并在一起工作,Serlvet之间是可以通信的。(4)高效持久:
Serlvet一旦载入,就驻留在内存中,用线程的方式加快了响应的速度。
6.1.3Servlet缺点
和传统的CGI方式相同,JavaServlet也是利用输出HTML语句来实现动态网页的,如果用它来开发整个网站,动态部分和静态页面的整合过程将变得无法想象。这就是SUN还要推出JSP的原因。
6.1.4Servlet示例
publicclassServletExampleimplementsServlet{privateServletConfigconfig;privateStringencoding;@Overridepublicvoidinit(ServletConfigconfig)throwsServletException{//这个方法只会执行一次//如果在web.xml文件中你设置了//级别大于0//那么就会在这个web应用启动的时候就初始化,也就是调用这个方法
}//初始化方法,你可以在这里获取初始化的参数,如果你在配置该servlet的时候使用了参数Stringencoding=config.getInitParameter("encoding");System.out.println("Encodingis:------>"+encoding);//在初始化的时候你可以把ServletConfig保存下来,以便以后使用this.config=config;this.encoding=encoding;}@OverridepublicServletConfiggetServletConfig(){returnthis.config;}@Overridepublicvoidservice(ServletRequestrequest,ServletResponseresponse)throwsServletException,IOException{//这里是主要的业务逻辑处理,这里演示输出编码System.out.println("Theencodingis:------------>"+this.encoding);}@OverridepublicStringgetServletInfo(){returnnull;}@Overridepublicvoiddestroy(){//销毁}
6.1.5Servlet注册和运行
Servlet程序必须通过Servlet容器来启动运行,并且储存目录有特殊要求,通常需要存储在\\WEB-INF\\classes\\目录中。
Servlet程序必须在WEB应用程序的web.xml文件中进行注册和映射其访问路径,才可以被Servlet引擎加载和被外界访问。
一个元素用于注册一个Servlet,它包含有两个主要的子元素:和,分别用于设置Servlet的注册名称和Servlet的完整类名。
一个元素用于映射一个已注册的Servlet的一个对外访问路径,它包含有两个子元素:和,分别用于指定Servlet的注册名称和Servlet的对外访问路径.
6.1.6Servlet映射细节
同一个Servlet可以被映射到多个URL上,即多个元素的子元素的设置值可以是同一个Servlet的注册名。
在Servlet映射到的URL中也可以使用*通配符,但是只能有两种固定的格式:一种格式是“*.扩展名”,另一种格式是以正斜杠(/)开头并以“/*”结尾。
6.1.7默认Servlet
如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web
应用程序的缺省Servlet。
凡是在web.xml文件中找不到匹配的元素的URL,它们的访问请求都将交给缺省Servlet处理,也就是说,缺省Servlet用于处理所有其他Servlet都不处理的访问请求。
在\\conf\\web.xml文件中,注册了一个名称为org.apache.catalina.servlets.DefaultServlet的Servlet,并将这个Servlet设置为了缺省Servlet。当访问Tomcat服务器中的某个静态HTML文件和图片时,实际上是在访问这个缺省Servlet。
6.2Servlet详解6.2.1Servlet的API包
JavaServletAPI包中提供的类和接口是用于完成客户端与Servlet对象的交互,主要由两个Java包组成:javax.servlet和javax.servlet.http.
在javax.servlet包中定义了所有的Servlet类都必须实现或扩展的通用接口和类。在javax.servlet.http包中除了实现servlet包中的基本功能外还特别针对于HTTP协议定义了HttpServlet类。
ServletAPI的框架的核心是javax.servlet.Servlet接口,所有的Servlet都必须实现这一接口。
在Servlet接口中定义了5个方法,其中有3方法代表了Servlet的生命周期:init方法,负责初始化Servlet对象service方法,负责响应客户的请求
destroy方法,当Servlet对象退出生命周期时,负责释放占用的资源
友情提示:本文中关于《java学习总结(基础加web)》给出的范例仅供您参考拓展思维使用,java学习总结(基础加web):该篇文章建议您自主创作。
来源:网络整理 免责声明:本文仅限学习分享,如产生版权问题,请联系我们及时删除。