JavaWeb day01 Java 基础加强.ppt day02 Java 基础加强.ppt day03 xml 基础语法和约束.ppt day04 xml 解析.ppt day05 HTTP 协议.ppt day05 JavaWEB 服务器配置使用.ppt day06 HTML&CSS 强化.ppt day06 Servlet 开发.ppt day07 Request&Response 编程.ppt day08 会话与状态.ppt day09 EL 表达式.ppt day09 JSP 技术.ppt day09 JSTL 标签库.ppt day10 JSP 模式和案例.ppt day12 自定义标签库开发.ppt day12 软件国际化.ppt day13 sql 入门.ppt day13 数据库基础强化.ppt day14 Jdbc 入门.ppt day15 Jdbc 事务控制管理.ppt day16 简单 JDBC 框架.ppt day17 JavaScript 基础加强.ppt day17 客户信息管理系统.ppt day18 Servlet 过滤器.ppt day19 Servlet 监听.ppt day19 在线支付.ppt day20 Javamail 开发.ppt day21 文件的上传和下载.ppt 基础加强(重要)\课件 IO 编程强化.ppt 基础加强(重要)\课件 多线程编程和网络编程入门.ppt 基础加强(重要)\课件 集合对象与常用数据结构性能分析.ppt 基础加强(重要)\课件 面向对象设计强化.ppt 面向对象设计强化  面向对象设计强化 ........................................................................................................... 1 重点内容...........................................................................................................................................................................1 面向对象的设计原则 .........................................................................................................................................................1 单一职责原则(SRP)......................................................................................................................................................2 开闭原则(OCP) ............................................................................................................................................................2 不遵循OCP的例子 ............................................................................................................................................................3 里氏代换原则(LSP) ......................................................................................................................................................3 依赖倒置原则(DIP).......................................................................................................................................................4 接口隔离原则(ISP) .......................................................................................................................................................4 合成/聚合复用原则(CARP) ..........................................................................................................................................4 迪米特法则(LoD) .........................................................................................................................................................4 类和对象设计高效原则......................................................................................................................................................4 复合优先于继承 ................................................................................................................................................................5 接口优先于抽象类.............................................................................................................................................................5 定义内部类:优先考虑静态成员类 ....................................................................................................................................5 方法高效设计....................................................................................................................................................................6 谨慎的进行优化 ................................................................................................................................................................6 尽量使用标准的异常 .........................................................................................................................................................6 线程的高效原则 ................................................................................................................................................................7 工厂模式...........................................................................................................................................................................7 简单工厂模式....................................................................................................................................................................7 考虑用静态工厂方法替代构造函数 ....................................................................................................................................8 工厂方法模式....................................................................................................................................................................8 工厂方法模式和简单工厂模式 ...........................................................................................................................................8 抽象工厂模式....................................................................................................................................................................9 单例模式...........................................................................................................................................................................9 单例模式优缺点 ............................................................................................................................................................. 10  重点内容  面向对象的设计原则 单一职责原则、开闭原则、里氏代换原则 、依赖倒置原则、接口隔离原则、合成/聚合复用原则、迪米特法则  面向对象的高效编程原则 类和对象、方法、优化、异常、线程 常用设计模式简介 工厂模式、单例模式 面向对象的设计原则  单一职责原则 开闭原则 里氏代换原则 依赖倒置原则 接口隔离原则 合成/聚合复用原则 迪米特法则 设计的臭味——腐化软件的气味 当软件出现下面任何一种气味时,就表明软件正在腐化 僵化性(Rigidity):很难对系统进行改动,因为每个改动都会迫使许多对系统其他部分的其他改动。 脆弱性(Fragility):对系统的改动会导致系统中和改动的地方在概念上无关的许多地方出现问题。 牢固性(Immobility):很难解开系统的纠结,使之成为一些可在其他系统中重用的组件。 粘滞性(Viscosity):做正确的事情比作错误的事情要困难。 不必要的复杂性(NeedlessComplexity):设计中包含不具任何直接好处的基础结构。 不必要的重复(NeedlessRepetition):设计中包含有重复的结构,而该重复的结构本可以使用单一的抽象进行统一。 晦涩性(Opacity):很难阅读,理解。没有很好的表现出意图。 单一职责原则(SRP)  一个类,只有一个引起它变化的原因 如果一个类有一个以上的职责,这些职责就耦合在了一起 当一个职责发生变化时,可能会影响其它的职责  多个职责耦合在一起,会影响复用性  SRP 中,把职责定义为“变化的原因” 将业务规则和持久化的控制分离 Façade 和 Proxy 模式进行重构   调制解调器的 modem 接口 interfaceModem{  publicvoiddial(Stringpno);  publicvoidhandup();  publicvoidsend(charc);  publicvoidrecv(); } 该接口显示出两个职责,第一个职责是连接管理,第二个职责是数据通信。dial 和 handup 进行调制解调器的连接处理,而 send 和 recv 进行数据通信 分离的 Modem 接口 publicinterfaceDataChannel{  publicvoidsend(charc);  publicvoidrecv(); } publicinterfaceConnection{  publicvoiddial(Stringpno);  publicvoidhandup(); } publicclassModemimplementsDataChannel,Connection{ …… } 开闭原则(OCP)  软件实体(类、模块、函数等)应该是可以扩展的,但是不可修改 遵循开发-封闭原则设计的两个主要特征 对于扩展是开放的 对于更改是封闭的 可复用性好 软件完成以后,仍然可以对软件进行扩展,加入新的功能,非常灵活 。因此,这个软件系统就可以通过不断地增加新的组件,来满足不断变化的需求。  可维护性好 由于对于已有的软件系统的组件,特别是它的抽象底层不去修改,因此,我们不用担心软件系统中原有组件的稳定性,这就使变化中的软件系统有一定的稳定性和延续性  不遵循 OCP 的例子  既不开放又不封闭的 Client STRATEGY 模式:既开放又封闭的 Client  里氏代换原则(LSP)  子类必须能够替换掉它们的基类型 里氏代换原则是对“开-闭”原则的补充 如果两个具体的类 A,B 之间的关系违反了 LSP 的设计 创建一个新的抽象类 C,作为两个具体类的超类,将 A,B 的共同行为移动到 C 中来解决问题  从 B 到 A 的继承关系改为委派关系   在进行设计的时候,我们尽量从抽象类继承,而不是从具体类继承 长方形和正方形的例子不满足 LSP OOD 的 IS-A 关系是就行为方式而言的,行为方式是可以进行合理假设的,是客户程序设计所依赖的  eg:    长方形类:    publicclassRectangle{    ...    setWidth(intwidth){    this.width=width;  }   setHeight(intheight){    this.height=height  } }   正方形类:    publicclassSquare{    ...    setWidth(intwidth){    this.width=width;    this.height=width;  }   setHeight(intheight){    this.setWidth(height);  } }   例子中改变边长的函数:   publicvoidresize(Rectangler){    while(r.getHeight()<=r.getWidth){    r.setHeight(r.getWidth+1);  } } 依赖倒置原则(DIP)  高层模块不应该依赖于底层模块,二者都应该依赖于抽象 抽象不应该依赖于细节。细节应该依赖于抽象 Hollywood 原则: “Don‘t call us, we’ll call you”.程序中所有的依赖关系都应该终止于抽象类和接口针对接口而非实现编程 依赖于抽象的启发式规则: 任何变量都不应该持有一个指向具体类的指针或引用 任何类都不应该从具体类派生 任何方法都不应该覆写他任何基类中的已经实现了的方法  接口隔离原则(ISP)  使用多个专门的接口比使用单一的总接口要好 一个类对另外一个类的依赖性应当是建立在最小的接口上的 一个接口代表一个角色,不应当将不同的角色都交给一个接口 不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构 满足接口隔离原则,调用者只能访问它自己的方法,不能访问到不应该访问的方法 合成/聚合复用原则(CARP)  合成(Composition)和聚合(Aggregation)都是关联(Association)的特殊种类。聚合表示整体和部分的关系,表示“拥有 ”;合成则是一种更强的“拥有”,部分和整体 的生命周期一样 在 OOD 中,有两种基本的办法可以实现复用 合成/聚合 继承  HAS-A 而非 IS-A 迪米特法则(LoD)  迪米特法则可以简单说成:talk only to your immediate friends 一个软件实体应当尽可能少的与其他实体发生相互作用。 每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位  迪米特法则的初衷在于降低类之间的耦合 设计模式的门面模式(Facade)和中介模式(Mediator),都是迪米特法则应用的例子 类和对象设计高效原则  避免创建重复对象 消除过期的对象引用 避免使用终结函数 为所有导出 API 的元素编写文档注释 使类和成员的可访问能力最小化 复合优先于继承 接口优先于抽象类 定义内部类:优先考虑静态成员类 承  继承是复用的用力手段但不是最佳工具 复合优先于继 对普通类跨包继承,是非常危险的 与方法调用不同,继承打破了封装性 例子 InstrumentedHashSet 使用复合的方式可以完全取代继承的复用 复合类不依赖于原有类的实现细节 原有类修改不会影响到复合类 Decorator 模式、STRATEGY 模式  TemplateMethod 模式和 STRATEGY 模式: 继承和委托 接口优先于抽象类  接口和抽象类的本质区别 抽象类允许包含某些方法的实现,接口不允许 只允许单继承,抽象类作为类型定义受到了极大限制 已有的类可以很容易被更新实现新的接口 接口是定义混合类型的理想选择 例如:Comparable、Cloneable 接口使得我们可以构造出非层次结构的类型框架 接口使得安全的增强一个类的功能成为可能 抽象的类的演化比接口演化容易得多 接口一旦广泛实现,再想改变是根本不可能的 定义内部类:优先考虑静态成员类  嵌套类有四种 静态成员类 内部类非静态成员类 匿名类 局部类 非静态成员类每个实例隐含着外围类一个实例 不可以在它的外围类实例之外独立存在 如果你声明的成员类不要求访问外部实例,请使用 static 修饰类的声明 方法高效设计  谨慎选择方法的名字 用接口而不是类 null 避免长长的参数列表 对于参数类型,优先使 返回零长度数组而不是 将局部变量的作用域最小化 第一次使用它的地方声明 几乎每一个局部变量的声明都应该包含一个初始化表达式 for 循环优先于 while 循环 使方法小而集中 谨慎的进行优化  很多计算上的过失都被归咎与效率原因(没有获得必要的效率),而不是其他的原因 失,在 97%的情况下,不成熟的优化是一切问题的根源 不要去计较小的效率上的得 在优化方面,我们应该遵守两条规则: 规则 1:不要做优化 规则 2:还是不要做优化 努力编写好的程序而不是快的程序 SRP 尽量使用标准的异常  专家程序员与缺乏经验的程序员一个最主要的区别是:专家追求高度的代码重用 通用的规则,异常也不例外 代码重用是值得提倡的,这是一条 重用异常的好处 它使你的 API 更加利于学习和使用 可读性更好 异常类越少,内存占用越小 每个方法抛出的异常都要有文档 不要使用空 catch 块 线程的高效原则  问 避免过多的同步 永远不要在循环的外面调用 wait 对共享可变的数据的同步访 使用 wait 循环模式来调用 wait 方法 避免使用线程组 wait 循环模式 synchronized(obj){  while();  obj.wait(); … } 工厂模式  责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类 工厂模式专门负 几种形态 简单工厂(Simple Factory)模式,又称静态工厂方法模式 工厂方法(Factory Method)模式,又称多态性工厂(Polymorphic Factory)模式 抽象工厂(Abstract Factory)模式,又称工具箱(Kit 或 Toolkit)模式  简单工厂模式   工厂类(Creator)角色: 担任这个角色的是工厂方法模式的核心,含有与应用紧密相关的商业逻辑。工厂类在客户端的直接调用下创建产品对象,它往往由一个具体 Java 类实现。 抽象产品(Product)角色: 担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。抽象产品角色可以用一个 Java 接口或者 Java 抽象类实现。 具体产品(Concrete Product)角色: 工厂方法模式所创建的任何对象都是这个角色的实例,具体产品角色由一个具体 Java 类实现。  优点:模式的核心是工厂类。这个类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例。而客户端则可以免除直接创建产品对象的责任,而仅仅负责“消费”产品。简单工厂模式通 过这种做法实现了对责任的分割 缺点(一): 当产品类有复杂的多层次等级结构时,工厂类只有它自己。以不变应万变,就是模式的缺点。 这个工厂类集中了所有的产品创建逻辑,形成一个无所不知的全能类,有人把这种类叫做上帝类(GodClass)。如果这个全能类代表的是农场的一个具体园丁的话,那么这个园丁就需要对所有的 产品负责,成了农场的关键人物,他什么时候不能正常工作了,整个农场都要受到影响。缺点(二): 当产品类有不同的接口种类时,工厂类需要判断在什么时候创建某种产品。这种对时机的判断和对哪一种具体产品的判断逻辑混合在一起,使得系统在将来进行功能扩展时较为困难。 缺点(三): 由于简单工厂模式使用静态方法作为工厂方法,而静态方法无法由子类继承,因此,工厂角色无法形成基于继承的等级结构。 考虑用静态工厂方法替代构造函数  与构造函数的区别 静态工厂方法拥有比构造函数更容易理解的名字 不要求每次调用创建一个新的对象 可以返回一个原返回类型的子类 缺点 类如果不含有子类可见的构造函数,就不能子类化 它们不会像构造函数那样被明确标识 valueOf getInstance 工厂方法模式   抽象工厂(Creator)角色: 担任这个角色的是工厂方法模式的核心,它是与应用程序无关的。任何在模式中创建对象的工厂类必须实现这个接口。在上面的系统中这个角色由 Java 接口 Creator 扮演; 在实际的系统中,这个角色也常常使用抽象 Java 类实现。 具体工厂(Concrete Creator)角色: 担任这个角色的是实现了抽象工厂接口的具体 Java 类。具体工厂角色含有与应用密切相关的逻辑,并且受到应用程序的调用以创建产品对象。在本系统中给出了两个这样的角色,也就是具体 Java 类 ConcreteCreator1 和 ConcreteCreator2。 抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。在本系统中,这个角色由 Java 接口 Product 扮演;在实际的系统中,这个角色也 常常使用抽象 Java 类实现。 具体产品(ConcreteProduct)角色:这个角色实现了抽象产品角色所声明的接口。工厂方法模式所创建的每一个对象都是某个具体产品角色的实例。 工厂方法模式和简单工厂模式  工厂方法模式可以允许很多具体工厂类从抽象工厂类中将创建行为继承下来,从而可以成为多个简单工厂模式的综合,进而推广了简单工厂模式 工厂方法模式的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上抽象工厂模式   抽象工厂(AbstractFactory)角色: 担任这个角色的是工厂方法模式的核心,它是与应用系统的商业逻辑无关的。通常使用 Java 接口或者抽象 Java 类实现,而所有的具体工厂类必须实现这个 Java 接口或继 承这个抽象 Java 类。 具体工厂类(Conrete Factory)角色: 这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。通常使用具体 Java 类实现 这个角色。 抽象产品(Abstract Product)角色: 担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。通常使用 Java 接口或者抽象 Java 类实现这一角色。 具体产品(Concrete Product)角色: 抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。通常使用具体 Java 类实现这个 角色。  在什么情形下应当使用抽象工厂模式? (1)一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节。这对于所有形态的工厂模式都是重要的; (2)这个系统的产品有多于一个的产品族,而系统只消费其中某一族的产品; (上面这一条叫做抽象工厂模式的原始用意。) (3)同属于同一个产品族的产品是在一起使用的,这一约束必须要在系统的设计中体现出来; (4)系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。 单例模式  对于系统中的某些类来说,只有一个实例很重要  实现要点 一、Singleton 类通过共有的静态方法 getInstance 获取实例,并且每次获取实例相同 二、Singleton 类没有共有的构造函数  饿汉式和懒汉式 单例模式饿汉式 publicclassEagerSingleton{  privatestaticfinalEagerSingletoninstance=newEagerSingleton();  privateEagerSingleton(){} publicstaticEagerSingletongetInstance(){ returninstance; } }  懒汉式 publicclassLazySingleton{  privatestaticLazySingleton instance=null; privateLazySingleton(){} synchronizedpublicstaticLazySingletongetInstance(){  if(instance==null) instance=newLazySingleton();  returninstance; } }   饿汉式单例与懒汉式单例类比较 饿汉式单例类在自己被加载时就将自己实例化。单从资源利用效率角度来讲,这个比懒汉式单例类稍差些。从速度和反应时间角度来讲,则比懒汉式单例类稍好些。 懒汉式单例类在实例化时,必须处理好在多个线程同时首次引用此类时的访问限制问题,特别是当单例类作为资源控制器,在实例化时必然涉及资源初始化,而资源初始化很有可能耗费大量时间,这 意味着出现多线程同时首次引用此类的机率变得较大,需要通过同步化机制进行控制。 单例模式优缺点  优点 提供了对惟一实例的受控访问 可以节约系统资源 允许可变数目的实例 缺点 单例类的扩展有很大的困难 单例类的职责过重(工厂和产品角色) 滥用单例将带来一些负面问题  模式适用环境 在以下情况下可以使用单例模式: 系统只需要一个实例对象,如系统要求提供一个惟一的序列号生成器,或者需要考虑资源消耗太大而只允许创建一个对象。 客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。 补充:在一个系统中要求一个类只有一个实例时才应当使用单例模式。反过来,如果一个类可以有几个实例共存,就需要对单例模式进行改进,使之成为多例模式集合对象与常用数据结构性能分析    集合对象与常用数据结构性能分析................................................................................... 1 重点内容...........................................................................................................................................................................1 数组回顾...........................................................................................................................................................................2 JDK5.0 新特性之泛型.......................................................................................................................................................2 泛型的定义格式举例 .........................................................................................................................................................3 数组的不足之处 ................................................................................................................................................................3 Collection接口 ................................................................................................................................................................4 List接口 ...........................................................................................................................................................................5 ArrayList类 .....................................................................................................................................................................5 LinkedList类 ...................................................................................................................................................................6 访问集合的标准操作 .........................................................................................................................................................6 for循环  / foreach循环....................................................................................................................................................6 迭代器Iterator.................................................................................................................................................................7 迭代器Enumeration(了解) ..............................................................................................................................................7 Set接口............................................................................................................................................................................8 HashSet类.......................................................................................................................................................................8 SortedSet接口 ................................................................................................................................................................8 TreeSet类 ........................................................................................................................................................................8 Map接口..........................................................................................................................................................................9 Map实现类的比较............................................................................................................................................................9 Map的遍历方法 ............................................................................................................................................................ 10 旧版集合的对比 ............................................................................................................................................................. 10 常用的数据结构 ............................................................................................................................................................. 10 数组Arrays ................................................................................................................................................................... 11 线性表 ........................................................................................................................................................................... 11 链表............................................................................................................................................................................... 11 二叉树简介 .................................................................................................................................................................... 11 哈希表简介 .................................................................................................................................................................... 11 Collections类............................................................................................................................................................... 12  重点内容  数组的回顾与排序 泛型 常用集合框架接口和实现类 Collection List Set Map 常用数据结构分析 工具类 Collections 的 API 数组回顾  基本类型的数组 对象数组 java.util.Arrays sort() binarySearch() toString()    Arrays 类中的 sort 方法需要对数组进行排序,必须首先知道怎么判断数组中两个元素的大小。 对于基本类型的数组,非常容易比较两个元素的大小,但对于对象数组,例如图中的 Dog 数组,Arrays 类无法判断两个数组元素的大小。 Java 中通过 Comparable 接口把比较大小的任务交由对象自身,实现了 Comparable 接口的对象具有同其他对象比较大小的能力。 Comparable 接口 publicclassDogimplementsComparable{ privateStringname; publicDog(Stringname){                 this.name=name; }  @Override publicintcompareTo(Dogo){ returnname.compareTo(o.name); } }  Comparable 接口的含义是“能够比较大小的”,一个类实现了 Comparable 接口,就需要实现 compareTo 方法, 这样java.util.Arrays中的sort方法或者binarySearch方法就可以调用 Dog 类的 compareTo 方法来比较两个对象谁大谁小。 Comparable接口中compareTo约定,如果返回值是负数,表示当前对象(this)比传入对象小;返回零表示二者“一样大”,返回整数表示当前对象大。 Java类库中的很多类都实现了 Comparable 接口,包括常见的 String 类。   如果程序中有时需要根据 Dog 的名字进行排序,有时需要根据 Dog 的年龄来排序,这时可以使用 Comparator 接口。 Arrays.sort方法可以接受一个 Comparator 的实例,Comparator 可以看作一个比较器。详细资料可参见 JavaAPI 文档。 JDK5.0 新特性之泛型  泛型(Generic)是参数化类型的能力 可以在类,接口或者方法中声明一个泛型类型,并且在使用这个类,接口或者方法的时候指定具体的类型 publicclassDogimplementsComparable{ //… publicintcompareTo(Dogdog){ returnname.compareTo(dog.name); } }  泛型是 Java5 中引入的新特性。泛型出现以前,类似于 Comparable 这样的接口和之后要学习的集合框架中,很多方法的参数或返回值的类型是 Object。实际使用过程中经常需要先进行类型转换。 泛型引入后,在使用这些类或接口时,在类名之后用<>对想要处理的类型加以限制,这样原来是 Object 类型的参数和返回值被限制为<>内声明的类型。 本例演示了 Java1.4 和 5.0 中要完成同样功能的区别。使用泛型后,代码会简洁得多。 在Java的API文档中具备泛型特性的类或方法名后一般用说明  没有泛型时 Java1.4 的代码 publicclassDogimplementsComparable{ //… publicintcompareTo(Objectobject){ Dogdog=(Dog)object; returnname.compareTo(dog.name); } } 泛型的定义格式举例  public class ArrayList { publicEget(intindex){…} publicvoidadd(Ee){…} … } public TreeSet(Collection c) { … } public TreeSet(Comparator comparator) { … } public interface Comparator { … } 自定义范例示例 classSwapper{ privateTfirst; privateTsecond; publicSwapper(Tfirst,Tsecond){ this.first=first; this.second=second; } publicvoidswap(){ Ttemp=first; first=second; second=temp; } publicTgetFirst(){ returnfirst; } publicTgetSecond(){ returnsecond; } } 数组的不足之处  容量不能自动调整 查找效率低 可采用 Arrays.binarySearch 方法,但必须实现 Comparable 接口 binarySearch 方法本身的效率也不高 如何在 Java 中实现常用的数据结构? 链表 栈 堆 队列 哈希表 …  数组的不足之处可以通过使用 Java 中的集合框架类库来弥补。 集合框架中定义了很多容器类型,每种类型的容器均有自己的特点和适用的范围,这些容器都可以自动调整容量。 集合框架结构  Collection 接口   表示一组对象 基本操作 add-添加一个元素 addAll-添加另一个 Collection 中所有元素 contains-是否包含某个元素 remove-从集合中删除一个元素 removeAll,containsAll,retainAll isEmpty-集合中是否有元素 size-集合中元素的个数 clear-清空所有元素 toArray-转成一个数组iterator-得到一个用于遍历该集合的迭代器  Collection 表示一组对象,其中的对象称为元素。 Collection抽象了很多容器的基本操作,主要涉及三类: 添加元素 删除元素 遍历和查找集合中的元素  Collection接口不要求元素的唯一性,元素之间也不要求有顺序。List 接口和 Set 接口都继承自 Collection 接口,这些子接口或多或少的对 Collection 中的元素加以限制,同时提供了更多的操 作方法。 因为Collection是一个接口,需要构造一个实现这个接口的类来测试这些方法,具体方法的例子参见 ArrayList。 List 接口    继承 Collection 接口 特性 元素具有顺序 元素可以重复 新增操作 set –将元素放入指定位置 get –取得指定位置的元素  publicvoidadd(intindex,Objectelement) publicObjectremove(intindex)  publicObjectget(intindex) publicObjectset(intindex,Objectelement) publicintindexOf(Objecto)  publicintlastIndexOf(Objecto) ArrayList 类   特性 使用数组实现的 List,自动调整容量 新增操作 indexOf/lastIndexOf 查找某个元素在 ArrayList 中的位置 ensureCapacity/trimToSize 调整内置数组的长度 可以对元素快速的随机访问; 向 ArrayList 插入或删除元素的速度较慢  LinkedList 类   特性 使用链表形式实现的 List 可以方便的实现栈、队列、双向队列 新增操作 addFirst/addLast 实现将元素插入到列表的开头或结尾 getFirst/getLast 返回此列表中的第一个或最后一个元素 removeFirst/removeLast 移除并返回此列表中的第一个或最后一个元素 便于元素的插入和删除,随即访问的速度较慢  使用 LinkedList 实现栈结构 publicclassMyStack{ privateLinkedListlinkedList=newLinkedList();//定义一个 LinkedList 对象 publicvoidpush(Objecto){//将元素存入栈 linkedList.add(o); } publicObjectpop(){//从栈内取出元素 returnlinkedList.removeFirst(); } publicObjectpeek(){//得到栈顶元素 returnlinkedList.getFirst(); } publicbooleanempty(){//判断栈是否为空 returnlinkedList.isEmpty(); } } 访问集合的标准操作  for 循环 / foreach 循环 Iterator ListIterator Enumeration 输出 for 循环  / foreach 循环  // 遍历列表元素方式之一:for 循环遍历 for(inti=0;i<list.size();i++){  Objecto=list.get(i);  System.out.println(o);} // 遍历列表元素方式之二:foreach 循环遍历(JDK5.0 以上版本) //  for(元素类型 Integer  元素变量 num: 遍历对象 list){ for(Integernum:list){    System.out.println(num); }  foreach 语句是 java5.0 的新特征之一,在遍历数组、集合方面,提供了极大的方便。  foreach 并不是一个关键字,习惯上将这种特殊的 for 语句格式称之为“foreach”语句。  相对之前的 for 语句来说是个很好的补充。  对集合、数组索引的情况下,foreach 显得力不从心,需要用 for 语句。 迭代器 Iterator  Iterator 接口用途是把集合中元素的内容按序排列取出后,可一个个读取 方法 hasNext-如果仍有元素可以迭代,返回 true next-返回迭代的下一个元素 remove-从迭代器指向的集合中移除迭代器返回的最后一个元素 代码 Iteratoriterator=list.iterator(); while(iterator.hasNext()){     Objecto=iterator.next(); }  迭代器 ListIterator(了解) ListIterator 接口继承了 Iterator 接口,并作了扩展 (API – java.util.ListIterator) 1).  ListIterator 有 add()方法,可以向 List 中添加对象,而 Iterator 不能 2).  ListIterator 和 Iterator 都有 hasNext()和 next()方法,可以实现顺序向后遍历,但是 ListIterator 有 hasPrevious()和 previous()方法,可以实现逆向(顺序向前)遍 历。Iterator 就不可以 3).ListIterator 可以定位当前的索引位置,nextIndex()和 previousIndex()可以实现。Iterator 没有此功能 4).ListIterator 的 set()方法可以实现对象的修改。Iterator 仅能遍历,不能修改 迭代器 Enumeration(了解)  Enumeration 已经不是主流,Iterator 是它的下一代替代品。构建一个 Enumeration 迭代器 : Enumerationenumeration= 被迭代的集合对象.elements() 实现该接口的对象由一系列的元素组成,可以连续地调用 nextElement()方法来得到 Enumeration 枚举对象中的元素 遍历 Vector 的代码Vectorlist=newVector(); Enumerationenumeration=list.elements(); while(enumeration.hasMoreElements()){  System.out.println(enumeration.nextElement()); } Set 接口   继承 Collection 接口 特性 元素没有顺序 元素不可以重复 HashSet 类   基于 HashMap 实现 HashSet 是无序集合的类 LinkedHashSet 按照插入集合的顺序提取集合中的元素 因操作(查询、插入、删除等)速度快,比较适用于内容规模较大的元素 SortedSet 接口  扩展了 Set 接口 元素按升序排序 添加到 SortedSet 实现类的元素必须实现可比较 Comparable 接口,否则我们必须给它的构造方法提供一个 Comparator 接口的实现。 SortedSet 常用方法: publicObjectfirst() publicObjectlast() publicSortedSetheadSet(ObjecttoElement) publicSortedSettailSet(ObjectfromElement) TreeSet 类  实现了 SortedSet 接口 是有序的集合类 基于 HashMap 实现 采用平衡二叉树的实现方式 操作速度较慢 遍历 Set 使用迭代 Iterator 遍历 foreach 循环遍历 Map 接口    表示一个映射 特性 将键映射到值 键不能重复 值可以重复 方法 put-添加一个“值”(想要的东西)和与“值”相关联的“键”(使用它来查找) keySet-返回由 Map 的“键”组成的 Set(确保不重复) get-返回与给定“键”相关联的“值” values-返回一个 Collection,包含 Map 中的所有“值”(可重复)  publicObjectput(Objectkey,Objectvalue) publicObjectget(Objectkey) publicObjectremove(Objectkey) 批处理操作方法:putAll() 、 clear() 获取集合数据的方法:keySet()、values() 和 entrySet()  Map 实现类的比较  HashMap 以哈希表为内核实现 Map 接口 key-valuepairs 的顺序和放入的顺序无关。 Key 不能重复, 后加入的值会覆盖原来的值 LinkedHashMap 以哈希表和链表为内核实现 map 接口 key-valuepairs 的顺序是放入的顺序。 Key 不能重复, 后加入的值会覆盖原来的值 TreeMap 以二叉树为内核实现 map 接口key-valuepairs 的顺序是按照 key 的升序进行排列 Key 不能重复, 后加入的值会覆盖原来的值 Map 的遍历方法  1). values() 返回所有值(value)的集合,是一个 Collection 2). keySet() 返回所有键对象的集合,是一个 Set 集合; 遍历这个 Set,用 get()方法来获得 Key 所对应的 value,也就遍历了 Map 3). Map 的 entrySet()方法可以返回一个 Set 集合,在 Set 集合中存放的是 Map.Entry 类型的对象,每个 Entry 代表 Map 中的一对(键,值) Map 遍历范例代码: publicstaticvoidmain(String[]args){ Mapmap=newHashMap(); map.put("1","one");map.put("2","two");map.put("3","three");  map.put("4","four"); //遍历方法 1:keySet() 返回此映射中包含的键的 Set 视图。 Iteratoriterator=map.keySet().iterator(); while(iterator.hasNext()){ Stringstr=iterator.next(); System.out.println("key:"+str+",value:"+map.get(str)); } //遍历方法 2:返回此映射中包含的映射关系的 Set 视图。 Iterator>it=map.entrySet().iterator(); while(it.hasNext()){ Map.Entryentry=it.next(); System.out.println(entry.getKey()+"---"+entry.getValue()); } } 旧版集合的对比  Enumeration vs. Iterator Enumeration 是一个传统的集合遍历工具 Dictionary vs. Map Dictionary 是一个现在已经被标记为 deprecated 的类,实现了老版本中的映射功能,现在已经完全被 Map 取代。 Dictionary 不 key 和 value 不能为 null,但 Map 却允许空的关键字和值 Vector vs. ArrayList Vector 和 ArrayList 是数组在 JCF(JavaCollectionsFramework)中的体现 主要区别在于:Vector 是线程同步集合;ArrayList 并不是线程同步的 Hashtable vs. HashMap Hashtable 是 Dictionary 子类,HashMap 是 Map 的子类 区别 Hashtable 是同步的,但 HashMap 不是 Properties 是 Hashtable 的子类,至今常用 常用的数据结构  数组 线性表 链表 哈希表 二叉树 数组 Arrays  长度固定,改变长度时,需要新建数组  线性表  类似于数组,实现类有 ArrayList 等  链表  不支持快速随机访问,修改、删除操作速度快,只修改链接即可,不影响其他元素 使用链表实现的集合类 LinkedHashMap LinkedHashSet LinkedList  二叉树简介  有排序的功能 数据的存取较慢 使用链表实现的集合类: TreeMap TreeSet  哈希表简介  数据以 key value paired 的形式存在(一个元素包含一个 key 和一个 value) 由 key 可以取得 value 数据读取速度快 占用较多内存空间  HashMap:该类是 Java 中哈希表最典型的实现类,程序员使用最多的类,通过使用 put(key,value)方法放入新的元素,如果原来已存在相同 key 的元素,则新的元素会覆盖原来的元素; Hashtable:该类的功能和 Hashmap 是类似的,但出现得比 Hashmap 更早,Hashtable 是线程安全的,但是 Hashmap 的性能更好,现在一般都是用 Hashmap,很少使用 Hashtable 了; LinkedHashMap:标准的哈希表里面的元素是没有顺序的,只能通过 key 来查找,如果某些情况下需要哈希表保持元素的排列顺序,则要使用 LinkedHashMap。 Collections 类  在 JDK 中提供了操作数组的 java.util.Arrays 类,为操作 java 数组提供了一系列的静态方法 在 JDK 中,提供了 java.util.Collections 类,可以用于操作 List 类型的集合,也可以用于操作所有的 Collection 类型或 Map 类型的集合 Collections 类以下的方法操作 List 类型的集合  调用其静态方法,可实现 binarySearch():折半查找 sort(): 排序 reverse():将线性表进行逆序操作 rotate():以某个元素为轴心将线性表“旋转” swap():交换一个线性表中两个元素的位置 。。。(查 API,阅读源码) 封装器功能,把一个集合转化成另一个特殊集合 unmodifiableXXX:转换成只读集合,这里 XXX 代表六种基本集合接口:Collection、List、Map、Set、SortedMap 和 SortedSet synchronizedXXX:转换成同步集合 。。。 I/O 编程强化    I/O编程强化 ................................................................................................................... 1 重点内容...........................................................................................................................................................................1 流(Stream)......................................................................................................................................................................1 流的意义...........................................................................................................................................................................2 InputStream...................................................................................................................................................................3 OutputStream................................................................................................................................................................4 File对象............................................................................................................................................................................5 File常用操作.....................................................................................................................................................................5 FileInputStream.............................................................................................................................................................6 FileOutputStream..........................................................................................................................................................6 SequenceInputStream ..................................................................................................................................................7 RandomAccessFile ........................................................................................................................................................7 装饰者模式:过滤流 .........................................................................................................................................................7 过滤流:缓冲流 ................................................................................................................................................................7 过滤流:数据流 ................................................................................................................................................................8 PrintStream....................................................................................................................................................................9 标准输入输出流 ................................................................................................................................................................9 字节流:对象流 ............................................................................................................................................................. 10 字节流:管道流 ............................................................................................................................................................. 11 Reader ......................................................................................................................................................................... 11 Writer .......................................................................................................................................................................... 12 字节流转换为字符流 ...................................................................................................................................................... 12 BufferedReader和BufferedWriter ............................................................................................................................ 12 Properties ................................................................................................................................................................... 13  重点内容  流及其意义 字节输入输出流 File 对象和文件输入输出流 常用过滤流 对象持久化 管道流 字符输入输出流 字节流向字符流的转换 流(Stream)  输入流 输出流   流是数据序列的抽象概念。对于一个程序来说,输入流用来读取数据,输出流用来写数据。 文件、网络连接、内部进程间的通信管道、内存都可以被看作是流,也就是程序可以从中读取数据,或向其写入数据。 流提供了一种用统一的方式从各种各样的输入输出设备中读取和写入数据的方法。 如果一个程序支持从文件中读取数据进行处理,那这个程序可以很容易的修改成从网络中读取数据并处理。 流的意义  流的概念使得文件、网络、内存等设备可以被统一处理   流一般分为输入流(InputStream)和输出流(OutputStream)两类,但这种划分并不是绝对的。比如一个文件,当向其中写数据时,它就是一个输出流;当从其中读取数据时,它就是一个输入流。 当然,键盘只是一个输入流,而屏幕则只是一个输出流。 在Java开发环境中,主要是由包 java.io 中提供的一系列的类和接口来实现输入/输出处理。标准输入/输出处理则是由包 java.lang 中提供的类来处理的,但这些类又都是从包 java.io 中的类继承 而来。 字节输入流结构   在 JDK1.1 之前,java.io 包中的流只有普通的字节流(以 byte 为基本处理单位的流),这种流对于以 16 位的 Unicode 码表示的字符流处理很不方便。 从JDK1.1开始, java.io 包中加入了专门用于字符流处理的类(以 Reader 和 Writer 为基础派生的一系列类)。 另外,为了使对象的状态能够方便地永久保存下来, JDK1.1 以后的 java.io 包中提供了以字节流为基础的用于对象的永久化保存状态的机制(通过实现 ObjectInput 和 ObjectOutput 接口)   这里列出了非常多的类,在学习时可以从以下角度入手:  先看父类提供了哪些操作,  看每个类想要实现的功能是什么,看这个类实现了哪个接口,有没有新增的操作,  看每个类提供了哪些构造方法,如何创建这些类的实例。InputStream  字节输入流的基类  常用读取数据方法  intread():从输入流中读一个字节,形成一个 0~255 之间的整数返回(是一个抽象方法)  intread(byteb[]):读多个字节到数组中,填满整个数组  intread(byteb[],intoff,intlen):从输入流中读取长度为 len 的数据,写入数组 b 中从索引 off 开始的位置,并返回读取得字节数 对于这三个方法,若返回-1,表明流结束  其他方法  skip():跳过流中若干字节数  available():返回流中可用字节数  mark():在流中标记一个位置  reset():返回标记过得位置  markSupport():是否支持标记和复位操作  close():关闭流 InputStream 读取数据的标准代码 InputStreamin=XXX; intdata; try{   while((data=in.read())!=-1){ //process } }catch(IOExceptione){   e.printStackTrace(); }finally{ try{ in.close();   }catch(IOExceptione){ e.printStackTrace(); } }  InputStreamin=null; byte[]buf=newbyte[1024]; intlen;try{   while((len=in.read(buf))!=-1){ //process } }catch(IOExceptione){   e.printStackTrace(); }finally{ try{ in.close();   }catch(IOExceptione){ e.printStackTrace(); } }  InputStream 是抽象了所有输入流最基本的操作。 read方法用来读入数据,不带参数的 read 方法一次读入一个字节,返回值表示读入的数据; 带byte数组的方法一次可读入多个字节,返回值表示本次读入了多少个字节。 注意,当读到一个流的结尾时,这两个方法的返回值为-1,因此一般通过一个循环读入一个输入流中的所有数据:详细范例代码参见 FileInputStream。  close方法用来关闭输入流,大多数输入流在使用完毕后都需要调用 close 方法关闭输入流。 当在程序中创建一个 IO 流对象时,计算机内存中实际上产生了两个事物,一个是 java 程序中类的实例对象,一个是系统本身产生的某种资源,以后讲到的 socket 等都是这样的情况。 Java垃圾回收器只能管理程序中的类的实例对象,没法去管理系统产生的资源,所以程序需要调用 close 方法,去通知系统释放自身产生的资源。 字节输出流结构  OutputStream  字节输出流的基类   常用方法  write(intb):将一个整数输出到流中(只输出低位字节,为抽象方法)  write(byteb[]):将字节数组中的数据输出到流中 write(byteb[],intoff,intlen):将数组 b 中从 off 指定的位置开始,长度为 len 的数据输出到流中  flush():刷空输出流,并将缓冲区中的数据强制送出  close():关闭流  同 InputStream 类似,OutputStream 是抽象了所有输出流最基本的操作。 write(int)方法一次向输出流中写入一个字节,write(byte[])一次写入多个字节。 flush方法对于带有缓存的输出流起作用,用于将缓存的内容写出到底层的输出流中。 close方法用来关闭输出流,释放资源,大多数输入流在使用完毕后都需要调用 close 方法关闭输入流。 File 对象  在 I/O 处理中,最常见的就是对文件的操作 File 对象代表磁盘上的文件或目录 构造方法 File(Fileparent,Stringchild) File(Stringpathname) File(Stringparent,Stringchild) File(URLuri) 举例 Filefile=newFile("c:\\temp","abc.txt") Filefile=newFile(".."+File.separator+"examples"+    File.separator+“abc.txt");   File 这个类代表磁盘上的文件,但并不是文件中的内容。可以把 File 对象想象成文件的路径,而不是文件本身。  如果文件名指定的文件存在,可以通过 File 对象来查看文件属性,对文件进行相关处理,例如改名,删除等。   File.separator 与系统有关的默认名称分隔符,出于方便考虑,它被表示为一个字符串。 创建一个文件需要注意: 在字符串中要使用”\”符号时,需要连续输入两个,即”\\”,因为”\”为转移字符。  如果没有指定路径名称的话,那么就会以程序正在运行的目录为文件存放的路径,例: Filefile=newFile(“abc.txt”); 这里要非常注意的是,上面的例子中是以 Windows 系统为例,只有 Windows 系统才有磁盘号,而且目录的分隔符号(separator)是”\”。不过在 Linux 和 Unix 的系统中,目录的分隔号是”/”, 刚好跟 Windows 所使用的相反,在 Java 编程中总是可以使用分隔符/。 用System类来取得系统参数 os.name,例如:System.getProperty(“os.name”)。 File 常用操作  Filef=newFile(“data\temp.dat”); f.getName():返回文件名   temp.dat f.getParent():返回文件所在目录名   data f.getPath():返回文件路径  data\temp.dat f.getAbsolutePath():返回绝对路径  …\data\temp.dat f.exists():文件是否存在 f.canWrite(),f.canRead():文件是否可写、读 f.isFile(),f.isDirectory():是否为文件或目录 f.lastModified(),f.length(),f.delete():文件的最后修改日期、长度;删除文件f.mkdir(),f.list():创建一个目录;列出目录下所有文件  deleteOnExit()-虚拟机终止时删除 文件目录遍历补充 String[]fileNames=f.list(); String[]fileNames=f.list(newFilenameFilter(){ publicbooleanaccept(Filedir,Stringname){ returnfalse; } }); File[]files=f.listFiles(); File[]files=f.listFiles(newFileFilter(){ publicbooleanaccept(Filepathname){ returnfalse; } }); File 类的静态方法 createTempFile() listRoots()-返回文件系统的 root 名,windows 系统上,例如 c:\,d:\ FileInputStream  将磁盘上的文件变成输入流  构造方法 FileInputStream(StringfileName) FileInputStream(Filefile) 例如 InputStreamin=newFileInputStream("D:/1.txt"); FileOutputStream  将磁盘上的文件变成输出流  构造方法 FileOutStream(StringfileName) FileOutStream(StringfileName,booleanappend) FileOutStream(Filefile) FileOutStream(Filefile,booleanappend) 例如 OutputStreamout=newFileOutputStream("d:/3.txt");OutputStreamout=newFileOutputStream("d:/1.txt",true); SequenceInputStream  将两个输入流合并成一个输入流  构造方法 SequenceInputStream(InputStreams1,InputStreams2); RandomAccessFile  对于 InputStream 和 OutputStream 来说,它们的实例都是顺序访问流,即只能进行顺序读/写 类 RandomAccessFile 则允许对文件内容同时完成读和写操作 提供了支持随机文件操作的方法 readXXX()或 writeXXX(): 如 ReadInt(),ReadLine(),WriteChar(),WriteDouble()等。  intskipBytes(intn):将指针向下移动若干字节  length():返回文件长度  longgetFilePointer():返回指针当前位置  voidseek(longpos):将指针调到所需位置  在生成一个随机文件对象时,除了么指明文件对象和文件名之外,还需要指明访问文件的模式。 Filef=newFile(“file.txt”); newRandomAccessFile(f,“r”); newRandomAccessFile(f,“rw”); newRandomAccessFile(“file1.txt”,“r”); newRandomAccessFile(“file2.txt”,“rw”); 装饰者模式:过滤流  java.io 中提供类 FilterInputStream 和 FilterOutputStream 分别对其他输入/输出流进行特殊处理,它们在读/写数据的同时可以对数据进行特殊处理 提供了同步机制,使得某一时刻只有一个线程可以访问一个输入/输出流 使用过滤流 FilterInputStream(InputStreamin); FilterOutputStream(OutputStreamout);  类 FilterInputStream 和 FilterOutputStream 分别重写了父类 InputStream 和 OutputStream 的所有方法,同时它们的子类也应该重写它们的方法以满足特定需要。 过滤流:缓冲流  BufferedInputStream BufferedOutputStream   对于有些输入流,例如文件输入流,一次只从磁盘上读取一个字节的效率非常低。磁盘读写效率最高的方式是按块读写。 可以使用 read(byte[])方法一次读入多个字节,但这样得到的是一个字节数组,有时在程序中处理起来并不方便。 BufferedInputStream提供了缓冲的功能,类似于 SequenceInputStream,BufferedInputStream 本身不提供数据,它依赖于其他输入流。 在构造BufferedInputStream时,需要指定这个输入流是什么,也可以指定缓冲区的大小。 从BufferedInputStream中读取数据时,如果缓冲区中有内容,读取过程相当于内存操作; 如果缓冲区中的内容已经读完,BufferedInputStream 会负责从底层的输入流中读取数据到缓冲区,直至读到底层输入流的末尾或者缓冲区读满。 将缓冲流与文件流相接 FileInputStreamin=newFileInputStream(“file1.txt”); FileOutputStreamout=newFileOutputStream(“file2.txt”); BufferedInputStreambin=newBufferedInputStream(in,256)  BufferedOutputStreambout=newBufferedOutputStream(out,256); intlen; bytebArray[]=newbyte[256]; len=bin.read(bArray);  //len 中得到是长度,bArray 中得到的是数据 对于 BufferedOutputStream,只有缓冲区满时,才会将数据真正送到输出流,但可以使用 flush()方法人为地将尚未填满的缓冲区中的数据送出 过滤流:数据流  数据流类 DataInputStream 和 DataOutputStream 的处理对象除了是字节或字节数组外,还可以实现对文件的不同数据类型的读写   publicstaticvoidmain(Stringargs[])throws  IOException{ FileOutputStreamfos=newFileOutputStream(“a.txt”); DataOutputStreamdos=newDataOutputStream(fos); try{ dos.writeBoolean(true); dos.writeByte((byte)123); dos.writeChar('J'); dos.writeDouble(3.141592654); dos.writeFloat(2.7182f); dos.writeInt(1234567890);dos.writeLong(998877665544332211L); dos.writeShort((short)11223); }finally{ dos.close(); } FileInputStream  fis=newFileInputStream("a.txt") DataInputStreamdis=newDataInputStream(fis); try{ System.out.println("\t"+dis.readBoolean()); System.out.println("\t"+dis.readByte()); System.out.println("\t"+dis.readChar()); System.out.println("\t"+dis.readDouble()); System.out.println("\t"+dis.readFloat()); System.out.println("\t"+dis.readInt()); System.out.println("\t"+dis.readLong()); System.out.println("\t"+dis.readShort()); }finally{ dis.close(); } } PrintStream  为输出流提供 print 方法 新增操作 print printf println 构造方法 PrintStream(OutputStream) PrintStream(File) …  PrintStream 为输出流提供了一系列的 print 方法。 另外PrintStream中的print方法不会抛出 IOException。  println方法的换行符可以通过调用以下方法获得: System.getProperty("line.separator"); 标准输入输出流  语言包 java.lang 中的 System 类管理标准输入/输出流和错误流 System.in:InputStream,用于从标准输入设备中获取输入数据(通常是键盘) System.out:PrintStream,把输出送到缺省的显示设备(通常是显示器) System.err:PrintStream,把错误信息送到缺省的显示设备(通常是显示器) 每当 main 方法执行时,就自动生成上述三个对象  标准输入输出是操作系统提供的输入输出流,默认情况下: 标准输入 System.in 对应键盘的输入,是 InputStream 类型的,程序使用 System.in 可以读取从键盘上输入的数据; 标准输出 System.out 对应控制台,是 PrintStream 类型的; 标准错误输出 System.err 默认情况下也会输出到控制台,在 Eclipse 开发环境中,标准错误输出打印出的内容用红色字体显示。  在操作系统中,可以使用重定向将标准输出和标准错误输出重定向到文件中,也可以将一个文件的内容作为标准输入。例如 将标准输出内容重定向到 1.txt diraaaaa.txt>1.txt 将标准错误输出的内容重定向到 2.txt diraaaaa.txt2>2.txt 将一个文件作为标准输入 javaTest<1.txt(这时,使用System.in读入的内容就是 1.txt 文件中的内容) 对象的持续性(persistence) 能够纪录自己的状态以便将来再生的能力,叫对象的持续性 对象的串行化(Serialization) 对象通过写出描述自己状态的的数值来记录自己的过程叫串行化。串行化的主要任务是写出对象实例变量的数值,如果变量是另一个对象的引用,则引用的对象也要串行化。 这个过程是递归的 对象流 能够输入输出对象的流称为对象流。 可以将对象串行化后通过对象输入输出流写入文件或传送到其它地方 字节流:对象流  Java 的对象的序列化将那些实现了 Serializable 接口的对象转换成一个字节序列,并能够在以后将这个字节序列完全恢复为原来的对象 publicclassStudentimplementsSerializable   Serializable 接口 标志着一个类的对象可以被序列化 需要序列化的状态必须可被序列化 基本类型 其他可序列化类型(实现 Serializable 接口) 用 transient 关键字标志不进行序列化的状态 静态变量不被序列化 ObjectOutputStream Studentstu=newStudent(981036,“LiMing”,16,“CSD”); FileOutputStreamfo=newFileOutputStream(“data.ser”); ObjectOutputStreamso=newObjectOutputStream(fo); so.writeObject(stu); so.close(); ObjectInputStream Studentstu; FileInputStreamfi=newFileInputStream(“data.ser”); ObjectInputStreamsi=newObjectInputStream(fi); stu=(Student)si.readObject();si.close(); 字节流:管道流  管道用来把一个程序、线程和代码块的输出连接到另一个程序、线程和代码块的输入 java.io 中提供了类 PipedInputStream 和 PipedOutputStream 作为管道的输入/输出流 通过构造方法连接 PipedInputStream(PipedOutputStreampos); PipedOutputStream(PipedInputStreampis); 通过各自的 connect()方法连接 在类 PipedInputStream 中, connect(PipedOutputStreampos); 在类 PipedOutputStream 中, connect(PipedInputStreampis); 字符输入流结构   在 JDK1.1 之前,java.io 包中的流只有普通的字节流(以 byte 为基本处理单位的流),这种流对于以 16 位的 Unicode 码表示的字符流处理很不方便。从 JDK1.1 开始, java.io 包中加入了专门用于字 符流处理的类,它们是以 Reader 和 Writer 为基础派生的一系列类。 同类InputStream和OutputStream一样,Reader 和 Writer 也是抽象类,只提供了一系列用于字符流处理的接口。它们的方法与类 InputStream 和 OutputStream 类似,只不过其中的参数 换成字符或字符数组。 字节流中类 DatainputStream 的 readLine 方法,可以以字节形式读入,以 Unicode 形式输出(StringreadLine()) Reader  字符输入流的基类  常用操作 read(): 读入一个字符 read(char[]): 读入多个字符 close(): 关闭此输入流字符输出流结构  Writer  字符输出流的基类  常用操作 write(int): 向输出流写一个字符 write(char[]):向输出流写多个字符 write(String): 向输出流写入一个字符串  flush(): 清空缓存 close(): 关闭此输出流 字节流转换为字符流  InputStreamReader 和 OutputStreamWriter 是 java.io 包中用于处理字符流的最基本的类,用来在字节流和字符流之间作为中介 InputStreamReader(InputStreamin);//缺省规范 InputStreamReader(InputStreamin,Stringenc);//指定规范 enc OutputStreamWriter(OutputStreamout);   //缺省规范 OutputStreamWriter(OutputStreamout,Stringenc);   //指定 enc 实际使用中,应尽量使用 BufferedWriter 类包装 OutputStreamWriter,用 BufferedReader 类包装 InputStreamReader 以提高性能  构造方法的 charsetName 参数在有些时候非常有用,例如操作系统默认编码方式为 GB2312,而文件使用 UTF-8 编码,可以用如下方式获得一个 Reader 实例: Readerin=newBufferedReader(newInputStreamReader( newFileInputStream("D:/1.txt"),"UTF-8")); BufferedReader 和 BufferedWriter  BufferedReader 为字符输入流增加缓存新增操作 readLine 读入一行,返回 String BufferedWriter 新增操作 newLine 写入一个行结束标志,不是简单的换行符‘\n’或‘\r’,而是系统定义的行隔离标志 其它字符流  Properties   特性 属性列表中每个键及其对应值都是一个字符串  方法 setProperty-设定某个键对应的值 getProperty-取得某个键对应的值 load-从输入流中读取属性列表(键和元素对)  store-将此 Properties 中的属性列表写入输出流多线程编程和网络编程入门  多线程编程和网络编程入门 ............................................................................................. 1 重点内容...........................................................................................................................................................................1 线程和进程 .......................................................................................................................................................................1 进程类 ..............................................................................................................................................................................2 线程体 ..............................................................................................................................................................................3 主线程 ..............................................................................................................................................................................3 创建线程...........................................................................................................................................................................3 java.lang.Thread类 ........................................................................................................................................................5 两种创建线程方法的比较 ..................................................................................................................................................5 守护(deamon)线程..........................................................................................................................................................6 线程的调度 .......................................................................................................................................................................6 线程的优先级....................................................................................................................................................................7 监视器(锁)....................................................................................................................................................................7 同步(synchronized)....................................................................................................................................................7 同步原理...........................................................................................................................................................................8 死锁..................................................................................................................................................................................8 多线程协作-wait和notify ................................................................................................................................................8 ThreadLocal ...................................................................................................................................................................9 计算机网络基本知识 ...................................................................................................................................................... 10 Java中的URL操作类...................................................................................................................................................... 11 什么是Socket?............................................................................................................................................................ 12 基于Java  自身技术实现消息方式系统通讯..................................................................................................................... 13  重点内容  进程和线程的区别 创建线程的两种方式 java.lang.Thread 类的常用方法 线程的四种状态 同步和锁 ThreadLocal 计算机网络基本知识 URL 及其操作类 基于 Java 自身技术实现消息方式系统通讯 线程和进程  进程 资源管理的最小单位 独立的内存空间 包含一个或多个线程线程 程序执行的最小单位 拥有独立的栈空间  进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响。 线程有自己的堆栈和局部变量,同一个进程之间多个线程共享堆上的内存空间。  线程和进程 每个进程都有独立的代码和数据空间(进程上下文),进程切换的开销大。 线程: 轻量的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。 多线程: 在同一个进程中有多个顺序流同时执行。 进程类  Process 通过调用 ProcessBuilder 的 start 方法启动 主要操作 destroy 结束进程 waitFor 等待进程结束 进程间通信 共享内存 管道 Socket …  使用 Process 中的 getInputStream 和 getOutputStream 进行进程间通信的范例代码: //Calulator.java importjava.util.Scanner; publicclassCalculator{ publicstaticvoidmain(String[]args){ Scannerscanner=newScanner(System.in); while(scanner.hasNext()){ inti=scanner.nextInt();   intj=scanner.nextInt(); System.out.println(i*j); } } } //ProcessTest.java importjava.io.*; publicclassProcessTest{ publicstaticvoidmain(String[]args)throwsIOException{ ProcessBuilderbuilder=newProcessBuilder( "D:/applications/jdk1.6.0_05/bin/java.exe","-cp", "D:/workspace/blackwhite/bin","Calculator");//根据自己开发环境修改 Processprocess=builder.start(); BufferedReaderin=newBufferedReader(newInputStreamReader(process.getInputStream())); PrintStreamout=newPrintStream(process.getOutputStream()); out.println(3); out.println(5); out.flush(); System.out.println("Resultis"+in.readLine()); } } 线程体  Java 的线程是通过 java.lang.Thread 类来实现的 每个线程都是通过某个特定 Thread 对象所对应的方法 run( )来完成其操作的,方法 run( )称为线程体(即线程的可执行代码)  主线程  在任何 Java 程序启动时,一个线程立刻运行(即 mian 方法对应的线程),该线程通常称为程序的主线程 主线程的特点 它是产生其他子线程的线程 它不一定是最后完成执行的线程,子线程可能在它结束之后还在运行 创建线程  方式一:用 Thread 类创建线程 声明为一个 Thread 类的子类,并覆盖 run() 方法   classMyThreadextendsThread{        publicvoidrun(){                 /* 覆盖该方法*/  } } 当使用继承创建线程,这样启动线程: newMyThread().start(); 创建线程方式一示例   publicclassTestThread{//主类用于执行程序,不扩展 Thread 类   publicstaticvoidmain(String[]args){   Threadt=newMyThread();//创建线程对象         t.start();//启动线程 t,它会自动调用 run 方法 } }classMyThreadextendsThread{//线程类,必须扩展 Thread 类   publicvoidrun(){//线程对象的可执行代码   for(inti=0;i<5;i++){ System.out.println("SubThread:"+i); } } } 方式二:使用 Runnable 接口创建多线程 声明为一个实现 Runnable 接口的类,并实现 run() 方法 classMyThreadimplementsRunnable{ publicvoidrun(){           /* 实现该方法*/  } } 当使用实现接口创建线程,这样启动线程: newThread(newMyThread()).start();  可看到该接口只有一个 run 方法,当使用 Thread(Runnable target)方法创建线程对象时,需要为该方法传递一个实现了 Runnable 接口的类对象,这样创建的线程将会调用实现了 Runnable 接口的 类对象中的 run 方法作为其运行代码,而不再调用 Thread 类中的 run 方法了。 通过实现 Runnable 接口来创建线程的好处是在实现接口的同时,继承另一个类 创建线程方式二示例  publicclassTestThread{//主类用于执行程序,不扩展 Runnable 接口 publicstaticvoidmain(String[]args){    MyThreadr=newMyThread();//生成线程类对象 r   Threadt=newThread(r);//创建线程对象,把线程类对象 r 作为参数传递给它        t.start();//启动线程 t,它会自动调用线程类对象 r 的 run 方法 } } classMyThreadimplementsRunnable{//线程类,实现 Runnable 接口  publicvoidrun(){//线程类对象的可执行代码  for(inti=0;i<3;i++){   System.out.println(“子线程No.”+i);  } }} java.lang.Thread 类  静态方法 currentThread() 返回当前线程实例 sleep(longmillis) 当前线程休眠 yield() 当前线程停顿 dumpStack() 打印当前线程的调用栈 常用方法 start()  启动该线程,将导致 run 方法被自动调用 run()  必须覆盖该方法,在方法体中添加线程逻辑代码 interrupt()  用于将一个中断请求发送给线程 interrupted()   用于测试当前线程是否已经被中断 isInterrupted()   用于测试某个线程是否已经被中断 isAlive()    用于测试某个线程是否还活着 setPriority(intnewPriority)   设置线程的优先级  join()   等待线程结束 两种创建线程方法的比较  使用 Runnable 接口 可以将代码和数据分开,形成清晰的模型 还可以从其他类继承 保持程序风格的一致性 直接继承 Thread 类 不能再从其他类继承 编写简单,可以直接操纵线程 无需使用 Thread.currentThread() 线程的四种状态  线程共有下面 4 种状态: 1、new(新建):当你用 new 创建一个线程时,该线程尚未运行。 2、runnable(可运行):一旦调用了 start 方法,该线程便是一个可运行的线程。可运行的线程可以尚未执行,也可以正在执行,取决于线程调度的结果。(java 文档并不将正在运行的情况视为一个专 门的状态) 3、blocked(被中断运行):当出现下列操作之一时,线程便进入中断状态: 有人调用该线程的 sleep()方法; 该线程调用了 wait()方法; 该线程调用了一个在输入输出时中断的操作,也就是说,在输入和输出操作完成之前,该操作不会返回到它的调用程序; 该线程试图锁定一个当前被另一个线程锁定了的对象 4、dead(死亡):由于下面两个原因,线程将变成死线程: 由于 run 方法的正常退出而自然死亡; 没有捕获到的异常事件终止了 run 方法的执行,从而导致线程突然死亡 join 方法使用示例 publicstaticvoidmain(String[]args){         Threadthread1=newThread("Thread1"); thread1.start(); try{ thread1.join(); }catch(InterruptedExceptione){             System.out.println("等待 thread 过程中被打断"); }         for(inti=0;i<10;i++){ System.out.printf("main:%d\n",i); } } 守护(deamon)线程    守护线程是为其它线程提供服务的线程,如定时器线程 守护线程一般应该是一个独立的线程,它的 run()方法是一个无限循环 守护线程与其它线程的区别是:如果守护线程是唯一运行着的线程,程序会自动退出 把线程变成一个守护线程:t .setDeamon(true); 线程的调度  Java 提供一个线程调度程序来监控程序中启动后进入可运行状态的所有线程 线程调度程序按照线程的优先级决定应调度哪些线程执行 多数线程的调度是抢占式的 时间片方式(timeslicing) 非时间片方式 下面几种情况下,当前线程会放弃 CPU 线程调用了 yield()或 sleep()方法主动放弃 由于当前线程进行 I/O 访问,外存读写,等待用户输入等操作,导致线程阻塞 为等候一个条件变量,线程调用 wait()方法抢先式系统下,有高优先级的线程参与调度;时间片方式下,当前时间片用完,有同优先级的线程参与调度 线程的优先级  在 java 中,每一个线程都有一个优先级。默认情况下,一个线程将继承其父线程的优先级。线程的优先级用数字来表示,范围从 1 到 10,一个线程的缺省优先级是 5 Thread.MIN_PRIORITY=1 Thread.MAX_PRIORITY=10 Thread.NORM_PRIORITY=5 使用下述线方法获得或设置线程对象的优先级 int  getPriority(); void  setPriority(intnewPriority);  线程的优先级代表该线程的重要程度,当有多个线程同时处于可执行状态并等待获得 CPU 时间时,线程调度系统根据各个线程的优先级来决定给谁分配 CPU 时间,优先级高的线程有更大的机会获 得 CPU 时间,优先级低的线程也不是没有机会,只是机会要小。  可以调用 Thread 类的方法 getPriority() 和 setPriority()来存取线程的优先级,线程的优先级界于 1(MIN_PRIORITY)和 10(MAX_PRIORITY)之间,缺省是 5(NORM_PRIORITY)。  线程的优先级是从 1 到 10 之间的一个数字,数字越大表明优先级越高。JVM 标准首先调用优先级较高的线程,然后才调用优先级较低的线程。但是,具有相同优先级的线程的处理是随机的。如何 处理这些线程取决于基层的操作系统策略。在某些情况下,优先级相同的线程分时运行;在另一些情况下,线程将一直运行到结束。 监视器(锁)  在 java 中,每个对象都包含了一把锁(也叫作“监视器”),它自动成为对象的一部分(不必为此写任何特殊的代码) 示例:线程 1 进入 withdrawal 方法时,获得监视器(加锁);当线程 1 的方法执行完毕返回时,释放监视器(开锁),线程 2 的 withdrawal 方能进入  同步(synchronized)  为了确保在任何时刻一个共享对象只被一个线程使用,必须使用“同步(synchronized)” 有两种方式实现同步: 使用同步方法  synchronizedvoidmethodA(){  } 使用同步块  synchronized(obj){//obj 是被锁定的对象       //要同步的语句 }  调用任何 synchronized 方法时,对象就会被锁定,不可再调用那个对象的其他任何 synchronized 方法,除非第一个方法完成了自己的工作,并解除锁定。因此,一个特定对象的所有 synchronized 方法都共享着一把锁,而且这把锁能防止多个方法对通用内存同时进行写操作(比如同时有多个线程)。 每个类也有自己的一把锁(作为类的 Class 对象的一部分),所以 synchronizedstatic 方法可在一个类的范围内被相互间锁定起来,防止与 static 数据的接触。 一般情况下,只在方法的层次上使用同步同步原理  每个对象拥有自己的锁 对于同一个锁,不能有两个线程同时访问 (浴室的例子) 一个房间一次只能进一个人  死锁  当所有的线程都在等待得到某个资源后才能继续运行下去时,整个程序将被挂起,这种情况就叫做死锁   造成死锁的原因如下: 相互排斥: 一个线程或者进程永远占有一共享资源,例如,独占该资源。  循环等待: 进程 A 等待进程 B,而后者又在等待进程 C,进程 C 又在等待进程 A。  部分分配: 资源被部分分配。例如,进程 A 和 B 都需要用访问一个文件,并且    都要用到打印机,进程 A 获得了文件资源,进程 B 获得了打印机资源,但是两个    进程不能获得全部的资源。  缺少优先权: 一个进程访问了某个资源,但是一直不释放该资源,则使该进    程处于阻塞状态。 多线程协作-wait 和 notify  wait 类似于 sleep,当前线程休眠 释放自己占用的锁(不同于 sleep) 可以指定休眠的时间,也可不指定 notify/notifyAll 唤醒正在 wait 状态等待当前锁的线程 notifyAll 唤醒所有 wait 状态的线程 notify 只唤醒一个 wait 状态的线程  这三个方法是 Object 类中的方法,每个对象都有自己的锁,通过 synchronized 块占用一个对象的锁,占用后调用 wait 方法可暂时释放这把锁,但当前仍在同步块中,释放锁后,线程处于 wait 状态, 等待其他线程将锁还给它。 interrupt 打断线程的等待 publicstaticvoidmain(String[]args)throwsInterruptedException{         Threadthread1=newPrintNumberThread("Thread1");      thread1.start();         Thread.sleep(3000); thread1.interrupt();         for(inti=0;i<10;i++){ System.out.printf("main:%d\n",i); } }        调用一个线程的 interrupt 方法,该线程会被打断。打断线程并不会意味结束线程的运行:如果线程正在执行某些可以被打断的方法,这些方法会抛出 InterruptedException,否则只在线程上做一个 标志。带有此标志的线程再次执行可以被打断的方法时,这些方法也会抛出 InterruptedException。可以被打断的方法包括 Thread 类中的 sleep 方法,join 方法,wait 方法等,这些方法都会抛出 InterruptedException。  对于 InterruptedException 的处理通常是捕获它,然后使用 break 语句退出循环,结束线程的运行。 ThreadLocal  用来为每个线程保存一个变量 操作 初始化(使用泛型) ThreadLocalcounter=newThreadLocal(); 保存一个值 counter.set(1); 读取一个值 inti=counter.get() 删除保存的值 counter.remove();  ThreadLocal 类中的公共方法都是多线程安全的,可以避免直接使用 synchronized 进行同步。 ThreadLocal 的含义是线程本地的。  classTestThreadimplementsRunnable{ privateThreadLocalcounter=newThreadLocal(); publicvoidrun(){ counter.set(0);for(inti=0;i<10;i++){ counter.set(counter.get()+1); } //每个线程结束时,打印出的结果都是 10,说明互相并不共享 ThreadLocal 中的值 System.out.println(counter.get());  } } publicclassThreadLocalTest{ publicvoidtest(){ Thread[]threads=newThread[5]; TestThreadrunnable=newTestThread(); for(inti=0;i<threads.length;i++){ threads[i]=newThread(runnable); threads[i].start(); } } publicstaticvoidmain(String[]args){ newThreadLocalTest().test(); } }  计算机网络基本知识  协议(Protocol):两台计算机通讯时对传送信息内容的理解、信息表示形式以及各种情况下应答信号都必须遵守的共同的约定 体系结构(Architecture):在一个计算机网络中将协议分成了若干层次,将协议按如何分层以及各层中具体采用协议的集合 OSI 和 TCP/IP 的体系结构:  TCP/IP 是指传输控制协议(Transmission Control Protocol)和网间协议(Internet Protocol) TCP/IP 网络参考模型包括五个层次:应用层、传输层、网络层、链路层、物理层 常用应用层协议:ftp、http、smtp、pop3、telnet 网络工作模式 客户机/服务器模式:(client/server) 浏览器/服务器模式:(browser/server) 对等式网络: (Peer-to-Peer) 专用服务器结构:(Server-Based)  TCP 握手协议 在 TCP/IP 协议中,TCP 协议提供可靠的连接服务,采用三次握手建立一个连接。  第一次握手:建立连接时,客户端发送 SYN 包(syn=j)到服务器,并进入 SYN_SEND 状态,等待服务器确认; SYN: 同步序列编号(SynchronizeSequenceNumbers) 第二次握手:服务器收到 SYN 包,必须确认客户的 SYN(ack=j+1),同时自己也发送一个 SYN 包(syn=k),即 SYN+ACK 包,此时服务器进入 SYN_RECV 状态;  第三次握手:客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK(ack=k+1),此包发送完毕,客户端和服务器进入 ESTABLISHED 状态,完成三次握手。  完成三次握手,客户端与服务器开始传送数据。  IP 地址:(IPv4:32bits)标识计算机、Hub、等网络设备的网络地址,由 4 个 8bits 组成,中间以小数点分隔。 分为网络标识(networkid)和主机标识(hostid),又被分成了 A、B、C、D、E 五类。如:166.111.136.3,166.111.52.80 子网掩码 为解决 IP 资源耗尽的问题:提出 IPv6(128bits)  URL 格式 Java 中的 URL 操作类  URI 是统一资源标识符,而 URL 是统一资源定位符。笼统地说,每个 URL 都是 URI,反之则不一定。  这是因为 URI 还包括一个子类,即统一资源名称 (URN),它命名资源但不指定如何定位资源 为了表示 URL,java.net 中实现了类 URL。类 URL 的常见构造方法如下 URLurlBase=newURL("http://www.263.net/")  URLnet263=newURL("http://www.263.net/")  URLindex263=newURL(net263,"index.html") newURL("http","www.gamelan.com",  "/pages/Gamelan.network.html");  URL 类常用方法 publicStringgetProtocol() 获取该 URL 的协议名。 publicStringgetHost() 获取该 URL 的主机名。 publicintgetPort() 获取该 URL 的端口号,如没有设置端口,返回-1。 publicStringgetFile() 获取该 URL 的文件名。 publicStringgetRef() 获取该 URL 在文件中的相对位置或锚点。publicStringgetPath() 获取该 URL 的路径。 publicStringgetAuthority()此 URL 的已解码的授权组成部分,如果授权未定义,则返回 null 。 publicStringgetUserInfo() 获得使用者的信息。 下载网页代码 URLurl=newURL("http://www.163.com"); URLConnectionconn=url.openConnection(); InputStreamin=conn.getInputStream(); inttemp; while((temp=in.read())!=-1){  System.out.print((char)temp); } in.close();  1.Java 中的 URL 类用来表示以及描述 URL,URL 类包含在 java.net 包中,在 URL 类中使用 String 类型描述网络的 URL,用以指向网络主机上的文件名字。在 URL 类中提供的 getFile()、getHost()、 getPort()、getProtocol()等方法用来访问 URL 对象的各个部分。通过 URL 类可以创建 URL 对象: URLurl=newURL("http://localhost:8080/mytest/index.html"); 2.URLConnection 类,用来对指定的 URL 进行访问,可以通过 getInputStream( )、getOutputStream( )方法得到数据的输入输出流对象,进行数据的读写操作。通过 URL 的 openConnection( ) 方法得到 URLConnection 的对象:URLConnectionconn=url.openConnection(); 什么是 Socket?   Socket 标识运行在网络上的两个程序之间的双向通信链接 IP Port    Socket:Java 语言中的套接字(Socket)就是网络通信协议的一种应用,通过 TCP/IP 协议进行通信 Socket 在哪里?  基于 Java  自身技术实现消息方式系统通讯   在网络协议上 java 支持 TCP/IP 和 UDP/IP 在网络 IO 操作上 java 支持 BIO 和 NIO 因此在 java 中有四种方法可实现基于消息方式的系统间通讯 TCP/IP+BIO TCP/IP+NIO UDP/IP+BIO UDP/IP+NIO  Socket:套接字是两台机器间通信的端点。是为了简化网络编程的复杂度而由开发语言提供的一个网络编程接口。可以在网络上建立机器和机器之间可靠的、双向的、持续的、点对点的流式连接。 传统的 Socket 编程(阻塞的,串行) 传统的基于多线程的 Socket 编程(阻塞的,并发) 基于多线程和 NIO 的非阻塞编程 阻塞的含义:执行这些方法时,只有这些方法有返回结果的情况下,程序才能继续运行,否则执行该方法的进程或线程处于阻塞等待状态。 java.net 包中提供了两个类 Socket 和 ServerSocket,分别用来表示双向连接的客户端和服务端。其常用构造方法如下: Socket(InetAddressaddress,intport); Socket(InetAddressaddress,intport,booleanstream); Socket(Stringhost,intport); Socket(Stringhost,intpor`t,InetAddresslocalAddr,intlocalPort) Socket(InetAddressaddress,intport,InetAddresslocalAddr,intlocalPort)  ServerSocket(intport); ServerSocket(intport,intbacklog); ServerSocket(intport,intbacklog,InetAddressbindAddr) 其中 address、host 和 port 分别是双向连接中另一方的 IP 地址、主机名和端口号,stream 指明 socket 是流 socket 还是数据报 socket,localPort 表示本地主机的端口号,localAddr 和 bindAddr 是本地机器的地址(ServerSocket 的主机地址),impl 是 socket 的父类,既可以用来创建 serverSocket 又可以用来创建 Socket。count 则表示服务端所能支持的最大连接数。例如: Socketclient=newSocket("127.0.01.",8081); ServerSocketserver=newServerSocket(8081); 注意:我们在选择端口号时,最好选择一个大于 1024 的数以防止发生冲突。类 Socket 提供了方法 getInputStream()和 getOutStream()来得到对应的输入/输出流以进行读/写操作,这两个方法分别返回 InputStream 和 OutputSteam 类对象。为了便于读/写数据,我们可以 在返回的输入/输出流对象上建立过滤流,如 DataInputStream、DataOutputStream 或 PrintStream 类对象,对于文本方式流对象,可以采用 InputStreamReader 和 OutputStreamWriter、PrintWirter 等处理。 例如: PrintStreamos=newPrintStream(newBufferedOutputStreem(socket.getOutputStream())); DataInputStreamis=newDataInputStream(socket.getInputStream()); PrintWriterout=newPrintWriter(socket.getOutStream(),true); BufferedReaderin=newButfferedReader(newInputSteramReader(Socket.getInputStream())); 注:输入输出流是网络编程的实质性部分,具体如何构造所需要的过滤流,要根据需要而定,能否运用自如主要看读者对 Java 中输入输出部分掌握如何。 每一个 Socket 存在时,都将占用一定的资源,在 Socket 对象使用完毕时,要其关闭。关闭 Socket 可以调用 Socket 的 Close()方法。在关闭 Socket 之前,应将与 Socket 相关的所有的输入/输出流 全部关闭,以释放所有的资源。而且要注意关闭的顺序,与 Socket 相关的所有的输入/输出该首先关闭,然后再关闭 Socket。 os.close(); is.close(); socket.close(); 尽管 Java 有自动回收机制,网络资源最终是会被释放的。但是为了有效的利用资源,建议读者按照合理的顺序主动释放资源。  TCP,可靠,传输大小无限制,但是需要连接建立时间,差错控制开销大。 UDP,不可靠,差错控制开销较小,传输大小限制在 64K 以下,不需要建立连接。 UDP(UserDatagramProtocol):是一种面向非连接的协议,在正式通信前不必与对方先建立连接,不管对方状态就直接发送。每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网 络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。这与现在手机短信非常相似。 UDP 适用于一次只传送少量数据、对可靠性要求不 高的应用环境。 例如“ping”命令可用来测试两台主机之间 TCP/IP 通信是否正常:一次向对方主机发送 4 个 UDP 数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通 的,否则网络连接不正常。 正因为 UDP 协议没有连接的过程,所以它的通信效果高;但也正因为如此,它的可靠性不如 TCP 协议高。QQ 就使用 UDP 发消息,因此有时会出现收不到消息的情况。 包 java.net 中提供了两个类 DatagramSocket 和 DatagramPacket 用来支持数据报通信,DatagramSocket 用于在程序之间建立传送数据报的通信连接,DatagramPacket 则用来表示一个数据报。 先来看一下 DatagramSocket 的构造方法: DatagramSocket(); DatagramSocket(intport); DatagramSocket(intport,InetAddressladdr)   其中,port 指明 socket 所使用的端口号,如果未指明端口号,则把 socket 连接到本地主机上一个可用的端口。laddr 指明一个可用的本地地址。给出端口号时要保证不发生端口冲突,否则会生成 SocketException 类例外。注意:上述的两个构造方法都声明抛弃非运行时例外 SocketException,程序中必须进行处理,或者捕获、或者声明抛弃。 用数据报方式编写 client/server 程序时,无论在客户方还是服务方,首先都要建立一个 DatagramSocket 对象,用来接收或发送数据报,然后使用 DatagramPacket 类对象作为传输数据的载体。下 面看一下 DatagramPacket 的构造方法 : DatagramPacket(bytebuf[],intlength); DatagramPacket(bytebuf[],intlength,InetAddressaddr,intport); DatagramPacket(byte[]buf,intoffset,intlength); DatagramPacket(byte[]buf,intoffset,intlength,InetAddressaddress,intport);   其中,buf 中存放数据报数据,length 为数据报中数据的长度,addr 和 port 旨明目的地址,offset 指明了数据报的位移量。 在接收数据前,应该采用上面的第一种方法生成一个 DatagramPacket 对象,给出接收数据的缓冲区及其长度。然后调用 DatagramSocket 的方法 receive()等待数据报的到来,receive()将一直等待, 直到收到一个数据报为止。   DatagramPacketpacket=newDatagramPacket(buf,256);   Socket.receive(packet);   发送数据报前,也要先生成一个新的 DatagramPacket 对象,这时要使用上面的第二种构造方法,在给出存放发送数据的缓冲区的同时,还要给出完整的目的地址,包括 IP 和端口号。发送数据是 通过 DatagramSocket 的方法 send()实现的,send()根据数据报的目的地址来寻径,以传递数据报。   DatagramPacketpacket=newDatagramPacket(buf,length,address,port);  Socket.send(packet); TCP/IP+BIO Server  publicstaticvoidmain(String[]args)throwsException{   intport=9527;   ServerSocketss=newServerSocket(port);   System.out.println("Serverlistenonport:"+port);   Socketsocket=ss.accept();   BufferedReaderin=newBufferedReader(newInputStreamReader(socket .getInputStream()));   PrintWriterout=newPrintWriter(socket.getOutputStream(),true); while(true){Stringline=in.readLine(); if(line==null){ Thread.sleep(100); continue; } if("quit".equalsIgnoreCase(line.trim())){ in.close(); out.close(); ss.close(); System.out.println("Serverhasbeenshutdown!"); System.exit(0); }else{ System.out.println("Messagefromclient:"+line); out.println("Serverresponse:"+line); Thread.sleep(100); } } } TCP/IP+BIO Client  publicstaticvoidmain(String[]args)throwsException{   Stringhost="127.0.0.1";   intport=9527;   Socketsocket=newSocket(host,port);   BufferedReaderin=newBufferedReader(newInputStreamReader(socket .getInputStream()));   PrintWriterout=newPrintWriter(socket.getOutputStream(),true);   BufferedReadersystemIn=newBufferedReader(newInputStreamReader( System.in));   booleanflag=true;   while(flag){ Stringcommand=systemIn.readLine(); if(command==null||"quit".equalsIgnoreCase(command.trim())){ flag=false; System.out.println("Clientquit!"); out.println("quit"); out.close(); in.close(); socket.close(); continue; } out.println(command); Stringresponse=in.readLine(); System.out.println(response); } } TCP/IP+NIO Server  publicstaticvoidmain(String[]args)throwsException{   intport=9527;   Selectorselector=Selector.open();   ServerSocketChannelssc=ServerSocketChannel.open();   ServerSocketserverSocket=ssc.socket();   serverSocket.bind(newInetSocketAddress(port));   System.out.println("Serverlistenonport:"+port);   ssc.configureBlocking(false);   ssc.register(selector,SelectionKey.OP_ACCEPT); while(true){ intnKeys=selector.select(1000); if(nKeys>0){ for(SelectionKeykey:selector.selectedKeys()){ if(key.isAcceptable()){ ServerSocketChannelserver=(ServerSocketChannel)key .channel(); SocketChannelsc=server.accept(); if(sc==null){ continue; } sc.configureBlocking(false); sc.register(selector,SelectionKey.OP_READ); }elseif(key.isReadable()){ ByteBufferbuffer=ByteBuffer.allocate(1024); SocketChannelsc=(SocketChannel)key.channel(); intreadBytes=0; Stringmessage=null; try{ intret; try{ while((ret=sc.read(buffer))>0){ readBytes+=ret; } }catch(Exceptione){ readBytes=0; //IGNORE }finally{ buffer.flip(); } if(readBytes>0){ message=Charset.forName("UTF-8").decode( buffer).toString(); buffer=null; } }finally{ if(buffer!=null){ buffer.clear(); } }if(readBytes>0){ System.out.println("Messagefromclient:" +message); if("quit".equalsIgnoreCase(message.trim())){ sc.close(); selector.close(); System.out.println("Serverhasbeenshutdown!"); System.exit(0); } StringoutMessage="Serverresponse:"+message; sc.write(Charset.forName("UTF-8") .encode(outMessage)); } } } selector.selectedKeys().clear(); } } } TCP/IP+NIO Client  publicstaticvoidmain(String[]args)throwsException{   intport=9527;   SocketChannelchannel=SocketChannel.open();   channel.configureBlocking(false);   SocketAddresstarget=newInetSocketAddress("127.0.0.1",port);   channel.connect(target);   Selectorselector=Selector.open();   channel.register(selector,SelectionKey.OP_CONNECT);   BufferedReadersystemIn=newBufferedReader(newInputStreamReader( System.in)); while(true){ if(channel.isConnected()){ Stringcommand=systemIn.readLine(); channel.write(Charset.forName("UTF-8").encode(command)); if(command==null||"quit".equalsIgnoreCase(command.trim())){ systemIn.close(); channel.close(); selector.close(); System.out.println("Clientquit!"); System.exit(0); } } intnKeys=selector.select(1000); if(nKeys>0){ for(SelectionKeykey:selector.selectedKeys()){ if(key.isConnectable()){ SocketChannelsc=(SocketChannel)key.channel(); sc.configureBlocking(false); sc.register(selector,SelectionKey.OP_READ);sc.finishConnect(); }elseif(key.isReadable()){ ByteBufferbuffer=ByteBuffer.allocate(1024); SocketChannelsc=(SocketChannel)key.channel(); intreadBytes=0; try{ intret=0; try{ while((ret=sc.read(buffer))>0){ readBytes+=ret; } }finally{ buffer.flip(); } if(readBytes>0){ System.out.println(Charset.forName("UTF-8") .decode(buffer).toString()); buffer=null; } }finally{ if(buffer!=null){ buffer.clear(); } } } } selector.selectedKeys().clear(); } } } UDP/IP+BIO Sender  publicstaticvoidmain(String[]args)throwsException{   intport=9527;   intaport=9528;   DatagramSocketserver=newDatagramSocket(port);   DatagramSocketclient=newDatagramSocket();   InetAddressserverAddress=InetAddress.getByName("localhost");   byte[]buffer=newbyte[65507];   DatagramPacketpacket=newDatagramPacket(buffer,buffer.length); while(true){ server.receive(packet); Stringline=newString(packet.getData(),0,packet.getLength(), "UTF-8"); if("quit".equalsIgnoreCase(line.trim())){ server.close(); System.exit(0); }else{ System.out.println("Messagefromclient:"+line); packet.setLength(buffer.length); Stringresponse="Serverresponse:"+line; byte[]datas=response.getBytes("UTF-8"); DatagramPacketresponsePacket=newDatagramPacket(datas, datas.length,serverAddress,aport); client.send(responsePacket); Thread.sleep(100); } } } UDP/IP+BIO Receiver  publicstaticvoidmain(String[]args)throwsException{   intport=9527;   intaport=9528;   DatagramSocketserverSocket=newDatagramSocket(aport);   byte[]buffer=newbyte[65507];   DatagramPacketreceivePacket=newDatagramPacket(buffer,buffer.length);   DatagramSocketsocket=newDatagramSocket();   InetAddressserver=InetAddress.getByName("localhost");   BufferedReadersystemIn=newBufferedReader(newInputStreamReader( System.in));   booleanflag=true;   while(flag){ Stringcommand=systemIn.readLine(); byte[]datas=command.getBytes("UTF-8"); DatagramPacketpacket=newDatagramPacket(datas,datas.length, server,port); socket.send(packet); if(command==null||"quit".equalsIgnoreCase(command.trim())){ flag=false; System.out.println("Clientquit!"); socket.close(); continue; } serverSocket.receive(receivePacket); StringreceiveResponse=newString(receivePacket.getData(),0, receivePacket.getLength(),"UTF-8"); System.out.println(receiveResponse); } } UDP/IP+NIO Sender  publicstaticvoidmain(String[]args)throwsException{   intrport=9527;   intsport=9528;   DatagramChannelsendChannel=DatagramChannel.open();   sendChannel.configureBlocking(false);   SocketAddresstarget=newInetSocketAddress("127.0.0.1",sport);   sendChannel.connect(target);   DatagramChannelreceiveChannel=DatagramChannel.open();   DatagramSocketserverSocket=receiveChannel.socket();   serverSocket.bind(newInetSocketAddress(rport));   System.out.println("Datareceivelistenonport:"+rport);   receiveChannel.configureBlocking(false);  Selectorselector=Selector.open();   receiveChannel.register(selector,SelectionKey.OP_READ); while(true){ intnKeys=selector.select(1000); if(nKeys>0){ for(SelectionKeykey:selector.selectedKeys()){ if(key.isReadable()){ ByteBufferbuffer=ByteBuffer.allocate(1024); DatagramChanneldc=(DatagramChannel)key.channel(); dc.receive(buffer); buffer.flip(); Stringmessage=Charset.forName("UTF-8") .decode(buffer).toString(); System.out.println("Messagefromclient:"+message); if("quit".equalsIgnoreCase(message.trim())){ dc.close(); selector.close(); sendChannel.close(); System.out.println("Serverhasbeenshutdown!"); System.exit(0); } StringoutMessage="Serverresponse:"+message; sendChannel.write(Charset.forName("UTF-8").encode( outMessage)); } } selector.selectedKeys().clear(); } } } UDP/IP+NIO Receiver  publicstaticvoidmain(String[]args)throwsException{   intrport=9528;   intsport=9527;   DatagramChannelreceiveChannel=DatagramChannel.open();   receiveChannel.configureBlocking(false);   DatagramSocketsocket=receiveChannel.socket();   socket.bind(newInetSocketAddress(rport));   Selectorselector=Selector.open();   receiveChannel.register(selector,SelectionKey.OP_READ);   DatagramChannelsendChannel=DatagramChannel.open();   sendChannel.configureBlocking(false);   SocketAddresstarget=newInetSocketAddress("127.0.0.1",sport);   sendChannel.connect(target);   BufferedReadersystemIn=newBufferedReader(newInputStreamReader( System.in)); while(true){ Stringcommand=systemIn.readLine(); sendChannel.write(Charset.forName("UTF-8").encode(command));if(command==null||"quit".equalsIgnoreCase(command.trim())){ systemIn.close(); sendChannel.close(); selector.close(); System.out.println("Clientquit!"); System.exit(0); } intnKeys=selector.select(1000); if(nKeys>0){ for(SelectionKeykey:selector.selectedKeys()){ if(key.isReadable()){ ByteBufferbuffer=ByteBuffer.allocate(1024); DatagramChanneldc=(DatagramChannel)key.channel(); dc.receive(buffer); buffer.flip(); System.out.println(Charset.forName("UTF-8").decode( buffer).toString()); buffer=null; } } selector.selectedKeys().clear(); } } }HTML&CSS 编程强化  目录 HTML&CSS编程强化..................................................................................................... 1 重点内容...........................................................................................................................................................................1 HTML简介 .......................................................................................................................................................................2 什么是DOCTYPE .............................................................................................................................................................3 HTML常用标记 ................................................................................................................................................................3 段落文字...........................................................................................................................................................................3 分段控制标签

............................................................................................................................................................4 水平分隔线


..............................................................................................................................................................4 标题文字标签..........................................................................................................................................................5 文字格式控制标签 ................................................................................................................................................5 超链接.......................................................................................................................................................................5 图片......................................................................................................................................................................6 列表
    1. .........................................................................................................................................................7 表格 ...................................................................................................................................................................7 什么是表单(form)........................................................................................................................................................8 form表单的三个要点........................................................................................................................................................9 表单控件...........................................................................................................................................................................9 CSS使用 ........................................................................................................................................................................ 10 CSS语法 ........................................................................................................................................................................ 11 CSS选择器..................................................................................................................................................................... 11 与颜色与背景相关的CSS属性......................................................................................................................................... 11 与字体相关的CSS属性 ................................................................................................................................................... 11 与文本相关的CSS属性 ................................................................................................................................................... 11 元素的定位 .................................................................................................................................................................... 12  重点内容  HTML 简介 HTML 常用标记  段落文字 链接 图片 列表 表格 表单 CSS 选择器 CSS 盒子模型HTML 简介  HTML(HypertextMarkupLanguage) 超文本标记语言 由浏览器解释执行 文件是 ASCII 纯文字格式 编写的超文本文档称为网页 XHTML HTML 升级为 XML 的过渡产品  完全兼容 HTML4.01  并且具有 XML 的语法   什么是 HTML? HTML语言是一种标记语言,不需要编译,需要通过浏览器显示出效果如 FireFox、IE。 在标准网页设计中 HTML 负责填充网页的内容。HTML 文件也可以说是一个文本文件,它包含了一些 HTML 元素、标签等。HTML 文件必须使用 html 或 htm 为文件名后缀。 HTML编写的超文本文档(文件)称为 HTML 文档(网页),能独立于各种操作系统平台,如 UNIX、WINDOWS 等,并且可以通知浏览器显示什么。自 1990 年以来 HTML 就一直被用作互联网的 信息表示语言,用于描述网页的格式设计和它与互联网上其它网页的连结信息。  HTML 基本结构   HTML 的语法结构与文件结构 1.一个 HTML 文件是由一系列的元素和标签组成的。元素是 HTML 文件的重要组成部分,例如:title(文件标题),img(图象)及 table(表格)等。元素名不区分大小写。HTML 用标签来规定元素 的属性和它在文件中的位置。之间的文字会出现在浏览器视窗最上头蓝色部分里,当作一篇网页的主题。  HTML 标签分为单独出现的标签和成对出现的标签两种。 大多数的标签成对出现,由首标签和尾标签组成,其完整语法如下: <元素名称>要控制的元素 2.当用一组 HTML 标签将一段文字包含在中间时,这段文字与包含文字 HTML 标签被称之为一个元素。 由于在 HTML 语法中,每个由 HTML 标签与文字所形成的元素内,还可以包含另一个元素。因此,整个 HTML 文件就像是一个大元素包含了许多小元素。  可以通过 body 的属性来设定网页的背景颜色、背景图片和文字的颜色。 网页的背景颜色: 网页的背景图片: 网页内的文字颜色: 这一组标签可有可无,这一组标签告诉浏览器这是一份 HTML 文件,也就是说这是一个网页的格式,包在网页的最上下两端,将所有的原始码都包起来。  同样,html 中也能加注释,注释用表示。 带有 DOCTYPE 声明的代码    带有 DOCTYPE 声明的文档  

      HelloWorld!

          说明该文档是遵照 HTML4.01 的规范来编写的,strict 说明文档的格式检验是严格的。 什么是 DOCTYPE  DOCTYPE 是 DOCUMETNTYPE 的简写,用来说明文件是遵照 XHTML 或者 HTML 的那一套规范来写的 XHTML1.0 提供了三种 DTD 声明 过渡的(Transitional) 严格的(Strict) 框架的(Frameset)  1、打开一些符合标准的站点,例如著名 web 设计软件开发商 Macromedia,设计大师 Zeldman 的个人网站,会发现同上面一样的声明代码。 其中的 DTD(例如上例中的 xhtml1-transitional.dtd)叫文档类型定义,里面包含了文档的规则,浏览器就根据你定义的 DTD 来解释你页面的标识,并展现出来。 要建立符合标准的网页,DOCTYPE 声明是必不可少的关键组成部分;除非你的 XHTML 确定了一个正确的 DOCTYPE,否则你的标识和 CSS 都不会生效。  XHTML1.0提供了三种 DTD 声明可供选择: a.过渡的(Transitional):要求非常宽松的 DTD,它允许你继续使用 HTML4.01 的标识(但是要符合 XHTML 的写法)。完整代码如下:     b.严格的(Strict):要求严格的 DTD,不能再使用任何表现层的标识和属性,例如
      。完整代码如下:   c.框架的(Frameset):专门针对框架页面设计使用的 DTD,如果你的页面中包含有框架,需要采用这种 DTD。完整代码如下:   2、理想情况当然是严格的 DTD,但对于大多数刚接触 web 标准的学习者来说,过渡的 DTD(XHTML1.0Transitional)是目前理想选择(包括本 DTD)。因为这种 DTD 允许使用表现层的标识、元素 和属性,也比较容易通过 W3C 的代码校验。  3、补充:DOCTYPE 声明必须放在每一个 HTML 文档最顶部,在所有代码和标识之上。 HTML 常用标记  段落文字 链接 图片 列表 表格 表单 段落文字  分段控制标签

       换行标签
       水平分隔线


      标题文字标签 文字格式控制标签 分段控制标签

         

      段落标签的作用:使文本、图片、表格等之间留一空行。  范例代码: Hereisthetextformyparagraph.Itdoesn'tmatterhowlongitis,  howmanyspacearebetweenthewordsorwhenIdecidetohitthereturnkey.  ItwillcreateanewparagraphonlywhenIbeginthetagwithanotherone. 

      Here'sthenextparagraph.

        显示结果: Hereisthetextformyparagraph.Itdoesn'tmatterhowlongitis,howmanyspacearebetweenthewordsorwhenIdecidetohitthereturnkey.Itwillcreateanewparagraphonlywhen Ibeginthetagwithanotherone.  Here'sthenextparagraph.  换行标签
             欢迎使用 HTML     

      这会是一种很有趣的
      体验

        

       另一个段落元素

          水平分隔线
       
      水平标尺标签用于在页面上绘制一条水平线。它只有开始标签,没有结束标签,且不包含任何内容       

      我的第一个 HTML 文档

                        
        

      这将会是一种很有趣的体验

          标题文字标签  六种大小的标题 即

      为最大,

      为最小        

      HTML 简介

             

      HTML 简介

             

      HTML 简介

             

      HTML 简介

             
      HTML 简介
             
      HTML 简介
        文字格式控制标签  标签用于控制文本在网页上的显示。可以指定 size(大小)、color(颜色)、style(样式)等属性   

      我的第一个 HTML 文档  

       

                 将会是一种很有趣的体验

        超链接  Sun target 属性确定链接页面显示的窗口 _blank(新窗口),_self(原窗口),_parent,_top 文档内导航 ………Top 发送邮件 发送邮件 图片作为链接      图片区域产生链接          图片  标签 将图像插入到 html 文档中 格式: src 是属性,值是指定图像文件位置的 url 作用:将 img 标签放置在要显示图像的位置  图象的取代文字 alt   根据以下示例,讲解各属性的具体用途:   src=“logo.gif”  图片来源,接受 .gif,.jpg 及 .png 格式,若图片文件与该 html 文件同处一目录则只写图片名称即可,否则必须加上正确的途径;  width=“100”  height=“100”  设定图片大小,此宽度、及高度一般采用 pixels 作单位。通常只设为图片的真实大小以免失真,若要改变图片大小最好事先使用图像编辑工具;  hspace=“5” vspace=“5”  设定图片边沿空白,以免文字或其它图片过于贴近。hspace 是设定图片左右的空间,vspace 则是设定图片上下的空间,高度采用 pixels 作单位; border=“2”  图片边框厚度; align=“top” 调整图片旁边文字的位置,你可以控制文字出现在图片的偏上方、中间、底端、 左右等,可选值:top,middle,bottom,left,right,内定为 botom。要注意 left 和 right 的具体含义,是指图片位 于文字的哪一边,当设为 right 时,图片在右,文字在左。列表
        1.    无序列表 
                  
          • 星期一
          •       
          • 星期二
          •       
          • 星期三
          •       
          • 星期四
          •       
          • 星期五
          •  
           有序列表 使用
            替换
                无序列表:就同购物清单一样,要购买的每件商品没有次序之分,这样的列表称为无序列表。
                中的 title 属性,用来对此无序列表进行说明;
              • 中的 type 属性,有三个值: disc,circle,square; 方形项目符号; 实心圆项目符号; 空心圆项目符号 。  1、
                  称为顺序清单标签,用
                1. 表示清单项目。  2、所谓顺序清单就是在每一项前面加上 1,2,3... 等数目,又称编号清单。 3、如果想让编号清单从第 n 个值开始编号,则设 如:  
                2. Thisisitemnumber5.
                3.  
                4. Thisisnumber6!
                5.  
                6. Andsoforth...
                7.   
                 4、清单整体从某个值开始,如果突然想改变从某一项开始的编号,则设,后一项为 n+1,以此类推…… 如:
                    
                1. Itemnumber1
                2.  
                3. Andthesecond
                4.  Jumptonumber9 
                5. Andcontinuewith10...
                6.  
                 表格
        table        Name          
      age
      Java20
        单元格间隔和单元格填充 table 的 cellspacing 属性定义单元格之间的间距. table 的 cellpadding 属性定义单元格边界与单元格中内容的间距. 单元格的对齐方式 align 属性用于指明横向对齐方式. leftcenterright valign 属性纵向对齐方式.  topmiddlebottom 单元格的合并 td 的 colspan 用于指定单元格所占的列数, 用于横向合并单元格. td 的 rowspan 用于指定单元格所占的行数, 用于纵向合并单元格.      单元格一     单元格二   单元格三   单元格四        单元格五     单元格六   什么是表单(form)  form 表单是 HTML 的一个重要部分,主要用于采集和提交用户输入的信息 form 表单的三个要点  … 表单控件 action  method   1、先说表单控件(formcontrols),通过 HTML 表单的各种控件,用户可以输入文字信息,或者从选项中选择,以及做提交的操作。 2、用户填入表单的信息总是需要程序来进行处理,表单里的 action 就指明了处理表单信息的程序。 3、method,表示发送表单信息的方式。method 有两个常用值:get 和 post。get 的方式是将表单控件的 name/value 信息经过编码之后,通过 URL 发送(可以在地址栏里看到),而 post 则将表单 的内容通过 HTTP 发送,你在地址栏看不到表单的提交信息。 什么时候用 get,什么时候用 post 呢?一般是这样来判断的,如果只是为取得和显示数据,用 get;一旦涉及数据的保存和更新,那么建议用 post。  GET 和 POST 方式提交数据的区别: GET 请求被设计用于请求资源,但可以通过请求参数的方式提交基于文本的数据:  http://...?username=“java”&password=“whatisjava”  由于请求参数作为地址的一部分受到浏览器的限制(例如:IE 为 2K 个字符),因此GET 提交的数据量不能过大。 POST 请求被用于设计向服务器提交数据,提交的数据量会受到服务器的限制,但比 GET 方式会大很多; 另外 POST 方式还可以用于提交非文本数据(例如文件上传). 表单控件  TextField    TextArea default CheckBox 中文 English RadioButton  Male Female textarea 内文本长度不能指定,它没有 maxlength 这个属性,开发过程中经常通过 JavaScript 来控制文本长度。 List/Menu    北京   上海  Button      Fileupload  Hidden   CSS 使用  内联样式表(style 属性)   内部样式表(style 元素)      body{background-color:#FF0000;}   外部样式表(引用样式表文件)   1、引用外部 css 文件的语句必须被插入 HTML 代码的头部(header),即放在标签和标签之间。  2、通过引用外部 css 文件的链接告诉浏览器:在显示该 HTML 文件时,应使用给出的 CSS 文件进行布局。这种方法的优越之处在于:多个 HTML 文档可以同时引用一个样式表。换句话说,可以用一 个 CSS 文件来控制多个 HTML 文档的布局。CSS 语法   CSS 选择器  HTML 选择器—选择器是 HTML 标记的名称 p{color:red;font-weight:bold} 类选择器—使用 HTML 元素的 class 属性 .bigFont{font-size:200%} ID 选择器—使用 HTML 元素的 id 属性 #blueBack{background-color:blue;color:yellow} 

      利用Class和ID显示内容。

       与颜色与背景相关的 CSS 属性  color  background-color  background-image  background-repeat  background-attachment  background-position 与字体相关的 CSS 属性  font-family  font-style  font-weight  font-size 与文本相关的 CSS 属性  text-indent  text-align  text-decoration  letter-spacing  text-transform 盒子模型  元素的定位  float(漂浮) position(定位) z-index(叠放顺序)  负外边距解决方案 #container{ width:760px; position:absolute; left:50%; margin-left:-380px; } JavaScript 基础加强  于  洋   JavaScript基础加强 ....................................................................................................... 1 Tip: JavaScript特性概述 .................................................................................................................................................1 Tip:  使用JavaScript编程方式..........................................................................................................................................2 Tip: JavaScript变量定义 .................................................................................................................................................2 Tip:  常用操作  –  数组遍历 ...............................................................................................................................................2 Tip: JavaScript函数定义 .................................................................................................................................................2 Tip: JavaScript系统函数 .................................................................................................................................................3 Tip: JavaScript常用内置对象 ..........................................................................................................................................3 Tip: JavaScript  提供浏览器对象 .....................................................................................................................................3 Tip: window对象 ............................................................................................................................................................4 Tip: window对象提供对话框相关方法.............................................................................................................................4 Tip:  利用history对象制作返回按钮 .................................................................................................................................4 Tip:  利用location对象制作链接按钮 ...............................................................................................................................4 Tip: JavaScript DOM对象模型 .......................................................................................................................................5 Tip: JavaScript Document对象 .....................................................................................................................................5 Tip: JavaScript  事件机制................................................................................................................................................5 Tip:  阻止javascript的默认事件动作 ................................................................................................................................7   Tip: JavaScript 特性概述   浏览器内部运行的脚本语言 解释执行 弱类型语言 基于对象 JavaScript 内置对象 浏览器 DOM 对象Tip:  使用 JavaScript 编程方式  html 页面内部的 JavaScript         alert("这是第一个 JavaScript 程序!");        通常编写在 内部 引入外部的 JavaScript 文件  上面的 language=“JavaScript 也可以写成 "type="text/javascript" Tip: JavaScript 变量定义  所有数据类型都使用 关键字 var 定义 vara=10; vars=  “abc“ ;// 定义字符串 也可以使用 ‘abc’ vardate=newDate(); varisValid=true; vararray=newArray(“aaa“,”bbb”); Tip:  常用操作  –  数组遍历  数组遍历      vararr=newArray('aaa',"bbb");     for(vari=0;i Tip: JavaScript 函数定义  定义函数使用 function 关键字 不需要定义函数返回值 不需要定义函数参数类型 例如: functionadd(a,b){ returna+b; } varc=add(10,20);alert(c); Tip: JavaScript 系统函数  参加 W3C 提供文档 JS 对象 ---JSFunctions 顶层函数(全局函数) 常用全局函数 decodeURIComponent()  encodeURIComponent()  escape()/unescape()  eval()  isNaN()  ---notanumber parseInt()  Tip: JavaScript 常用内置对象  JSArray 数组 JSBoolean  布尔 JSDate  日期 JSMath数学 JSNumber 数字 JSString 字符串 Tip: JavaScript  提供浏览器对象  浏览器对象  DOMWindow 表示浏览器中打开的窗口  DOMNavigator 包含有关浏览器的信息  DOMScreen---获得屏幕分辨率 包含客户端显示屏幕的信息  DOMHistory包含用户(在浏览器窗口中)访问过的 URL  DOMLocation  包含有关当前 URL 的信息  Tip: window 对象  window 对象是一个全局对象,是所有对象的顶级对象 代表浏览器打开的窗口 通过 open 和 close 方法控制窗口打开关闭 window 对象的属性和方法可以直接使用 例如:window.alert(1); 可以写为 alert(1);  window.document.write(…) 可以写为  document.write(…)  适用于 Chrome,IE6,Safari 等几种浏览器的关闭方法:  varopened=window.open('about:blank','_self'); opened.opener=null; opened.close();  Tip: window 对象提供对话框相关方法  window.alert(String)  Booleanwindow.confirm(String)  Stringwindow.prompt(String)  Tip:  利用 history 对象制作返回按钮    go(-1) 效果等同于 back 函数 Tip:  利用 location 对象制作链接按钮   这里面的 location.href 和效果是一样的Tip: JavaScript DOM 对象模型  JavaScript 主要操作 HTML 页面元素  每一个标签中内容就是一个元素 在 JavaScript 中提供了两种操作元素方式 对 XML 的支持 --- 参数 XMLDOM 手册 DOMNodeDOMNodeList  DOMElementDOMAttrDOMText  同时根据 HTML 的常用元素提供 HTMLDOM   HTMLDOM 可以说 继承 XMLDOM,并扩展了 XMLDOM 的功能 Tip: JavaScript Document 对象  每个载入浏览器的 HTML 文档都会成为 Document 对象  全局检索对象操作 getElementById()  getElementsByName()  getElementsByTagName() 检索后对象可以使用XML DOM和HTML DOM 的 API Tip: JavaScript  事件机制  页面加载/卸载事件(页面关闭前确认) onload 和 onbeforeunload 聚焦与离焦事件 (form 实时校验) onfocus 和 onblur   键盘事件 (表单回车提交) onkeydown/onkeyup/onkeypress 鼠标事件 mousemove/mouseout/mouseover click/dblclick/mousedown/mouseup form提交确认事件 ---用于form校验  onsubmit  focus/blur   functioncheckDate(){  vardate1=document.getElementById("testdate").value;  if(date1.match("^\\d{8}$")==null){alert("wrong");}else{alert("right");} }   请输入一个八位数字    keydown/keyup/keypress   functionsubmitform(){ if(event.keyCode==13){document.forms(0).submit();}   }   没有按钮的表单,用回车键提交       submit/reset   functionisDelete(){ varisdelete=window.confirm(); if(isdelete){returntrue;} else{returnfalse;} }    姓名:小明  年龄:23  学校:清华大学      mousemove/mouseout/mouseover     functionmouseovertest(){  document.getElementById("info").value="鼠标在输入框上";}  functionmouseouttest(){   document.getElementById("info").value="鼠标在输入框外";}           click/dblclick/mousedown/mouseup     functionaddFile(){ varfile=document.createElement('input'); file.setAttribute('id','temp_file'); file.setAttribute('type','file'); document.body.appendChild(file); }            Tip:  阻止 javascript 的默认事件动作  阻止 javascript 的默认事件动作 functionconfirmDel(e){   //e 是一个事件对象   // 提示用户确认   varisConfirm=window.confirm("是否删除?"); if(!isConfirm){    // 用户取消删除 if(e&&e.preventDefault){ //此时不是 IE e.preventDefault();//官方DOM提供方法 火狐可以用 }else{ //此时IE window.event.returnValue=false; } } }数据库基础强化    数据库基础强化............................................................................................................... 1 重点内容...........................................................................................................................................................................1 数据库和数据库管理系统 ..................................................................................................................................................2 关系化数据库管理系统......................................................................................................................................................2 关系化数据库的设计 .........................................................................................................................................................3 数据库建模 .......................................................................................................................................................................3 ER图建模要点...................................................................................................................................................................4 ER图.................................................................................................................................................................................4 实体集(Entity Set)...........................................................................................................................................................4 属性(Attributes) .............................................................................................................................................................5 联系(Relationship) .........................................................................................................................................................5 关系化模型的相关概念......................................................................................................................................................6 E-R图转换为表的规则.......................................................................................................................................................6 M:N的联系引入关系表 .....................................................................................................................................................7 1:N  的联系可不引入关系表..............................................................................................................................................7 1:1 的联系不必引入关系表................................................................................................................................................7 范式..................................................................................................................................................................................7 好的关系的特点 ................................................................................................................................................................8 1NF  第一范式..................................................................................................................................................................8 2NF  第二范式..................................................................................................................................................................8 3NF  第三范式..................................................................................................................................................................9 完整性约束 .......................................................................................................................................................................9  重点内容  数据库概论知识 E-R 图 范式理论 完整性约束 常用 SQL 语句 DDL(DataDefinitionLanguage)  DML(DataManipulationLanguage)  DCL(DataControlLanguage)  DQL(DataQueryLanguage)  数据处理发展简史   软件通常要处理大量数据。数据处理的发展历经了 3 个阶段:  20 世纪 50 年代中期以前是计算机用于数据管理的初级阶段,计算机只相当一个计算工具没有操作系统,没有管理数据的软件。这个时期数据管理的主要特点在于:主要用于科学计算,数据并不长期 保存;数据的管理由程序员个人考虑安排,迫使用户程序与物理地址直接打交道,效率低,数据管理不具备安全性和灵活性;数据与程序不具备独立性,数据成为程序的一部分,导致程序之间大量数 据重复。  50 年代后期到 60 年代中期计算机有了磁盘、磁带等直接存取的外存储器设备,操作系统有了专门管理数据的软件--文件系统。文件系统使得计算机数据管理的方法得到极大改善。这个时期的特点是: 计算机大量用于管理,数据需要长期保存,可以将数据存放在外存上反复处理和使用;数据文件可以脱离程序而独立存在,应用程序可以通过文件名来存取文件中的数据,实现数据共享;所有文件由 文件管理系统进行统一管理和维护。但该方法也有其不足之处,体现在数据冗余性、数据不一致性和数据之间联系比较弱。  数据库系统的萌芽出现于 20 世纪 60 年代。当时计算机开始广泛地应用于数据管理,对数据的共享提出了越来越高的要求。传统的文件系统已经不能满足人们的需要。能够统一管理和共享数据的数据 库管理系统(DBMS)应运而生。   设计数据库系统的目的是为了管理大量信息。对数据的管理既涉及到信息存储结构的定义,又涉及信息操纵机制的提供,此外,数据库系统还必须提供所存储信息的安全性保证,即使在系统崩溃或有 人企图越权访问时也应保障信息的安全性。 数据库和数据库管理系统  数据库 存放数据的仓库 按一定数据模型组织和存储 需要频繁搜索和读取 数据库管理系统 管理数据库的软件  Database(数据库):以便于快速搜索和获取的方式组织的大量数据的集合。 DBMS:数据库管理系统(DatabaseManagementSystem),DBMS 是位于用户与操作系统之间的一层数据管理软件,为用户或应用程序提供访问数据库的方法,包括 DB 的建立、查询、更新及各 种数据控制。  “数据库”作为短语最早使用的是在 1963 年 6 月,System Development Corporation 赞助举办了一个题为“开发计算机管理中心数据库”(“Development and Management of a Computer-centeredDataBase”)的研讨会。数据库作为一个独立的单词大量出现在 70 年代初的欧洲,直到二十世纪末才被美国各大报纸使用。 第一数据库管理系统开发于 1960,在此之前,数据处理是基于穿孔卡片和磁带。 两大数据模型从那时起延续至今:CODASYL 根据 Bachman 的思想开发的网络模型以及应用于 NorthAmericanRockwell 开发的一个系统中的层次模型。 关系模型由 E.F.Codd 于 1970 年提出。 第一商业产品 ,甲骨文和 DB2 在 1980 年左右面市。 第一个成功的微机数据库产品是运行于 CP/M 和 PC-DOS/MS-DOS 操作系统上的 dBASE。  90 年代,重点转向面向对象数据库。 2000 年后,热点是 XML 数据库。 目前基于关系化模型的数据库仍然是应用最为广泛的数据库。 关系化数据库管理系统  基于关系化数据模型的数据库管理系统 数据存储在很多表中  常见关系化数据库  常见的关系化数据库 商业化数据库 Oracle http://www.oracle.com/index.html 微软的 SQLServer  http://www.microsoft.com/SQL/default.mspx IBM 的 DB2 http://www-306.ibm.com/software/data/db2/9/download.html Sybase http://www.sybase.com/  开源的数据库 MySQL http://www.mysql.com/ SQLite http://www.sqlite.org/ HSQLDB 纯 Java 小型数据库 http://www.hsqldb.org/ PostgreSQL http://www.postgresql.org/ 关系化数据库的设计  了解需求 抽象出实体和实体间的联系,使用 ER 图来描述 把 ER 图转换为关系(表) 将关系分开以避免冗余(范式) 为数据添加完整性约束 操作关系型数据库通用语言 SQL 数据库建模  给程序中使用的数据创建模型 程序开发过程中重要的一步 现实世界到信息世界的第一层抽象 数据库建模 数据库建模指的是对现实世界各类数据的抽象组织,确定数据库需管辖的范围、数据的组织形式等直至转化成现实的数据库。  一旦需要将现实中的数据保存中数据库中,必须要进行数据库建模,本章主要讲述 ER 模型的建模方法。数据库建模的过程就是进行数据库设计的过程。 ER 图建模要点  建模过程 抽象出实体和联系,使用 ER 图表示 将 ER 图转化为多个关系模式(表结构) 使用范式消除冗余 基本元素 实体集 属性 关系 关系的基数 实体联系模型(EntityRelationshipModel),又称 ER 模型 ,ER 图。 ER 图用于粗略地表示数据库设计,非常方便,并且有成熟的规则可以将 ER 图转换成最终数据库中关系和表的设计。  P.P.Chen于 1976 年发表的一篇文章中提出统一建摸语言(UnifiedModelingLanguage,简称 UML)来图形表示 ER 模型。 UML 是一种可视化建模语言 ,1994 年开始 Rational 公司的 3 位面向对象方法学的创始人 Rumbaugh、Booch 和 Jacobson 先后开始合作, 于 1997 年提交给对象管理组(ObjectManagementGroup,简称 OMG),被采纳为面向对象建模方法的标准。 两种表示方式的实质没什么区别,只是所用的工具和图示不同。 ER 图  世界由一组称作实体的基本对象及这些对象间的联系组成 用图形的方法,描述实体集之间的联系 供使用者进行交流 数据库设计人员 程序员 用户 实体集(Entity Set)   实体(Entity) 客观存在并可相互区别的事件或物体 实体集(Entity Set) 具有相同类型、相同性质的实体的集合 用矩形表示属性(Attributes)  实体所具有的某一特性  用与实体集相连的椭圆表示 主标识属性加下划线表示  属性可分为以下类型 主标识属性在属性名下加下划线表示,主标识属性可以唯一的确定一个实体 多值属性(用双线与实体集相连) 复合属性(与其他属性相连) 联系(Relationship)  用与相应的实体集相连的菱形表示 表示实体集之间的关联 联系可能有自己的属性  特殊的联系-有属性的联系  联系的基数  E-R 图表示几种不同的联系  关系化模型的相关概念  关系-表 属性-列名 元组-行   关系化数模型中的术语对照 关系:Relation- 表:Table 属性:Attribute- 列名:ColumnHeaderName 元组:Tuple- 行或者记录:Row/Record 另外 ER 图中的主标识属性在关系化数据库中通常称为主键(PrimaryKey)。 关系模式 关系名(属性名 [属性类型],…)  数据库模式 数据库中所有关系模式的集合  关系模式的实质是表的定义。 而数据库模式是数据库中所有表的定义。 E-R 图转换为表的规则  每个实体集转化为一张表 除多值属性以外的所有属性对应着字段 实体的主标识称为主键 组合属性将其子属性转化为表中的属性 组合属性本身不转换 多值属性和实体的主标识属性组合转化为一张表 表中的所有属性为表的主键 也可单独设立主键M:N 的联系引入关系表  联系的属性及两个实体的主标识形成关系表。 关系表的主键为两个实体主标识的组合  参加表(E1,P1,percent) 雇员表(E1,E2) 项目表(P1,P2,P3) 1:N  的联系可不引入关系表  将关系的属性及非多方的主标识加入到多方表 多方表的外键是非多方实体的主标识  老师表(Tid,Tname,Tsex) 课程表(Cid,Cname,Tid,allowance)  外键实际上是一种约束,表示这个属性是另一个实体集中的主标识属性,即另一个表中的主键。 外键用于建立和加强两个表数据之间的链接的一列或多列。 1:1 的联系不必引入关系表   方案一 presidents(Eid,Ename) studios(Sid,Sname,Eid ,year ) 方案二 presidents(Eid,Ename ,Sid ,year) studios(Sid,Sname) 范式  范式是符合某一种级别的关系模式的集合 关系数据库中的关系必须满足一定的要求,满足不同程度要求的为不同范式 范式的种类 第一范式(1NF)第二范式(2NF) 第三范式(3NF) BC 范式(BCNF) 目的 消除冗余 例如:学生(学号,姓名,系名,系主任名)   冗余的坏处 数据冗余太大 浪费大量的存储空间 例:每一个系主任的姓名重复出现 更新异常(UpdateAnomalies) 数据冗余 ,更新数据时,维护数据完整性代价大 例:某系更换系主任后,系统必须修改与该系学生有关的每一个元组 插入异常(InsertionAnomalies) 该插的数据插不进去 如果一个系刚成立,尚无学生,就无法把这个系及其系主任的信息存入数据库 删除异常(DeletionAnomalies) 不该删除的数据不得不删 如果某个系的学生全部毕业了,在删除该系学生信息的同时,把这个系及其系主任的信息也丢掉了 好的关系的特点  不发生插入异常、删除异常、更新异常 数据冗余应尽可能少 原因:由存在于模式中的某些数据依赖引起的 解决方法:通过分解关系来消除其中不合适的数据依赖 1NF  第一范式  数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性 第一范式是对关系模式的最起码的要求。不满足第一范式的数据库模式不能称为关系数据库 如职工号,姓名,电话号码组成一个表(一个人可能有一个办公室电话 和一个家里电话号码) 规范成为 1NF 有三种方法 一是重复存储职工号和姓名。这样,关键字只能是电话号码 二是职工号为关键字,电话号码分为单位电话和住宅电话两属性  三是职工号为关键字,但强制每条记录只能有一个电话号码 以上三个方法,第一种方法最不可取,按实际情况选后两种情况  2NF  第二范式  不存在非关键字段对任一候选关键字段的部分函数依赖 选课表(学号, 姓名, 年龄, 课程名称, 成绩, 学分)  拆分后的关系 学生(学号,姓名,年龄) 课程(课程名称,学分)选课表(学号,课程名称,成绩)  第二范式要求数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖 。 部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的情况, 也即所有非关键字段都完全依赖于任意一组候选关键字 3NF  第三范式  没有非关键字段传递依赖主键 非关键字段只依赖于主键 学生(学号, 姓名, 系名, 系主任名)  不符合第三范式的需要拆分关系 学生(学号, 姓名, 系名) 系(系名, 系主任名) 完整性约束  Primary key 主键约束,一个表一个 Unique 唯一约束,值不能重复 Foreign key 外键约束,列值要匹配指向的表的相应列值 Check 检查约束,给列的取值范围加条件 Not NULL 非空约束,只能附加在列中  完整性约束是一种规则,不占用任何数据库空间。完整性约束存在数据字典中,在执行 SQL 或 PL/SQL 期间使用。用户可以指明约束是启用的还是禁用的,当约束启用时,增强了数据的完整性,否则, 则反之,但约束始终存在于数据字典中。 Check 约束 在数据列上 Check 约束需要 一个特殊的布尔条件或者将数据列设置成 TRUE,至少一个数据列的值是 NULL,Check 约束用于增强表中数据内容的简单的商业规则。用户使用 Check 约束保证 数据规则的一致性。check 约束可以涉及该行同属 Check 约束的其他数据列但不能涉及其他行或其他表,或调用函数 SYSDATE,UID,USER,USERENV。如果用户的商业规则需要这类的数据检查, 那么可以使用触发器。Check 约束不保护 LOB 数据类型的数据列和对象、嵌套表、VARRY、ref 等。单一数据列可以有多个 Check 约束保护,一个 Check 约束可以保护多个数据列。 NOTNULL 约束 NOTNULL约束应用在单一的数据列上,并且他保护的数据列必须要有数据值。缺省状况下,ORACLE 允许任何列都可以有 NULL 值。某些商业规则要求某数据列必须要有值,NOT NULL 约 束将确保该列的所有数据行都有值。 唯一性约束(Uniqueconstraint) 唯一性约束可以保护表中多个数据列,保证在保护的数据列中任何两行的数据都不相同。唯一性约束与表一起创建,在唯一性约束创建后,可以使用 ALTERTABLE 语句修改。 主键(PrimaryKey)约束 表有唯一的主键约束。表的主键可以保护一个或多个列,主键约束可与 NOT NULL 约束共同作用于每一数据列。NOT NULL 约束和唯一性约束的组合将保证主键唯一地标识每一行。像唯一性 约束一样,主键由 B-tree 索引增强。 外部键约束(Foreignkeyconstraint) 外部键约束保护一个或多个数据列,保证每个数据行的数据包含一个或多个 null 值,或者在保护的数据列上同时拥有主键约束或唯一性约束。引用(主键或唯一性约束)约束可以保护同一个表, 也可以保护不同的表。与主键和唯一性约束不同外部键不会隐式建立一个 B-tree 索引。在处理外部键时,我们常常使用术语父表(parenttable)和子表(childtable),父表表示被引用主键或唯一性约 束的表,子表表示引用主键和唯一性约束的表。Java 基础加强  第一部分  于 洋 Java基础加强  第一部分.................................................................................................. 1 Eclipse的使用 ..................................................................................................................................................................1 程序的调试和运行.............................................................................................................................................................2 单体测试—— Junit4.x ....................................................................................................................................................2 JDK 5.0  新特性 ...............................................................................................................................................................2 泛型(Generic)—泛形的作用.............................................................................................................................................3 泛型(Generic)  —泛形的作用...........................................................................................................................................3 泛型典型应用....................................................................................................................................................................3 自定义泛形——泛型方法..................................................................................................................................................4 自定义泛形——泛型类 .....................................................................................................................................................4 泛型的高级应用——通配符 ..............................................................................................................................................4 泛型的高级应用——有限制的通配符 ................................................................................................................................5 枚举类 ..............................................................................................................................................................................5 枚举类 ..............................................................................................................................................................................5 枚举类案例 .......................................................................................................................................................................6 枚举类API ........................................................................................................................................................................6 静态导入...........................................................................................................................................................................6 自动装箱/拆箱 ..................................................................................................................................................................6 自动装箱/拆箱练习 ...........................................................................................................................................................7 for/in语句 .......................................................................................................................................................................7 for/in语句 .......................................................................................................................................................................7 让Class可用于for/in........................................................................................................................................................8 移除练习...........................................................................................................................................................................8 可变参数...........................................................................................................................................................................8 反射..................................................................................................................................................................................8 Class类 ............................................................................................................................................................................9 Constructor类 ................................................................................................................................................................9 Field类.............................................................................................................................................................................9 Method类 .................................................................................................................................................................... 10  Eclipse 的使用  工作空间(workspace)、工程(project)、工作组(working set) 在 eclipse 下 Java 程序的编写和运行,及 java 运行环境的配置。 快捷键的配置,常用快捷键: 内容提示(ContentAssist):Alt+/  (自定义模板:Templates) 快速修复(QuickFix):Ctrl+1 导包:ctrl+shift+O 格式化代码块:ctrl+shift+F  ---> 配置代码自动格式化 添加(除去)块注释 Ctrl+Shift+/(Ctrl+Shift+\)添加(除去)单行注释 Ctrl+/  移动代码:选中行 alt+上/下 删除行:ctrl+D 查看方法说明:F2 重置透视图 查看类 ctrl+shift+T 程序的调试和运行  查看关键位置数据 System.out Log 技术 使用 Eclipse 的 Debug 功能 查看类源代码:ctrl+鼠标左键/F3  前向后:Alt+ 方向键 查看类继承关系:F4 F5(跳入)F6(跳过)F7(跳出)debug模式 单体测试——  Junit4.x  取代 main 方法快速测试程序 @Test: 测试方法 @Ignore: 被忽略的测试方法 @Before: 在每个测试方法执行之前都要执行一次。 @After: 在每个测试方法执行之后要执行一次。 @BeforeClass: 所有测试开始之前运行 static @AfterClass: 所有测试结束之后运行 static 使用断言判断测试结果 assertEquals(expected,actual) assertNull(object) assertNotNull(object) assertTrue(condition) assertFalse(condition) JDK 5.0  新特性  JDK5 中新增了很多新的 java 特性,利用这些新语法可以帮助开发人员编写出更加高效、清晰,安全的代码。 泛型 枚举 静态导入自动装箱/拆箱 for/in 语句 可变参数 注解、字符串格式化、Java5 线程并发库 泛型(Generic)—泛形的作用  JDK5 以前,对象保存到集合中就会失去其特性,取出时通常要程序员手工进行类型的强制转换,这样不可避免就会引发程序的一些安全性问题。例如: ArrayListlist=newArrayList(); list.add("abc"); Integernum=(Integer)list.get(0);  //运行时会出错,但编码时发现不了  list.add(newRandom()); list.add(newArrayList()); for(inti=0;i list = new ArrayList(); 注意:泛型是提供给 javac 编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。 但编译器编译完带有泛形的 java 程序后,生成的 class 文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。 泛形的基本术语,以 ArrayList为例:<>念着 typeof ArrayList中的 E 称为类型参数变量 ArrayList中的 Integer 称为实际类型参数 整个 ArrayList称为参数化的类型 ParameterizedType  泛型典型应用  使用 Type-Safe 的 List、Set、Map 接受 Parameterized Type 作为参数 返回 Parameterized Type 使用 Parameterized Type 作为类型参数 泛型的类型转换 Listints=newLinkedList(); Listnums=newLinkedList();自定义泛形——泛型方法  Java 程序中的普通方法、构造方法和静态方法中都可以使用泛型。方法使用泛形前,必须对泛形进行声明,语法: ,T 可以是任意字母,但通常必须要大写。通常 需放在方法的返回值声明之前。例如:  publicstaticvoiddoxx(Tt); 练习: 编写一个泛形方法,实现指定位置上数组元素的交换。 编写一个泛形方法,接收一个任意数组,并颠倒数组中的所有元素。 注意: 只有对象类型才能作为泛型方法的实际参数。 在泛型中可以同时有多个类型,例如:   publicstaticVgetValue(Kkey){returnmap.get(key);} 自定义泛形——泛型类  如果一个类多处都要用到同一个泛型,这时可以把泛形定义在类上(即类级别的泛型),语法格式如下:  publicclassGenericDao{   privateTfield1; publicvoidsave(Tobj){}   publicTgetId(intid){} } 注意,静态方法不能使用类定义的泛形,而应单独定义泛形。 泛型的高级应用——通配符  定义一个方法,接收一个集合,并打印出集合中的所有元素,如下所示: voidprint(Collectionc){  for(Stringe:c){  System.out.println(e);  } } 问题:该方法只能打印保存了 Object 对象的集合,不能打印其它集合。通配符用于解决此类问题,方法的定义可改写为如下形式: voidprint(Collectionc)  {   //Collection(发音为:"collectionofunknown")  for(Objecte:c){  System.out.println(e); } } 此种形式下需要注意的是:由于 print 方法 c 参数的类型为 Collection,即表示一种不确定的类型,因此在方法体内不能调用与类型相关的方法,例如 add()方法。总结:使用?通配符主要用于引用对象,使用了?通配符,就只能调对象与类型无关的方法,不能调用对象与类型有关的方法。 泛型的高级应用——有限制的通配符  限定通配符的上边界: 正确:Vectorx=newVector(); 错误:Vectorx=newVector(); 限定通配符的下边界: 正确:Vectorx=newVector(); 错误:Vectorx=newVector(); 问题:以下代码行不行? publicvoidadd(Listlist){  list.add("abc"); } 枚举类  为什么需要枚举? 一些方法在运行时,它需要的数据不能是任意的,而必须是一定范围内的值,此类问题在 JDK5 以前采用自定义带有枚举功能的类解决,Java5 以后可以直接使用枚举予以 解决 JDK 5 新增的 enum 关键字用于定义一个枚举类 创建枚举格式: enum 枚举类型名称 { 枚举对象 1 名称, 枚举对象 2 名称, …, 枚举对象 n 名称; } 枚举类  枚举类具有如下特性: 枚举类也是一种特殊形式的 Java 类。 枚举类中声明的每一个枚举值代表枚举类的一个实例对象。 与 java 中的普通类一样,在声明枚举类时,也可以声明属性、方法和构造函数,但枚举类的构造函数必须为私有的(这点不难理解)。 枚举类也可以实现接口、或继承抽象类。 JDK5 中扩展了 swith 语句,它除了可以接收 int,byte,char,short 外,还可以接收一个枚举类型。 若枚举类只有一个枚举值,则可以当作单态设计模式使用。枚举类案例  枚举解决一个什么问题 员工、角色案例 带参数构造方法的枚举类型举例 带有方法的枚举类型举例 带有抽象方法的枚举类型举例 练习:请编写一个关于星期几的枚举 WeekDay,要求: 枚举值:Mon,Tue,Wed,Thu,Fri,Sat,Sun  该枚举要有一个方法,调用该方法返回中文格式的星期。 枚举类 API  Java 中声明的枚举类,均是 java.lang.Enum 类的孩子,它继承了 Enum 类的所有方法。常用方法: name() ordinal() valueof(ClassenumClass,Stringname) 自定义的枚举类 valueof(Stringname) values() 此方法虽然在 JDK 文档中查找不到,但每个枚举类都具有该方法,它遍历枚举类的所有枚举值非常方便 思考 枚举对象、枚举对象下标、枚举字符串表示之间的转换 静态导入  JDK 1.5 增加的静态导入语法用于导入类的某个静态属性或方法 使用静态导入可以简化程序对类静态属性和方法的调用。 语法:Import static 包名.类名.静态属性|静态方法|* 例如: importstaticjava.lang.System.out; importstaticjava.util.Arrays.sort; importstaticjava.lang.Math.*; 自动装箱/拆箱  JDK5.0 的语法允许开发人员把一个基本数据类型直接赋给对应的包装类变量, 或者赋给 Object 类型的变量,这个过程称之为自动装箱。 自动拆箱与自动装箱与之相反,即把包装类对象直接赋给一个对应的基本类型变量。 典型应用:  Listlist=newArrayList(); list.add(1);  intj=(Integer)list.get(0); 自动装箱/拆箱练习  publicvoiddoSomething(doubled){} publicvoiddoSomething(Integeri){} 下面的代码会执行上面哪个方法? intfoo=1; doSomething(foo); for/in 语句   引入增强 for 循环的原因:抛弃 Iterator for/in 语句的适用范围 遍历数组 遍历实现 Iterable 接口的集合类 语法格式:  for(变量类型 变量 :需迭代的数组或集合){  } for/in 语句  使用增强 for 循环的几个注意事项(以下程序的输出结果?) intarr[]=newint[5]; for(intnum:arr){  num=1; } System.out.println(arr[0]); Listlist=newArrayList(); list.add("xxx"); for(Stringstr:list){  str="yyy"; } System.out.println(list.get(0)); 让 Class 可用于 for/in  实现 Iterable publicinterfaceIterable{ Iteratoriterator(); } 提供 Iterator publicinterfaceIterator{ booleanhasNext(); Enext(); voidremove(); } 移除练习  定义一个 List集合,将”abc”,”bcd”,”asf”,”ceg”,”daf”,”dfs”存入集合,遍历集合移除所有包含字母”a” 的字符串,并在移除后输出结果。 结果:bcd,ceg,dfs 可变参数  测试 JDK 中具有可变参数的类 Arrays.asList()方法。分别传多个参、传数组,传数组又传参的情况。 注意:传入基本数据类型数组的问题。 从 JDK 5 开始, Java 允许为方法定义长度可变的参数。语法:   publicvoidfoo(int…args){ } 注意事项: 调用可变参数的方法时, 编译器将自动创建一个数组保存传递给方法的可变参数,因此,程序员可以在方法体中以数组的形式访问可变参数 可变参数只能处于参数列表的最后, 所以一个方法最多只能有一个长度可变的参数 反射  JavaSE 中的高级特性 什么是反射? 剖析 Java 类中的各个组成部分映射成一个个 java 对象 类 java.lang.Class java.lang.reflect  构造方法 Constructor 成员变量 Field 方法 Method 反射用在哪里 多用于框架和组件,写出复用性高的通用程序 Class 类  Java 中 java.lang.Class 类用于表示一个类的字节码(.class)文件 如何得到某个 class 文件对应的 class 对象 已知类和对象的情况下 类名.class  对象.getClass() 未知类和对象的情况下 Class.forName(“包名.类名”)   Class 类代表某个类的字节码,并提供了加载字节码的方法:forName(“包名.类名”) forName 方法用于加载类字节码到内存中,并封装成一个 Class 对象 Constructor 类  Constructor 类的实例对象代表类的一个构造方法 得到某个类所有的构造方法  Constructor[]constructors=Class.forName("java.lang.String").getConstructors(); 得到指定的构造方法并调用 Constructorconstructor=Class.forName(“java.lang.String”).getConstructor(String.class); Stringstr=(String)constructor.newInstance(“abc”); Class 类的 newInstance()方法用来调用类的默认构造方法 Stringobj=(String)Class.forName("java.lang.String").newInstance(); Field 类  Field 类代表某个类中的一个成员变量,并提供动态的访问权限 Field 对象的获得 得到所有的成员变量 Field[]fields=c.getFields();// 取得所有 public 属性Field[]fields=c.getDeclaredFields();// 取得所有声明的属性 得到指定的成员变量 Fieldname=c.getField("name"); Fieldname=c.getDeclaredField("name"); 设置 Filed 变量是否可以访问 field.setAccessible(boolean); Field 变量值的读取、设置 field.get(obj) filed.set(obj,value); Method 类  Method 类代表某个类中的一个成员方法 得到类中的某一个方法: 例子:       MethodcharAt=Class.forName("java.lang.String").getMethod("charAt",int.class); 调用方法: 通常方式:System.out.println(str.charAt(1)); 反射方式:System.out.println(charAt.invoke(str,1));  如果传递给 Method 对象的 invoke()方法的第一个参数为 null,这有着什么样的意义呢?说明该 Method 对象对应的是一个静态方法! jdk1.4 和 jdk1.5 的 invoke 方法的区别: Jdk1.5:publicObjectinvoke(Objectobj,Object...args) Jdk1.4:publicObjectinvoke(Objectobj,Object[]args) 即按 jdk1.4 的语法,需要将一个数组作为参数传递给 invoke 方法时,数组中的每个元素分别对应被调用方法中的一个参数,所以,调用 charAt 方法的代码也可以用 Jdk1.4 改写为 charAt.invoke(“str”,newObject[]{1})形式。 Java 基础加强  第二部分  于洋 Java基础加强  第二部分.................................................................................................. 1 Annotation(注解)  概述 ..................................................................................................................................................2 注解的应用结构图.............................................................................................................................................................2 自定义  Annotation.........................................................................................................................................................3 JDK  的元  Annotation ...................................................................................................................................................3 提取  Annotation  信息 ...................................................................................................................................................3 动态代理...........................................................................................................................................................................4 内部类 ..............................................................................................................................................................................4 普通内部类 .......................................................................................................................................................................5 静态内部类 .......................................................................................................................................................................5 方法和作用域中的内部类 ..................................................................................................................................................6 匿名内部类 .......................................................................................................................................................................6 主线程 ..............................................................................................................................................................................7 线程体 ..............................................................................................................................................................................7 创建线程...........................................................................................................................................................................7 java.lang.Thread类 ........................................................................................................................................................9 两种创建线程方法的比较 ..................................................................................................................................................9 join方法使用示例 .......................................................................................................................................................... 10 守护(deamon)线程....................................................................................................................................................... 10 线程的调度 .................................................................................................................................................................... 11 线程的优先级................................................................................................................................................................. 11 监视器(锁)................................................................................................................................................................. 11 同步(synchronized)................................................................................................................................................. 12 同步原理........................................................................................................................................................................ 12 死锁............................................................................................................................................................................... 12 多线程协作-wait和notify ............................................................................................................................................. 13 Lock&Condition实现线程同步通信 ............................................................................................................................. 13 线程池 ........................................................................................................................................................................... 13 计算机网络基本知识 ...................................................................................................................................................... 14 计算机网络基本知识 ...................................................................................................................................................... 14 什么是Socket?............................................................................................................................................................ 15 Annotation(注解)  概述   从 JDK 5.0 开始, Java 增加了对元数据(MetaData) 的支持, 也就是 Annotation(注解)。 什么是 Annotation,以及注解的作用?三个基本的 Annotation: @Override: 限定重写父类方法, 该注解只能用于方法 @Deprecated: 用于表示某个程序元素(类, 方法等)已过时 @SuppressWarnings: 抑制编译器警告.  Annotation 其实就是代码里的特殊标记, 它用于替代配置文件,也就是说,传统方式通过配置文件告诉类如何运行,有了注解技术后,开发人员可以通过注解告诉类如何运 行。 在 Java 技术里注解的典型应用是:可以通过反射技术去得到类里面的注解,以决定怎么去运行类。 掌握注解技术的要点: 如何定义注解 如何反射注解,并根据反射的注解信息,决定如何去运行类  @SuppressWarnings unused 变量未使用 deprecation 使用了不赞成使用的类或方法时的警告  unchecked 执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型。  fallthrough 当 Switch 程序块直接通往下一种情况而没有 Break 时的警告。  path 在类路径、源文件路径等中有不存在的路径时的警告。  serial 当在可序列化的类上缺少 serialVersionUID 定义时的警告。  finally 任何 finally 子句不能正常完成时的警告。  all 关于以上所有情况的警告。  注解的应用结构图  注解类 应用了“注解类”的类 对“应用了注解类的类”进行反射操作的类  注解就相当于一个你的源程序中要调用的一个类,要在源程序中应用某个注解,得先准备好了这个注解类。就像你要调用某个类,得先有开发好这个类。 自定义  Annotation  定义新的 Annotation 类型使用 @interface 关键字 所有的 Annotation 自动继承 java.lang. annotation.Annotation 接口 声明注解的属性 注解属性的作用:原来写在配置文件中的信息,可以通过注解的属性进行描述。 Annotation 的属性声明方式:Stringname(); 属性默认值声明方式:Stringname()default “xxx”; 特殊属性 value:如果注解中有一个名称 value 的属性,那么使用注解时可以省略 value=部分,如@MyAnnotation(“xxx") 特殊属性 value[]; 注解支持类型:八种基本数据类型和 String、Enum、Class、annotation 以及以上类型的数组) JDK  的元  Annotation  元 Annotation 指修饰 Annotation 的 Annotation。JDK 中定义了如下元 Annotation: @Retention: 只能用于修饰一个 Annotation 定义, 用于指定该 Annotation 可以保留的域, @Rentention 包含一个 RetentionPolicy 类型的成员变量, 通过这个变量指定域。 RetentionPolicy.CLASS: 编译器将把注解记录在 class 文件中. 当运行 Java 程序时,JVM 不会保留注解. 这是默认值 RetentionPolicy.RUNTIME:编译器将把注释记录在 class 文件中. 当运行 Java 程序时,JVM 会保留注解. 程序可以通过反射获取该注释 RetentionPolicy.SOURCE: 编译器直接丢弃这种策略的注释 @Target:指定注解用于修饰类的哪个成员. @Target 包含了一个名为 value,类型为 ElementType 的成员变量。 @Documented: 用于指定被该元 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档. @Inherited: 被它修饰的 Annotation 将具有继承性.如果某个类使用了被 @Inherited 修饰的 Annotation, 则其子类将自动具有该注解 提取  Annotation  信息  JDK 5.0 在 java.lang.reflect 包下新增了 AnnotatedElement 接口, 该接口代表程序中可以接受注释的程序元素 当一个 Annotation 类型被定义为运行时 Annotation 后, 该注释才是运行时可见, 当 class 文件被载入时保存在 class 文件中的 Annotation 才会被虚拟机读取 程序可以调用 AnnotatedElement 对象的如下方法来访问 Annotation 信息 动态代理   代理对象存在的价值:主要用于拦截对真实业务对象的访问 代理对象应该提供与真实业务对象一样的方法 使用动态代理,只要为真实业务对象生成代理对象即可 操作代理对象的方法,间接访问真实对象的业务方法 Java 提供了一个 Proxy 类,调用它的 newInstance 方法可以生成某个对象的代理对象,使用该方法生成代理对象时,需要三个参数: 1.生成代理对象使用哪个类装载器 2.生成哪个对象的代理对象,通过接口指定 3.生成的代理对象的方法里干什么事,由开发人员编写 handler 接口的实现来指定。 初学者必须记住的 2 件事情: Proxy 类负责创建代理对象时,如果指定了 handler(处理器),那么不管用户调用代理对象的什么方法,该方法都是调用处理器的 invoke 方法。 由于 invoke 方法被调用需要三个参数:代理对象、方法、方法的参数,因此不管代理对象哪个方法调用处理器的 invoke 方法,都必须把自己所在的对象、自己(调用 invoke 方法的方法)、方法的参数传递进来。  内部类   一个类的定义嵌套在另一个类内部 分类 普通内部类 嵌套类(静态内部类) 方法和作用域中的内部类 匿名内部类 意义 隐藏实现细节,增强封装性 方便共享数据 使得程序代码更为紧凑,程序更具模块化 提高性能 普通内部类  可以访问外部类中的所有数据和方法,包括私有数据和方法 每个内部类的实例与一个外部类的实例相关 使用 Outer.this 引用外部实例 内部类实例化依赖外部实例 可使用 private,protected 修饰 不允许定义静态成员 publicstaticvoidmain(String[]args){ Outerouter=newOuter();         Outer.Innerinner=outer.newInner(); } classOuter{     privateinti=1; privateclassInner{ inti; Inner(){ this.i=Outer.this.i*2; } } } 静态内部类  使用 static 关键字修饰 没有对外部对象的引用 和外部类相关而与外部实例无关 不能直接访问外部类中的实例成员 publicclassTimerTest{ staticclassTaskextendsTimerTask{ publicvoidrun(){                        System.out.println("当前时间:"+newjava.util.Date()); } }        publicstaticvoidmain(String[]args){                Timertimer=newTimer(); timer.schedule(newTask(),newjava.util.Date(),5000); } } 方法和作用域中的内部类  只在作用域中可见 可访问作用域中的 final 变量 publicstaticvoidmain(String[]args){ finalinti=11; classTaskextendsTimerTask{ publicvoidrun(){                        System.out.println("当前时间:"+newjava.util.Date()); System.out.println(i); } }         Timertimer=newTimer(); timer.schedule(newTask(),newjava.util.Date(),5000); } 匿名内部类  方法和作用域中的内部类的更简化形式 publicstaticvoidmain(String[]args){  MyFrameframe=newMyFrame();  JButtonbutton=newJButton();  button.setText("点击试试");  button.addActionListener(newActionListener(){   publicvoidactionPerformed(ActionEvente){System.out.println("被点击了..."); }  });  frame.add(button);  frame.setBounds(200,200,200,200);  frame.setVisible(true); } 主线程  在任何 Java 程序启动时,一个线程立刻运行(即 main 方法对应的线程),该线程通常称为程序的主线程 主线程的特点 它是产生其他子线程的线程 它不一定是最后完成执行的线程,子线程可能在它结束之后还在运行 线程体  Java 的线程是通过 java.lang.Thread 类来实现的 每个线程都是通过某个特定 Thread 对象所对应的方法 run( )来完成其操作的,方法 run( )称为线程体(即线程的可执行代码)  创建线程  方式一:用 Thread 类创建线程 声明为一个 Thread 类的子类,并覆盖 run() 方法   classMyThreadextendsThread{  publicvoidrun(){ /*覆盖该方法*/  } } 当使用继承创建线程,这样启动线程: newMyThread().start(); 创建线程方式一示例 //主类和线程类分开写  publicclassTestThread{//主类用于执行程序,不扩展 Thread 类   publicstaticvoidmain(String[]args){   Threadt=newMyThread();//创建线程对象         t.start();//启动线程 t,它会自动调用 run 方法} } classMyThreadextendsThread{//线程类,必须扩展 Thread 类   publicvoidrun(){//线程对象的可执行代码   for(inti=0;i<5;i++){ System.out.println("SubThread:"+i); } } } 方式二:使用 Runnable 接口创建多线程 声明为一个实现 Runnable 接口的类,并实现 run() 方法 classMyThreadimplementsRunnable{ publicvoidrun(){           /* 实现该方法*/  } } 当使用实现接口创建线程,这样启动线程: newThread(newMyThread()).start();  可看到该接口只有一个 run 方法,当使用 Thread(Runnable target)方法创建线程对象时,需要为该方法传递一个实现了 Runnable 接口的类对象,这样创建的线程将会调用实现了 Runnable 接口的 类对象中的 run 方法作为其运行代码,而不再调用 Thread 类中的 run 方法了。 通过实现 Runnable 接口来创建线程的好处是在实现接口的同时,继承另一个类 创建线程方式二示例 //主类用于执行程序,不扩展 Runnable 接口  publicclassTestThread{     publicstaticvoidmain(String[]args){    MyThreadr=newMyThread();//生成线程类对象 r   Threadt=newThread(r);//创建线程对象,把线程类对象 r 作为参数传递给它     t.start();//启动线程 t,它会自动调用线程类对象 r 的 run 方法   } } classMyThreadimplementsRunnable{//线程类,实现 Runnable 接口  publicvoidrun(){//线程类对象的可执行代码  for(inti=0;i<3;i++){  System.out.prinlnt (“子线程No.”+i);  } } } java.lang.Thread 类  静态方法 currentThread() 返回当前线程实例 sleep(longmillis) 当前线程休眠 yield() 当前线程停顿 (需要 cpu, 释放 cpu 控制权) dumpStack() 打印当前线程的调用栈 常用方法 start()  启动该线程,将导致 run 方法被自动调用 run()  必须覆盖该方法,在方法体中添加线程逻辑代码 isAlive()    用于测试某个线程是否还活着 setPriority(intnewPriority)   设置线程的优先级 join()等待线程结束 两种创建线程方法的比较  使用 Runnable 接口 可以将代码和数据分开,形成清晰的模型 还可以从其他类继承 保持程序风格的一致性 直接继承 Thread 类 不能再从其他类继承 编写简单,可以直接操纵线程 无需使用 Thread.currentThread()----this 线程的四种状态  线程共有下面 4 种状态:1、new(新建):当你用 new 创建一个线程时,该线程尚未运行。 2、runnable(可运行):一旦调用了 start 方法,该线程便是一个可运行的线程。可运行的线程可以尚未执行,也可以正在执行,取决于线程调度的结果。(java 文档并不将正在运行的情况视为一个专 门的状态) 3、blocked(被中断运行):当出现下列操作之一时,线程便进入中断状态: 有人调用该线程的 sleep()方法; 该线程调用了 wait()方法; 该线程调用了一个在输入输出时中断的操作,也就是说,在输入和输出操作完成之前,该操作不会返回到它的调用程序; 该线程试图锁定一个当前被另一个线程锁定了的对象 4、dead(死亡):由于下面两个原因,线程将变成死线程: 由于 run 方法的正常退出而自然死亡; 没有捕获到的异常事件终止了 run 方法的执行,从而导致线程突然死亡 join 方法使用示例  main 线程等待 thread1 执行完毕后继续执行 publicstaticvoidmain(String[]args){         Threadthread1=newThread("Thread1"); thread1.start(); try{ thread1.join(); }catch(InterruptedExceptione){             System.out.println("等待 thread 过程中被打断"); }         for(inti=0;i<10;i++){ System.out.printf("main:%d\n",i); } } 守护(deamon)线程    守护线程是为其它线程提供服务的线程 守护线程一般应该是一个独立的线程 守护线程与其它线程的区别是:如果守护线程是唯一运行着的线程,程序会自动退出 把线程变成一个守护线程:t .setDeamon(true); 守护线程应该永远不去访问固有资源,如文件、数据库,因为它会在任何时候甚至在一个操作的中间发生中断 线程的调度   Java 提供一个线程调度程序来监控程序中启动后进入可运行状态的所有线程 线程调度程序按照线程的优先级决定应调度哪些线程执行 多数线程的调度是抢占式的 时间片方式(timeslicing) 非时间片方式 下面几种情况下,当前线程会放弃 CPU 线程调用了 yield()或 sleep()方法主动放弃 由于当前线程进行 I/O 访问,外存读写,等待用户输入等操作,导致线程阻塞 为等候一个条件变量,线程调用 wait()方法 抢先式系统下,有高优先级的线程参与调度;时间片方式下,当前时间片用完,有同优先级的线程参与调度 线程的优先级  在 java 中,每一个线程都有一个优先级。默认情况下,一个线程将继承其父线程的优先级。 线程的优先级用数字来表示,范围从 1 到 10,一个线程的缺省优先级是 5  Thread.MIN_PRIORITY=1 Thread.MAX_PRIORITY=10 Thread.NORM_PRIORITY=5 使用下述线方法获得或设置线程对象的优先级 int  getPriority(); void  setPriority(intnewPriority);  线程的优先级代表该线程的重要程度,当有多个线程同时处于可执行状态并等待获得 CPU 时间时,线程调度系统根据各个线程的优先级来决定给谁分配 CPU 时间,优先级高的线程有更大的机会获 得 CPU 时间,优先级低的线程也不是没有机会,只是机会要小。  可以调用 Thread 类的方法 getPriority() 和 setPriority()来存取线程的优先级,线程的优先级界于 1(MIN_PRIORITY)和 10(MAX_PRIORITY)之间,缺省是 5(NORM_PRIORITY)。  线程的优先级是从 1 到 10 之间的一个数字,数字越大表明优先级越高。JVM 标准首先调用优先级较高的线程,然后才调用优先级较低的线程。但是,具有相同优先级的线程的处理是随机的。如何 处理这些线程取决于基层的操作系统策略。在某些情况下,优先级相同的线程分时运行;在另一些情况下,线程将一直运行到结束。 监视器(锁)  在 java 中,每个对象都包含了一把锁(也叫作“监视器”),它自动成为对象的一部分(不必为此写任何特殊的代码) 示例:线程 1 进入 withdrawal 方法时,获得监视器(加锁);当线程 1 的方法执行完毕返回时,释放监视器(开锁),线程 2 的 withdrawal 方能进入  同步(synchronized)  为了确保在任何时刻一个共享对象只被一个线程使用,必须使用“同步(synchronized)” 有两种方式实现同步: 使用同步方法  synchronizedvoidmethodA(){  } 使用同步块  synchronized(obj){//obj 是被锁定的对象       //要同步的语句 }  调用任何 synchronized 方法时,对象就会被锁定,不可再调用那个对象的其他任何 synchronized 方法,除非第一个方法完成了自己的工作,并解除锁定。因此,一个特定对象的所有 synchronized 方法都共享着一把锁,而且这把锁能防止多个方法对通用内存同时进行写操作(比如同时有多个线程)。 每个类也有自己的一把锁(作为类的 Class 对象的一部分),所以 synchronizedstatic 方法可在一个类的范围内被相互间锁定起来,防止与 static 数据的接触。 一般情况下,只在方法的层次上使用同步 同步原理   每个对象拥有自己的锁 对于同一个锁,不能有两个线程同时访问 (浴室的例子) 一个房间一次只能进一个人 死锁  当所有的线程都在等待得到某个资源后才能继续运行下去时,整个程序将被挂起,这种情况就叫做死锁 造成死锁的原因如下: 相互排斥: 一个线程或者进程永远占有一共享资源,例如,独占该资源。  循环等待: 进程 A 等待进程 B,而后者又在等待进程 C,进程 C 又在等待进程 A。  部分分配: 资源被部分分配。例如,进程 A 和 B 都需要用访问一个文件,并且    都要用到打印机,进程 A 获得了文件资源,进程 B 获得了打印机资源,但是两个    进程不能获得全部的资源。  缺少优先权: 一个进程访问了某个资源,但是一直不释放该资源,则使该进    程处于阻塞状态。 多线程协作-wait 和 notify  wait 类似于 sleep,当前线程休眠 释放自己占用的锁(不同于 sleep) 可以指定休眠的时间,也可不指定 notify/notifyAll 唤醒正在 wait 状态等待当前锁的线程 notifyAll 唤醒所有 wait 状态的线程 notify 只唤醒一个 wait 状态的线程  这三个方法是 Object 类中的方法,每个对象都有自己的锁,通过 synchronized 块占用一个对象的锁,占用后调用 wait 方法可暂时释放这把锁,但当前仍在同步块中,释放锁后,线程处于 wait 状态, 等待其他线程将锁还给它。 Lock&Condition 实现线程同步通信  Lock 比传统线程模型中的 synchronized 方式更加面向对象 Condition 的功能类似在传统线程技术中的 Object wait 和 Object notify 功能 一个锁内部可以有多个 Condition,即有多路等待和通知,参看 jdk5.0 提供的阻塞队列应用案例 线程池  Java5 中的线程并发库 java.util.concurrent 包及子包的 API 文档 线程池的概念与 Executors 类的应用 创建固定大小的线程池 创建缓存线程池 创建单一线程池 关闭线程池 shutdown 与 shutdownNow 的比较计算机网络基本知识  协议(Protocol): 两台计算机通讯时对传送信息内容的理解、信息表示形式以及各种情况下应答信号都必须遵守的共同的约定 体系结构(Architecture): 在一个计算机网络中将协议分成了若干层次,将协议按如何分层以及各层中具体采用协议的集合 OSI 和 TCP/IP 的体系结构:  计算机网络基本知识  TCP/IP 是指传输控制协议(Transmission Control Protocol)和网间协议(Internet Protocol) TCP/IP 网络参考模型包括四个层次:应用层、传输层、网际层、网络接口层 常用应用层协议:ftp、http、smtp、pop3、telnet 网络工作模式 客户机/服务器模式:(client/server) 浏览器/服务器模式:(browser/server) 对等式网络: (Peer-to-Peer)  对等网(PeertoPeer) 在对等网络中,所以计算机地位平台,没有从属关系,也没有专用的服务器和客户机。网络中的资源是分散在每台计算机上的,每一台计算机都有可能成为服务器也以可能成为客 户机。网络的安全验证在本地进行,一般对等网络中的用户小于或等于 10 台,如图 1-10 所示。对等网能够提供灵活的共享模式,组网简单、方便、但难于管理,安全性能较差。它可满足一般数据传 输的需要,所以一些小型单位在计算机数量较少时可选用“对等网”结构。 客户机/服务器模式(Client/Server) 为了使网络通信更方便、更稳定、更安全,我们引入基于服务器的网络(Client/Server,简称 C/S)如图 1-11 所示。这种类型中的网络中有一台或几台较大计 算机集中进行共享数据库的管理和存取,称为服务器,而将其他的应用处理工作分散到网络中其他计算机上去做,构成公布式的处理系统。服务器控制管理数据的能力已由文件管理方式上升为数据库 管理方式,因此,C/S 中的服务器也称为数据库服务器,注重于数据定义及存取安全备份及还原,并发控制及事务管理,执行行诸如选择检索和索引排序等数据库管理功能。它有足够的能力做到把通 过其处理后用户所需的那一部分数据而不是整个文件通过网络传送到客户机去,减轻了网络的传输负荷。C/S 结构是数据库技术的发展和普遍应用与局域网技术发展相结合的结果。  B/S(浏览器/服务器模式) 模式又称 B/S 结构。它是随着 Internet 技术的兴起,对 C/S 模式应用的扩展。在这种结构下,用户工作界面是通过 IE 浏览器来实现的。B/S 模式最大的好处是运行维护比 较简便,能实现不同的人员,从不同的地点,以不同的接入方式(比如 LAN,WAN,Internet/Intranet 等)访问和操作共同的数据;最大的缺点是对企业外网环境依赖性太强,由于各种原因引起企业 外网中断都会造成系统瘫痪。 /s 是 brower/server 就是用浏览器(如 ie)为应用程序客户端操作服务器。这样用浏览器来操作简单易用,但是对输入没有很好的验证。逻辑实现不多。本地只是用于获 取数据然后大部分验证需要提交服务器来完成。  TCP 三次握手  网络交互模型  什么是 Socket?  Socket 标识运行在网络上的两个程序之间的双向通信链接 IP Port   Socket:Java 语言中的套接字(Socket)就是网络通信协议的一种应用,通过 TCP/IP 协议进行通信 Socket 在哪里?  TCP/IP+BIO Server  publicstaticvoidmain(String[]args)throwsException{   intport=9527;   ServerSocketss=newServerSocket(port);   System.out.println("Serverlistenonport:"+port);   Socketsocket=ss.accept();   BufferedReaderin=newBufferedReader(newInputStreamReader(socket .getInputStream()));   PrintWriterout=newPrintWriter(socket.getOutputStream(),true); while(true){ Stringline=in.readLine(); if(line==null){ Thread.sleep(100); continue; } if("quit".equalsIgnoreCase(line.trim())){ in.close(); out.close(); ss.close(); System.out.println("Serverhasbeenshutdown!"); System.exit(0); }else{ System.out.println("Messagefromclient:"+line); out.println("Serverresponse:"+line); Thread.sleep(100); } } } TCP/IP+BIO Client  publicstaticvoidmain(String[]args)throwsException{   Stringhost="127.0.0.1";   intport=9527;   Socketsocket=newSocket(host,port);   BufferedReaderin=newBufferedReader(newInputStreamReader(socket .getInputStream()));   PrintWriterout=newPrintWriter(socket.getOutputStream(),true);   BufferedReadersystemIn=newBufferedReader(newInputStreamReader( System.in));   booleanflag=true;   while(flag){ Stringcommand=systemIn.readLine(); if(command==null||"quit".equalsIgnoreCase(command.trim())){ flag=false; System.out.println("Clientquit!"); out.println("quit"); out.close(); in.close(); socket.close(); continue; } out.println(command); Stringresponse=in.readLine(); System.out.println(response); } }XML 语言  于 洋 XML语言 ........................................................................................................................ 1 什么是XML(Extensible Markup Language)? ...............................................................................................................2 XML企业端应用 ...............................................................................................................................................................2 XML语法..........................................................................................................................................................................3 XML语法-文档声明 ........................................................................................................................................................3 元素(1) (element)...........................................................................................................................................................3 元素(2).............................................................................................................................................................................4 元素(3)——命名规范 .......................................................................................................................................................4 属性..................................................................................................................................................................................4 注释..................................................................................................................................................................................4 CDATA区 .........................................................................................................................................................................5 转义字符...........................................................................................................................................................................5 处理指令...........................................................................................................................................................................5 XML语法规则总结............................................................................................................................................................5 XML约束概述...................................................................................................................................................................6 XML约束  DTD............................................................................................................... 6 DTD约束快束入门 ............................................................................................................................................................6 将DTD与XML文档关联三种方式 ......................................................................................................................................6 引用DTD约束 ...................................................................................................................................................................7 DTD约束语法细节 ............................................................................................................................................................7 属性(ATTLIST)定义......................................................................................................................................................8 实体(ENTITY)定义.......................................................................................................................................................9 实体定义 引用实体 .........................................................................................................................................................9 XML约束  Schema......................................................................................................... 9 XML Schema............................................................................................................................................................... 10 Schema一些概念 .......................................................................................................................................................... 10 XMLSchema文档基本结构 ........................................................................................................................................... 10 Schema入门案例  1 ...................................................................................................................................................... 11 Schema入门案例  2 ...................................................................................................................................................... 11 在XML Schema文档中声明名称空间 ............................................................................................................................ 12 名称空间的概念 ............................................................................................................................................................. 12 使用名称空间引入Schema ............................................................................................................................................ 12 基本格式: .................................................................................................................................................................... 13 使用名称空间引入多个XML Schema文档 ..................................................................................................................... 13 XML Schema基础概念 ................................................................................................................................................. 14  XML 文档片段        EverydayItalian   GiadaDeLaurentiis   2005    30.00          LearningXML    ErikT.Ray    2003    39.95       什么是 XML(Extensible Markup Language)?  XML 指可扩展标记语言 XML 是一种标记语言,很类似 HTML XML 的设计宗旨是存储、传输数据,而非显示数据 XML 标签没有被预定义 使用约束的 XML 文档设计具有自我描述性。 XML 是 W3C 的推荐标准 XML 企业端应用  存储和传输复杂的关系模型数据 在软件系统中,作为配置文件使用 为提高系统的灵活性,它所启动的模块通常由其配置文件决定 例如一个软件在启动时,它需要启动A、B两个模块,而 A、B这两个模块在启动时,又分别需要 A1、A2 和 B1、B2 模块的支持,为了准确描述这种关系,此时使用XM L文件最为合适不过。 XML 文档的树形结构  XML 语法  一个 XML 文件分为如下几部分内容: 文档声明  元素 属性 注释 CDATA 区 、特殊字符  处理指令(processinginstruction)  XML 语法-文档声明  在编写 XML 文档时,需要先使用文档声明,声明 XML 文档的类型。 最简单的声明语法:   用 encoding 属性说明文档的字符编码:     用 standalone 属性说明文档是否独立:   常见错误,见 PPT 下面的备注区 常见错误: 1. 2. 3.编码错误 元素(1) (element)  XML 元素指 XML 文件中出现的标签,一个标签分为开始标签和结束标签,一个标签有如下几种书写形式,例如: 包含标签体:www.itcast.cn 不含标签体的:, 简写为: 一个标签中也可以嵌套若干子标签。但所有标签必须合理的嵌套,绝对不允许交叉嵌套 ,例如:   welcometowww.it315.org 格式良好的 XML 文档必须有且仅有一个根标签,其它标签都是这个根标签的子孙标签。 元素(2)  对于 XML 标签中出现的所有空格和换行,XML 解析程序都会当作标签内容进行处理。例如:下面两段内容的意义是不一样的。 第一段: <网址>www.itcast.cn  第二段:  <网址>  www.itcast.cn  由于在 XML 中,空格和换行都作为原始内容被处理,所以,在编写 XML 文件时,使用换行和缩进等方式来让原文件中的内容清晰可读的“良好”书写习惯可能要被迫改 变。 元素(3)——命名规范  一个 XML 元素可以包含字母、数字以及其它一些可见字符,但必须遵守下面的一些规范: 区分大小写,例如,

      是两个不同的标记。 不能以数字开头 不建议"_"(下划线)开头。 不建议以 xml(或 XML、或 Xml 等)开头。 不能包含空格。 名称中间不能包含冒号(:)。 ---Schema 约束冲突 属性  一个标签可以有多个属性,每个属性都有它自己的名称和取值,例如:    属性值一定要用双引号(")或单引号(')引起来 定义属性必须遵循与标签相同的命名规范 多学一招:在 XML 技术中,标签属性所代表的信息,也可以被改成用子元素的形式来描述,例如:      text    注释  Xml 文件中的注释采用:“” 格式。 注意:XML 声明之前不能有注释 注释不能嵌套,例如:    ……  -->   CDATA 区  在编写 XML 文件时,有些内容可能不想让解析引擎解析执行,而是当作原始内容处理。 遇到此种情况,可以把这些内容放在 CDATA 区里,对于 CDATA 区域内的内容,XML 解析程序不会处理,而是直接原封不动的输出。 语法:  
         ]]> 转义字符  对于一些单个字符,若想显示其原始样式,也可以使用转义的形式予以处理。  处理指令  处理指令,简称 PI (processing instruction)。处理指令用来指挥解析引擎如何解析 XML 文档内容。 例如,在 XML 文档中可以使用 xml-stylesheet 指令,通知 XML 解析引擎,应用 css 文件显示 xml 文档内容。  处理指令必须以“”作为结尾,XML 声明语句就是最常见的一种处理指令。 标签名为中文时,css 不起作用 XML 语法规则总结  所有 XML 元素都须有关闭标签 XML 标签对大小写敏感 XML 必须正确地嵌套顺序 XML 文档必须有根元素(只有一个) XML 的属性值须加引号 特殊字符必须转义 --- CDATA XML 中的空格会被保留 XML 约束概述  什么是 XML 约束 在 XML 技术里,可以编写一个文档来约束一个 XML 文档的书写规范,这称之为 XML 约束。 为什么需要 XML 约束 常用的约束技术 XMLDTD  XMLSchema XML 约束  DTD  于 洋 DTD 约束快束入门  DTD(Document Type Definition),全称为文档类型定义。  DTD 文件应使用 UTF-8 或 Unicode 将 DTD 与 XML 文档关联三种方式  DTD 约束即可以作为一个单独的文件编写,也可以在 XML 文件内编写 使用内部 DTD 使用外部 DTD 使用公共 DTD 在 xml 文件内编写 DTD          ]> <书架>  <书>   <书名>Java 就业培训教程   <作者>张孝祥   <售价>39.00 元   ...  引用 DTD 约束  XML 文件使用 DOCTYPE 声明语句来指明它所遵循的 DTD 文件,DOCTYPE 声明语句有两种形式: 当引用的文件在本地时(外部 DTD),采用如下方式:     例如: 。在 xml 文件中手写一下。  当引用的文件是一个公共的文件时(公共 DTD)采用如下方式:        例如: DTD 约束语法细节  元素(ELEMENT)定义 属性(ATTLIST)定义 实体(ENTITY)定义 元素(ELEMENT)定义  元素内容的类型  元素定义示例  属性(ATTLIST)定义   属性声明举例  属性类型及其含义  约束的四种形式  实体(ENTITY)定义  实体用于为一段内容创建一个别名,以后在 XML 文档中就可以使用别名引用这段内容了。 在 DTD 定义中,一条语句用于定义一个实体。 实体定义 引用实体      引用实体主要在 XML 文档中被应用 语法格式: :直接转变成实体内容 引用方式: &实体名称; 举例:      ……   ©right;  另一种方式::用一个文档所实体 XML 约束  Schema  于 洋XML Schema   XML Schema 是用一套预先规定的 XML 元素和属性创建的,这些元素和属性定义了 XML 文档的结构和内容模式。 XMLSchema 规定 XML 文档实例的结构和每个元素/属性的数据类型 Schema 相对于 DTD 的明显好处是,XML Schema 文档本身也是 XML 文档,而不是像 DTD 一样使用自成一体的语法 Schema 和 DTD 区别 XML 从 SGML 中继承了 DTD,并用它来定义内容的模型,验证和组织元素。同时,它也有很多局限: DTD 不遵守 XML 语法; DTD 不可扩展; DTD 不支持命名空间的应用; DTD 没有提供强大的数据类型支持,只能表示很简单的数据类型。 Schema 完全克服了这些弱点,使得基于 Web 的应用系统交换 XML 数据更为容易。下面是它所展现的一些新特性: Schema 完全基于 XML 语法,不需要再学习特殊的语法; Schema 能用处理 XML 文档的工具处理,而不需要特殊的工具; Schema 大大扩充了数据类型,支持 booleans、numbers、datesandtimes、URIs、integers、decimalnumbers 和 realnumbers 等; Schema 支持原型,也就是元素的继承。如:我们定义了一个“联系人”数据类型,然后可以根据它产生“朋友联系人”和“客户联系”两种数据类型; Schema 支持属性组。我们一般声明一些公共属性,然后可以应用于所有的元素,属性组允许把元素、属性关系放于外部定义、组合; 开放性。原来的 DTD 只能有一个 DTD 应用于一个 XML 文档,现在可以有多个 Schema 运用于一个 XML 文档。 Schema 一些概念  XML Schema 文件自身就是一个 XML 文件,但它的扩展名通常为.xsd 一个 XML Schema 文档通常称之为模式文档(约束文档),遵循这个文档书写的 xml 文件称之为实例文档 和 XML 文件一样,一个 XML Schema 文档也必须有一个根结点,但这个根结点的名称为 Schema 编写了一个 XML Schema 约束文档后,通常需要把这个文件中声明的元素绑定到一个URI地址上,在 XML Schema 技术中有一个专业术语来描述这个过程, 即把 XMLSchema 文档声明的元素绑定到一个名称空间上,以后 XML 文件就可以通过这个 URI(即名称空间)来告诉解析引擎,xml 文档中编写的元素来自哪里,被谁约 束 XMLSchema 文档基本结构  在 W3C XML schema 规范中规定:所有的 Schema 文档都使用作为其根元素  元素可以包含一些属性。一个 XML schema 声明看起来经常以如下的形式出现  Schema 入门案例  1  book.xsd 文件                        Schema 入门案例  2  book.xsd 文件        JavaScript 网页开发   张孝祥   28.00 元    在 XML Schema 文档中声明名称空间     targetNamespace 元素用于指定 schema 文档中声明的元素属于哪个名称空间。 elementFormDefault 元素用于指定局部元素是否受到该 schema 指定 targetNamespace 所指定的名称空间限定 attributeFormDefault 元素用于指定局部属性是否受到该 schema 指定 targetNamespace 所指定的名称空间限定 名称空间的概念    在 XML Schema 中,每个约束模式文档都可以被赋以一个唯一的名称空间,名称空间用一个唯一的 URI(Uniform Resource Identifier,统一资源标识符)表示。 在 Xml 文件 中书写标签时,可以通过名称空间声明(xmlns),来声明当前编写的标签来自哪个 Schema 约束文档。如:     ……      此处使用 itcast 来指向声明的名称,以便于后面对名称空间的引用。 注意:名称空间的名字语法容易让人混淆,尽管以 http:// 开始,那个 URL 并不指向一个包含模式定义的文件。事实上,这个 URL:http://www.itcast.cn 根本没有指向任何文件,只是一个分配的 名字。 使用名称空间引入 Schema    为了在一个 XML 文档中声明它所遵循的 Schema 文件的具体位置,通常需要在 Xml 文档中的根结点中使用 schemaLocation 属性来指定,例如:   schemaLocation 此属性有两个值。第一个值是需要使用的命名空间。 第二个值是供命名空间使用的 XMLschema 的位置,两者之间用空格分隔。 注意,在使用 schemaLocation 属性时,也需要指定该属性来自哪里。 使用默认名称空间 基本格式:   xmlns="URI"  举例:  <书架 xmlns="http://www.itcast.cn"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:schemaLocation=“http://www.itcast.cnbook.xsd"> <书>   <书名>JavaScript 网页开发   <作者>张孝祥   <售价>28.00 元   <书架> 使用名称空间引入多个 XML Schema 文档    文件清单:xmlbook.xml   <书架 xmlns="http://www.it315.org/xmlbook/schema"   xmlns:demo="http://www.it315.org/demo/schema"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://www.it315.org/xmlbook/schema  http://www.it315.org/xml/book.xsd    http://www.it315.org/demo/schemahttp://www.it315.org/demo.xsd">  <书>   <书名>JavaScript 网页开发   <作者>张孝祥   <售价 demo:币种=”人民币”>28.00 元  XML Schema 基础概念   Schema 元素:简单类型和复杂类型 XML Schema 规范中将元素分为两种类型 简单类型元素:简单类型元素只能包含字符内容。这些字符可以被约束为特殊的预定义类型或派生类型。 例如,可以指定一个简单元素的内容必须是日期、整数、字符串或者仅仅是一个字符或者一系列字符。type 复杂类型元素:复杂类型元素是包含子元素内容或者属性的元素  XML 解析技术  于洋 XML解析技术 ................................................................................................................. 1 XML解析技术概述............................................................................................................................................................1 DOM和SAX区别..............................................................................................................................................................1 DOM和SAX的选择 ..........................................................................................................................................................2 JAXP(Java API for XML Processing ) ..........................................................................................................................2 DOM解析模型 .................................................................................................................................................................2 使用DOM方式解析XML...................................................................................................................................................3 节点列表类NodeList........................................................................................................................................................3 节点对象  Node ...............................................................................................................................................................3 节点对象  Element Attr Text ..........................................................................................................................................4 节点对象的查询总结 .........................................................................................................................................................4 节点对象的增加、修改、删除总结 ....................................................................................................................................4 更新XML文档...................................................................................................................................................................4 DOM  编程强化练习.........................................................................................................................................................5 SAX解析原理 ...................................................................................................................................................................5 SAX DocumentHandler示例 .........................................................................................................................................5 使用SAX方式解析XML.....................................................................................................................................................6 使用XML Pull  解析XML .................................................................................................................................................7 使用Pull解析器生成XML文件...........................................................................................................................................8 XML解析案例练习............................................................................................................................................................9  C:create R:read U:update D:delete XML 解析技术概述  XML 解析方式分为两种:dom 和 sax dom:(DocumentObjectModel, 即文档对象模型) 是 W3C 组织推荐的解析 XML 的一种方式。 sax: (SimpleAPIforXML) 不是官方标准,但它是 XML 社区事实上的标准,几乎所有的 XML 解析器都支持它。  XML 解析开发包 Jaxp(sun)、xmlpull 、dom4j DOM 和 SAX 区别  DOM 支持回写 会将整个 XML 载入内存,以树形结构方式存储 一个 300KB 的 XML 文档可以导致 RAM 内存或者虚拟内存中的 3,000,000KB 的 DOM 树型结构  XML 比较复杂的时候,或者当你需要随机处理文档中数据的时候不建议使用SAX (内存中没有 xml 全部数据) 相比 DOM 是一种更为轻量级的方案 采用串行方法读取 --- 逐行读取 编程较为复杂 无法在读取过程中修改 XML 数据 DOM 和 SAX 的选择  选择 DOM 还是 SAX,这取决于几个因素 应用程序的目的:如果必须对数据进行更改,并且作为 XML 将它输出,则在大多数情况下,使用 DOM 数据的数量:对于大文件,SAX 是更好的选择 将如何使用数据:如果实际上只使用一小部分数据,则使用 SAX 将数据抽取到应用程序中,这种方法更好些 需要速度:通常,SAX 实现比 DOM 实现快 JAXP(Java API for XML Processing )  DOM 和 SAX 只是 XML 解析方式,没有 API JAXP 是 Sun 提供的一套 XML 解析 API JAXP 很好的支持 DOM 和 SAX 解析方式 JAXP 开发包是 JavaSE 的一部分,它由 javax.xml、org.w3c.dom 、org.xml.sax 包及其子包组成 在 javax.xml.parsers 包中,定义了几个工厂类,程序员调用这些工厂类,可以得到对 xml 文档进行解析的 DOM 或 SAX 的解析器对象 DOM 解析模型  DOM 是以层次结构组织的节点或信息片断的集合,是 XML 数据的一种树型表示 文档中所有的元素、属性、文本都会被解析成 node 节点 节点之间关系 Parent  Children  sibling(兄弟) DOM 树形结构示例     HarryPotter  JK.Rowling  2005  29.99      使用 DOM 方式解析 XML  解析器工厂类 DocumentBuilderFactory DocumentBuilderFactorydbf=DocumentBuilderFactory.newInstance(); 解析器类 DocumentBuilder DocumentBuilderdb=dbf.newDocumentBuilder(); 解析生成 Document 对象 Documentdoc=db.parse("message.xml"); 通过 Document 对象查询节点 document.getElementsByTagName  返回 NodeList 对象 节点列表类 NodeList  节点列表类 NodeList 就是代表了一个包含一个或者多个 Node 的列表 可以简单的把它看成一个 Node 的数组 常用方法 getLength():返回列表的长度。  ArrayListsize() item(index):返回指定位置的 Node 对象 ArrayListget(index) 节点对象  Node  Node 对象提供了一系列常量来代表结点的类型 查看 org.w3c.dom.Node 接口源码 当开发人员获得某个 Node 类型后,就可以把 Node 节点转换成相应的节点对象 Element 、Attr、Text 节点的操作 getNodeName():返回节点的名称 getNodeType():返回节点的类型 getNodeValue():返回节点的值 节点对象  Element Attr Text  元素节点 Element 获得元素节点中的属性值 element.getAttribute(属性名称)  获得元素节点内部文本内容 element.getTextContent() element.getFirstChild().getNodeValue() 节点对象的查询总结  全局查找元素节点 document.getElementsByTagName 相对节点位置查找节点 getChildNodes():返回这个节点的所有子节点列表 getFirstChild():返回这个节点的第一个子节点 getParentNode():返回这个节点的父节点对象 getNextSibling():返回该节点下一个兄弟节点, getPreviousSibling()方法返回其前一个兄弟节点 节点对象的增加、修改、删除总结  节点对象的增加 document.createXXX() 创建节点 element.appendChild(org.w3c.dom.Node) 添加节点 节点对象的修改 修改元素的属性值 element.setAttribute(name,value); 修改元素内文本内容 element.setTextContent(value); 节点对象的删除 删除节点.getParentNode().removeChild(删除节点) 更新 XML 文档  javax.xml.transform 包中的 Transformer 类用于把代表 XML 文件的 Document 对象转换为某种格式后进行输出, 例如把 xml 文件应用样式表后转成一个 html 文档。利用这个对象,当然也可以把 Document 对象又重新写入到一个 XML 文件中。Transformer 类通过 transform 方法完成转换操作,该方法接收一个源和一个目的地。我们可以通过: javax.xml.transform.dom.DOMSource 类来关联要转换的 document 对象,  用 javax.xml.transform.stream.StreamResult 对象来表示数据的目的地。 Transformer 对象通过 TransformerFactory 获得。 DOM  编程强化练习  XML 的 CURD 操作 创建(Create) 更新(Update) 读取(Read) 删除(Delete)操作  SAX 解析原理  SAX 是事件驱动的 XML 处理方法 它是基于事件驱动的 startElement() 回调在每次 SAX 解析器遇到元素的起始标记时被调用 characters() 回调为字符数据所调用 endElement() 为元素的结束标记所调用 DefaultHandler 类(在 org.xml.sax.helpers 软件包中)来实现所有这些回调,并提供所有回调方法默认的空实现 SAX 的事件驱动模型  SAX DocumentHandler 示例  SAX 解析器采用了基于事件的模型,它在解析 XML 文档的时候可以触发一系列的事件 发生相应事件时,将调用一个回调方法 Startdocument Startelement(config) Characters(whitespace) Startelement(server) Characters(UNIX)Endelement(server) Characters(whitespace) Endelement(config) Enddocument     UNIX  使用 SAX 方式解析 XML  使用 SAXParserFactory 创建 SAX 解析工厂 SAXParserFactoryspf=SAXParserFactory.newInstance(); 通过 SAX 解析工厂得到解析器对象 SAXParsersp=spf.newSAXParser(); 通过解析器对象得到一个 XML 的读取器 XMLReaderxmlReader=sp.getXMLReader(); 设置读取器的事件处理器 xmlReader.setContentHandler(newXMLContentHandler()); 解析 xml 文件 xmlReader.parse("book.xml"); SAX 代码例子 publicclassXMLContentHandlerextendsDefaultHandler{ //当前元素中的数据 privateStringcurrentData; //取得元素数据 publicvoidcharacters(char[]ch,intstart,intlength) throwsSAXException{       currentData=newString(ch,start,length); }  //在解析整个文档结束时调用 publicvoidendDocument()throwsSAXException{         System.out.println("结束文档"); } //在解析元素结束时调用publicvoidendElement(Stringuri,StringlocalName,Stringname) throwsSAXException{       System.out.println("节点数据 *************************"+this.currentData);       System.out.println("结束元素 ************"+name); }  //在解析整个文档开始时调用 publicvoidstartDocument()throwsSAXException{      System.out.println("开始文档"); }  //在解析元素开始时调用 publicvoidstartElement(Stringuri,StringlocalName,Stringname, Attributesattributes)throwsSAXException{       System.out.println("开始元素 ************"+name); } } 使用 XML Pull  解析 XML   Android 系统内置的 Pull 解析器也可以进行 XML 文件的解析 Pull 解析器是一个开源的 Java 项目,既可以用于 Android,也可以用于 JavaEE 官方站点:http://www.xmlpull.org/ 下载实现 xpp3 Pull 解析器运行方式与 SAX 解析器相似 基于事件驱动的 参考官方文档 http://www.xmlpull.org/v1/download/unpacked/doc/quick_intro.html Xpp3XmlPullParserjavadoc关键代码 XmlPullParserFactoryfactory=   XmlPullParserFactory.newInstance(); factory.setNamespaceAware(true);  XmlPullParserxpp=factory.newPullParser();  xpp.setInput(inStream,"UTF-8");  inteventType=xpp.getEventType();  --- 当前节点事件类型 eventType=xpp.next();--- 下一个节点 xpp.getAttributeValue--- 获得标签属性值 xpp.nextText--- 获得标签后面文本内容  使用 Pull 解析器生成 XML 文件   有些时候,我们需要生成一个XML 文件,生成XML 文件的方法有很多,如:可以只使用一个StringBuilder 组拼 XML 内容,然后把内容写入到文件中;或者使用DOMAPI 生成 XML 文件,或者也可以使用 pull 解析器生成 XML 文件,这里推荐大家使用 Pull 解析器。 使用 Pull 解析器生成一个 xml 文件,代码在本页下方备注 publicstaticStringwriteXML(Listpersons,Writerwriter){ XmlPullParserFactoryfactory=XmlPullParserFactory.newInstance(); XmlSerializerserializer=factory.newSerializer(); try{ serializer.setOutput(writer); serializer.startDocument("UTF-8",true); //第一个参数为命名空间,如果不使用命名空间,可以设置为 null serializer.startTag("","persons"); for(Personperson:persons){ serializer.startTag("","person"); serializer.attribute("","id",person.getId().toString()); serializer.startTag("","name"); serializer.text(person.getName()); serializer.endTag("","name"); serializer.startTag("","age"); serializer.text(person.getAge().toString()); serializer.endTag("","age"); serializer.endTag("","person"); } serializer.endTag("","persons"); serializer.endDocument(); returnwriter.toString(); }catch(Exceptione){ e.printStackTrace(); } returnnull;} 使用代码如下(生成 XML 文件): FilexmlFile=newFile("myitcast.xml"); FileOutputStreamoutStream=newFileOutputStream(xmlFile); OutputStreamWriteroutStreamWriter=newOutputStreamWriter(outStream,"UTF-8"); BufferedWriterwriter=newBufferedWriter(outStreamWriter); writeXML(persons,writer); writer.flush(); writer.close(); 如果只想得到生成的 xml 字符串内容,可以使用 StringWriter: StringWriterwriter=newStringWriter(); writeXML(persons,writer); Stringcontent=writer.toString(); XML 解析案例练习   商品信息管理系统 提供商品的 CURD 功能  商品信息 编号(id)、名称(name)、售价(price)、数量(number)、描述(description)HTTP 协议  于洋 HTTP协议 ...................................................................................................................... 1 Tip1:什么是HTTP协议 ..................................................................................................................................................1 Tip2:HTTP协议简介......................................................................................................................................................1 Tip3:HTTP1.0 和HTTP1.1 的区别 ................................................................................................................................1 Tip4:HTTP请求.............................................................................................................................................................1 Tip5:HTTP请求的细节——请求行.................................................................................................................................2 Tip6:HTTP请求的细节——消息头.................................................................................................................................2 Tip7:HTTP响应.............................................................................................................................................................3 Tip8:HTTP响应的细节——状态行.................................................................................................................................3 Tip9:HTTP响应细节——常用响应头 .............................................................................................................................4 Tip9:HTTP实用头字段 ..................................................................................................................................................4 Tip11:作业 ....................................................................................................................................................................5  Tip1:什么是 HTTP 协议  客户端连上 web 服务器后,若想获得 web 服务器中的某个 web 资源,需遵守一定的通讯格式,HTTP 协议用于定义客户端与 web 服务器通迅的格式 基于 TCP 连接的传输协议 默认端口是 80 基于请求-响应模式的协议 通过 telnet 命令 快速了解 HTTP 协议 安装 IE 浏览器插件 HttpWatch,查看 IE 浏览器通过 HTTP 协议获取某个页面。 Tip2:HTTP 协议简介  HTTP 是 hypertexttransferprotocol(超文本传输协议)的简写,它是 TCP/IP 协议的一个应用层协议,用于定义 WEB 浏览器与 WEB 服务器之间交换数据的过程。  HTTP 协议是学习 JavaWEB 开发的基石,不深入了解 HTTP 协议,就不能说掌握了 WEB 开发,更无法管理和维护一些复杂的 WEB 站点。 HTTP 协议的版本:HTTP/1.0、HTTP/1.1 Tip3:HTTP1.0 和 HTTP1.1 的区别  在 HTTP1.0 协议中,客户端与 web 服务器建立连接后,只能获得一个 web 资源。 HTTP1.1 协议,允许客户端与 web 服务器建立连接后,在一个连接上获取多个 web 资源。 一个好多同学搞不清楚的问题: 一个 web 页面中,使用 img 标签引用了三幅图片,当客户端访问服务器中的这个 web 页面时,客户端总共会访问几次服务器,即向服务器发送了几次 HTTP 请求。 Tip4:HTTP 请求  客户端连上服务器后,向服务器请求某个 web 资源,称之为客户端向服务器发送了一个 HTTP 请求。一个完整的 HTTP 请求包括如下内容:  一个请求行、若干消息头、以及实体内容,如下所示 :GET/books/java.htmlHTTP/1.1 Accept:*/* Accept-Language:en-us Connection:Keep-Alive Host:localhost Referer:http://localhost/links.asp User-Agent:Mozilla/4.0  Accept-Encoding:gzip,deflate   Web 服务器通过客户端发送过来的这些请求信息,就可以确定向请求者回送什么资源,以及根据客户端的环境信息采用什么方式进行回送等。 Tip5:HTTP 请求的细节——请求行  请求行中的 GET 称之为请求方式,请求方式有:POST、GET、HEAD、OPTIONS、DELETE、TRACE、PUT 常用的有: GET、 POST 用户如没有设置,默认情况下浏览器向服务器发送的都是 get 请求,例如在浏览器直接输地址访问,点超链接访问等都是 get,用户如想把请求方式改为 post,可通过更改 表单的提交方式实现。 不管 POST 或 GET,都用于向服务器请求某个 WEB 资源,这两种方式的区别主要表现在数据传递上: 如请求方式为 GET 方式,则可以在请求的 URL 地址后以?的形式带上交给服务器的数据,多个数据之间以&进行分隔,例如: GET/mail/1.html?name=abc&password=xyzHTTP/1.1 GET 方式的特点:在 URL 地址后附带的参数是有限制的,其数据容量通常不能超过 1K。 如请求方式为 POST 方式,则可以在请求的实体内容中向服务器发送数据,Post 方式的特点:传送的数据量无限制。 Tip6:HTTP 请求的细节——消息头  用于 HTTP 请求中的常用头 Accept:text/html,image/*     Accept-Charset:ISO-8859-1 Accept-Encoding:gzip Accept-Language:zh-cn  Host:www.itcast.com:80 If-Modified-Since:Tue,11Jul200018:23:51GMT Referer:http://www.itcast.com/index.jsp User-Agent:Mozilla/4.0(compatible;MSIE5.5;WindowsNT5.0) Connection:close/Keep-Alive    Date:Tue,11Jul200018:23:51GMTTip7:HTTP 响应  一个 HTTP 响应代表服务器向客户端回送的数据,它包括:一个状态行、若干消息头、以及实体内容 。     HTTP/1.1200OK   Server:Microsoft-IIS/5.0 Date:Thu,13Jul200005:46:53GMT Content-Length:2291 Content-Type:text/html Cache-control:private    ……  在一个 HTTP 响应中,WEB 服务器通过响应头向 web 客户端描述客户端的请求成功与否,以及它所发送的数据类型等一些信息,客户端通过这些信息,进而可以知道如何对数据进行  Tip8:HTTP 响应的细节——状态行  状态行  格式: HTTP 版本号 状态码 原因叙述  举例:HTTP/1.1200OK 状态码用于表示服务器对请求的处理结果,它是一个三位的十进制数。响应状态码分为 5 类,如下所示: 状态码 含义 100~199 表示成功接收请求,要求客户端继续提交下一次请求才能完成整个 处理过程 200~299 表示成功接收请求并已完成整个处理过程,常用 200 300~399 为完成请求,客户需进一步细化请求。例如,请求的资源已经移动 一个新地址,常用 302、307 和 304 400~499 客户端的请求有错误,常用 404 500~599 服务器端出现错误,常用 500 Tip9:HTTP 响应细节——常用响应头   HTTP 请求中的常用响应头 Location:http://www.it315.org/index.jsp  Server:apachetomcat Content-Encoding:gzip  Content-Length:80  Content-Language:zh-cn  Content-Type:text/html;charset=GB2312  Last-Modified:Tue,11Jul200018:23:51GMT Refresh:1;url=http://www.it315.org Content-Disposition:attachment;filename=aaa.zip Expires:-1 Cache-Control:no-cache   Pragma:no-cache Connection:close/Keep-Alive    Date:Tue,11Jul200018:23:51GMT Tip10:HTTP 实用头字段  HTTP 请求头字段 Range 头指示服务器只传输一部分 Web 资源。这个头可以用来实现断点续传功能。Range 字段可以通过三种格式设置要传输的字节范围: Range: bytes=1000-2000 传输范围从 1000 到 2000 字节。 Range: bytes=1000-          传输 Web 资源中第 1000 个字节以后的所有内容。 Rangebytes=1000         传输最后 1000 个字节。 HTTP 响应消息头字段 Accept-Ranges:这个字段说明 Web 服务器是否支持 Range 支持,则返回 Accept-Ranges: bytes,如果不支持,则返回 Accept-Ranges: none. Content-Range:指定了返回的 Web 资源的字节范围。这个字段值的格式是:例子: Content-Range:1000-3000/5000Tip11:作业  阅读 HTTP 协议详解.txt 整理一篇关于 HTTP 协议的笔记,要求: 描述清楚 HTTP 请求、响应的格式 请求头和响应头中各个头字段的含义 如果浏览器传递给 WEB 服务器的参数内容超过 1K,应该使用那种方式发送请求消息?  请描述 200、302、304、404 和 500 等响应状态码所表示的意义。  请列举三种禁止浏览器缓存的头字段,并写出相应的设置值。JavaWEB 服务器配置使用  于洋 JavaWEB服务器配置使用............................................................................................... 1 WEB开发的相关知识 ........................................................................................................................................................1 常见WEB服务器 ...............................................................................................................................................................2 常见WEB服务器 ...............................................................................................................................................................2 常见WEB服务器  apache.................................................................................................................................................2 Tomcat服务器 .................................................................................................................................................................2 Tomcat服务器 .................................................................................................................................................................3 常见启动问题....................................................................................................................................................................3 Tomcat的目录结构 ..........................................................................................................................................................3 WEB应用程序...................................................................................................................................................................4 WEB应用的组成结构 ........................................................................................................................................................4 虚拟目录的映射方式(如何部署web程序) ..........................................................................................................................5 context元素常用属性 ......................................................................................................................................................5 Web系统通信详解............................................................................................................................................................5 配置虚似主机....................................................................................................................................................................6 作业(虚拟目录三种配置方式) ............................................................................................................................................6 使用Eclipse开发动态web程序..........................................................................................................................................7  WEB 开发的相关知识  WEB,在英语中 web 即表示网页的意思,它用于表示 Internet 主机上供外界访问的资源。 Internet 上供外界访问的 Web 资源分为: 静态 web 资源(如 html 页面):指 web 页面中供人们浏览的数据始终是不变。 动态 web 资源:指 web 页面中供人们浏览的数据是由程序产生的,不同时间点访问 web 页面看到的内容各不相同。 静态 web 资源开发技术 Html 常用动态 web 资源开发技术: JSP/Servlet、ASP、PHP 等 在 Java 中,动态 web 资源开发技术统称为 Javaweb,我们课程的重点也是教大家如何使用 Java 技术开发动态的 web 资源,即动态 web 页面。  javaweb:使用 java 技术开发 web 页面。供浏览器访问的项目 WEB 系统是怎么样通信的  常见 WEB 服务器  WebLogic 是 BEA 公司的产品,是目前应用最广泛的 Web 服务器,支持 JavaEE 规范,而且不断的完善以适应新的开发要求,启动界面如图  常见 WEB 服务器  另一个常用的 Web 服务器是 IBM 公司的 WebSphere,支持 J2EE 规范,启动界面如图  常见 WEB 服务器  apache  在小型的应用系统或者有特殊需要的系统中,可以使用一个免费的 Web 服务器:Tomcat,该服务器支持全部 JSP 以及 Servlet 规范,启动界面如图  Tomcat 服务器  Tomcat 官方站点:http://jakarta.apache.org 获取 Tomcat 安装程序包  tar.gz(zip)文件是 Linux 操作系统下的安装版本  exe 文件是 Windows 系统下的安装版本  zip 文件是 Windows 系统下的压缩版本  安装 Tomcat --- 配置 JAVA_HOME Tomcat 服务器  双击 bin 目录下的 startup.bat 文件 输入 http://localhost:8080/,显示如下界面代表安装成功  常见启动问题  JAVA_HOME 环境变量 在 windows 中设置 JAVA_HOME 环境变量 JAVA_HOME 路径必须是 JDK 不可以是 JRE 端口占用问题 WindoxXP 使用 Fport 工具 Win7 使用 DOS 命令 netstat –ano CATALINA_HOME 环境变量的设置问题 Tomcat 服务器与 Servlet 版本关系 Tomcat 版本 Servlet/JSP 版本 JavaEE 版本 运行环境 4.1 2.3/1.2 1.3 JDK1.3 5.5 2.4/2.0 1.4 JDK1.4 6 2.5/2.1 5 JDK5.0 7 3.0/2.2 6 JDK6.0  omcat 的目录结构  本文件 Conf:存放 Tomcat 服务器的各种配置文件 Lib: 存放 Tomcat 服务器和所有 web 应用程序需要访问的 jar 文件 Logs: 存放 Tomcat 的日志文件 Temp: 存放 Tomcat 运行时产生的临时文件 Webapps:当发布 web 应用程序时,通常把 web 应用程序的目录及文件放到这个目录下 Works: Tomcat 将 JSP 生成的 Servlet 源文件和字节码文件放到这个目录下 T Bin:存放启动和关闭 Tomcat 的脚 WEB 应用程序   WEB 应用程序指供浏览器访问的程序,通常也简称为 web 应用 一个 web 应用由多个静态 web 资源和动态 web 资源组成,如: html、css、js 文件 Jsp 文件、java 程序、支持 jar 包、 配置文件等等….. 组成 web 应用的这些文件通常我们会使用一个目录组织,这个目录称之为 web 应用所在目录(网站的根目录)。  Web 应用开发好后,若想供外界访问,需要把 web 应用所在目录交给 web 服务器管理,这个过程称之为虚似目录的映射。  Web 应用:例如有 a.html 、b.html…..多个 web 资源,这多个 web 资源用于对外提供邮件服务,此时应把这多个 web 资源放在一个目录中,以组成一个 web 应用(或 web 应用程序)。 WEB 应用的组成结构  开发 web 应用时,不同类型的文件有严格的存放规则,否则不仅可能会使 web 应用无法访问,还会导致 web 服务器启动报错。 虚拟目录的映射方式(如何部署 web 程序)  虚拟目录的映射有三种方式: 1、 在 server.xml 文件的 host 元素中配置,例如:  补充知识点:映射缺省 web 应用。 注意:一个 Context 即代表一个 web 应用,context 元素在配置文件中除用于映射虚似目录外,它还可用于为 web 应用配置一些资源,例如:配置 web 应用使用的数据 库连接池,javamailsession 等(这些本配置以后会用到)。  2、在 Tomcat6 中,不再建议在 server.xml 文件中配置 context 元素,细节查看 tomcat 服务器关于 context 元素的说明 3、让 tomcat 自动映射: tomcat 服务器会自动管理 webapps 目录下的所有 web 应用,并把它映射成虚拟目录。换句话说,tomcat 服务器 webapps 目录中的 web 应 用,外界可以直接访问 通过 WAR 方式发布部署 web 应用  WAR 文件制作 TomcatManager的使用  context 元素常用属性  课后查看 tomcat 关于 context 元素的文档  Web 系统通信详解  配置虚似主机   在一个 tomcat 服务器中可以放置多个网站,所谓配置虚似主机,就是在 tomcat 服务器中配置一个网站。 如需在 WEB 服务器中配置一个网站,需使用 Host 元素进行配置, 例:  配置的主机(网站)要想被外部访问,必须在 DNS 服务器或 windows 系统中注册 C:\WINDOWS\system32\drivers\etc\hosts  缺省虚似主机 作业(虚拟目录三种配置方式)  在 webapps 目录下创建一个可供外界访问的 web 应用 在 server.xml 文件中进行配置,把 c:盘下的某一个 web 应用映射成可供外界访问的虚似目录 在 catalina/localhost 目录下进行设置,把 c:盘下的某一个 web 应用映射成可供外界访问的虚似目录 在 server.xml 文件中配置一台 www.itcast.cn 的虚似主机,然后在 window 系统中注册 www.itcast.cn 这台主机 在虚似主机的根目录中创建一个名称为 itcast 的 web 应用,并在该应用下创建一个 index.html 页面,然后把 web 应用映射成缺省 web 应用。index.html 页面设置为 web 应用 的首页 将 web 服务器端口更改为 80 端口 画图说明浏览器是如何访问到 web 服务器下的 web 主机下的 web 应用下的 web 资源的 ipconfig/flushdns 使用 Eclipse 开发动态 web 程序   在 myeclipse 中新建一个 web project 工程   Servlet 开发  于洋 Servlet开发.................................................................................................................... 1 Servlet简介 .....................................................................................................................................................................1 快速入门总结....................................................................................................................................................................1 Servlet接口定义了Servlet生命周期.................................................................................................................................2 关于  Servlet的生命周期 ..................................................................................................................................................3 配置  Servlet自动加载......................................................................................................................................................3 Servlet接口实现类...........................................................................................................................................................4 当继承了HttpServlet的注意事项.....................................................................................................................................4 配置Servlet路径映射配置.................................................................................................................................................4 Servlet路径映射举例 .......................................................................................................................................................5 Web开发中的路径问题分析..............................................................................................................................................6 init方法中的ServletConfig对象......................................................................................................................................6 Web应用对象:ServletContext .....................................................................................................................................6 ServletContext应用........................................................................................................................................................6 web project中读取文件总结............................................................................................................................................7 关于缺省Servlet ..............................................................................................................................................................7 作业:整理以下问题的答案...............................................................................................................................................8 Servlet编程快入门...........................................................................................................................................................8  Servlet 简介  Servlet 是 sun 公司提供的一门用于开发动态 web 资源的技术 Servlet 技术基于 Request-Response 编程模型 Sun 公司在其 API 中提供了一个 servlet 接口,用户若想要开发一个动态 web 资源(即开发一个 Java 程序向浏览器输出数据),需要完成以下 2 个步骤: 编写一个 Java 类,实现 servlet 接口 把开发好的 Java 类部署到 web 服务器中 快速入门,用 servlet 向浏览器输出“hello servlet” 使用 MyEclipse 创建 webproject 通过向导创建 Servlet 继承 HttpServlet 配置 Servlet 虚拟路径 覆盖 doGet 或者 doPost 方法 进行输出 快速入门总结  编写 Servlet 步骤 继承 javax.servlet.http.HttpServlet web.xml 配置 Servlet 的虚拟路径 覆盖 doGet、doPost在 web.xml 配置 Servlet 访问虚拟路径  GET 方式请求提交映射关系  Servlet 的接口实现关系 Servlet 接口定义了 Servlet 生命周期  init()方法:服务器调用该方法初始化 Servlet service()方法:初始化完毕,服务器调用该方法响应客户的请求 destroy()方法:服务器调用该方法消灭 servlet 对象 其中,init()方法只在 Servlet 第一次被请求加载的时候被调用一次,当有客户再请求 Servlet 服务时,Web 服务器将启动一个新的线程,在该线程中,调用 service 方法响应客 户的请求 关于  Servlet 的生命周期   Servlet 是一个供其他 Java 程序(Servlet 引擎)调用的 Java 类,它不能独立运行,它的运行完全由 Servlet 引擎来控制和调度。 针对客户端的多次 Servlet 请求,通常情况下,服务器只会创建一个 Servlet 实例对象,也就是说 Servlet 实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务, 直至 web 容器退出,servlet 实例对象才会销毁。 在 Servlet 的整个生命周期内,Servlet 的 init 方法只被调用一次。而对一个 Servlet 的每次访问请求都导致 Servlet 引擎调用一次 servlet 的 service 方法。对于每次访问请求, Servlet 引擎都会创建一个新的 HttpServletRequest 请求对象和一个新的 HttpServletResponse 响应对象,然后将这两个对象作为参数传递给它调用的 Servlet 的 service()方法, service 方法再根据请求方式分别调用 doXXX 方法。 配置  Servlet 自动加载   如果在元素中配置了一个元素,那么 WEB 应用程序在启动时,就会装载并创建 Servlet 的实例对象、以及调用 Servlet 实例对象的 init()方法。  举例:     invoker    org.apache.catalina.servlets.InvokerServlet      2    例如:为 web 应用写一个 InitServlet,这个 servlet 配置为启动时装载,为整个 web 应用创建必要的数据库表和数据。 Servlet 接口实现类  Servlet 接口 SUN 公司定义了两个默认实现类,分别为:GenericServlet、HttpServlet。 HttpServlet 指能够处理 HTTP 请求的 servlet,它在原有 Servlet 接口上添加了一些与 HTTP 协议处理方法,它比 Servlet 接口的功能更为强大。因此开发人员在编写 Servlet 时, 通常应继承这个类,而避免直接去实现 Servlet 接口。 HttpServlet 在实现 Servlet 接口时,覆写了 service 方法,该方法体内的代码会自动判断用户的请求方式,如为 GET 请求,则调用 HttpServlet 的 doGet 方法,如为 Post 请求, 则调用 doPost 方法。因此,开发人员在编写 Servlet 时,通常只需要覆写 doGet 或 doPost 方法,而不要去覆写 service 方法。 阅读 HttpServlet API 文档 当继承了 HttpServlet 的注意事项  Servlet 初始化时覆盖 init() ,无需覆盖 init(config) 根据 Http 请求的方式,覆盖相应的 doGet 或者 doPost 方法,无需覆盖 Service 方法 当 doGet 和 doPost 代码逻辑相同时,可以相互调用,简化编程 Servlet 的运行过程(课后看) 配置 Servlet 路径映射配置  由于客户端是通过 URL 地址访问 web 服务器中的资源,所以 Servlet 程序若想被外界访问,必须把 servlet 程序映射到一个 URL 地址上,这个工作在 web.xml 文件中使用 元素和元素完成。 元素用于注册 Servlet,它包含有两个主要的子元素:,分别用于设置 Servlet 的注册名称和 Servlet 的完整类名。 一个元素用于映射一个已注册的 Servlet 的一个对外访问路径,它包含有两个子元素:,分别用于指定 Servlet 的注册名称和 Servlet 的对外访问路径。例如:      AnyName   HelloServlet       AnyName   /demo/hello.html   · 同一个 Servlet 可以被映射到多个 URL 上,即多个元素的子元素的设置值可以是同一个 Servlet 的注册名。 在 Servlet 映射到的 URL 中也可以使用*通配符,但是只能有两种固定的格式:一种格式是“*.扩展名”,另一种格式是以正斜杠(/)开头并以“/*”结尾。   AnyName    /action/*      AnyName     *.do    Servlet 路径映射举例  对于如下的一些映射关系: Servlet1 映射到 /abc/*  Servlet2 映射到 /*----- 所有路径 Servlet3 映射到 /abc  Servlet4 映射到 *.do  当请求 URL 为“/abc/a.html”,“/abc/*”和“/*”都匹配,哪个 servlet 响应  Servlet 引擎将调用 Servlet1。 当请求 URL 为“/abc”时,“/abc/*”和“/abc”都匹配,哪个 servlet 响应  Servlet 引擎将调用 Servlet3。 当请求 URL 为“/abc/a.do”时,“/abc/*”和“*.do”都匹配,哪个 servlet 响应  Servlet 引擎将调用 Servlet1。 当请求 URL 为“/a.do”时,“/*”和“*.do”都匹配,哪个 servlet 响应  Servlet 引擎将调用 Servlet2. 当请求 URL 为“/xxx/yyy/a.do”时,“/*”和“*.do”都匹配,哪个 servlet 响应  Servlet 引擎将调用 Servlet2。Web 开发中的路径问题分析   Web 系统中的相对路径和绝对路径 相对路径:hello   ./hello  ../myweb/hello 绝对路径:/hello   /myweb/hello 服务器端和客户端对于/ 的区别 客户端关于路径问题的编程结论 *.html  *.jsp 内都使用绝对路径 *.css  内部使用相对路径---- 背景图片 *.js 中使用绝对路径 init 方法中的 ServletConfig 对象  在 Servlet 的配置文件中,可以使用一个或多个标签为 servlet 配置一些初始化参数。 当 servlet 配置了初始化参数后,web 容器在创建 servlet 实例对象时,会自动将这些初始化参数封装到 ServletConfig 对象中,并在调用 servlet 的 init 方法时,将 ServletConfig 对象传递给 servlet。进而,程序员通过 ServletConfig 对象就可以得到当前 servlet 的初始化参数信息。 阅读 ServletConfig API,并举例说明该对象的作用: 获得配置文件,查看 struts 案例的 web.xml 文件 Web 应用对象:ServletContext  WEB 容器在启动时,它会为每个 WEB 应用程序都创建一个对应的 ServletContext 对象,它代表当前 web 应用。 ServletConfig 对象中维护了 ServletContext 对象的引用,开发人员在编写 servlet 时,可以通过 ServletConfig.getServletContext 方法获得 ServletContext 对象。 由于一个 WEB 应用中的所有 Servlet 共享同一个 ServletContext 对象,因此 Servlet 对象之间可以通过 ServletContext 对象来实现通讯。ServletContext 对象通常也被称之为 context 域对象。 查看 ServletContext API 文档,了解 ServletContext 对象的功能。 ServletContext 应用  获取 WEB 应用的初始化参数 通过 ServletContext 对象实现数据共享 案例--- 统计站点访问次数实现 Servlet 的转发  案例 --- 统计字母出现次数  利用 ServletContext 对象读取资源文件 web project 中读取文件总结  文件系统路径 getServletContext().getRealPath(“/WEB-INF/info.txt”)  类路径 classpath (src 下) 通过字节码对象读取 Class getResource(“/info.txt”).getFile() 获取字节码对象 Class 类名.class---- 静态方法 对象.getClass()  ----  实例方法 关于缺省 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。  服务器中的 html 文件数据的读取由缺省 servlet 完成 作业:整理以下问题的答案  HttpServlet 和 Servlet 是什么关系 实际开发 Servlet 的步骤是什么 什么是 Servlet 生命周期 init(ServletConfig)方法什么时候执行 为什么要配置 Servlet 的 url-pattern Servlet 路径映射有几种配置方式 ServletConfig 和 ServletContext 的区别 Servlet 编程快入门  request 获取页面数据 getParameter 设置页面请求数据编码 setCharacterEncoding(只适用 post) 获得请求头信息 getHeader response 设置响应状态码 setStatus 设置响应消息头 setHeader 获取页面输出流 getOutputStreamgetWriter 设置页面输出流编码 setContentTypeHttpServletResponse  于洋 HttpServletResponse.................................................................................................. 1 简介..................................................................................................................................................................................1 HttpServletResponse....................................................................................................................................................1 response  指定状态码&头信息 ........................................................................................................................................2 response状态码和头信息应用 .........................................................................................................................................2 response生成响应...........................................................................................................................................................2 response生成响应注意事项.............................................................................................................................................3 通过response实现文件下载.............................................................................................................................................3 输出验证码图片 ................................................................................................................................................................3 HttpServletRequest .................................................................................................... 4 HttpServletRequest ......................................................................................................................................................5 request获取客户机信息...................................................................................................................................................5 request获取请求头信息...................................................................................................................................................5 request获取请求参数 ......................................................................................................................................................6 URL特殊字符转义规则......................................................................................................................................................6 request利用请求域传递对象 ............................................................................................................................................7 请求转发的细节 ................................................................................................................................................................7 转发  vs.  重定向...............................................................................................................................................................8 请求重定向和请求转发的区别 ...........................................................................................................................................8 RequestDispatcher........................................................................................................................................................9 作业..................................................................................................................................................................................9  简介  Web 服务器收到客户端的 http 请求,会针对每一次请求,分别创建一个用于代表请求的 request 对象、和代表响应的 response 对象 request 和 response 对象即然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找 request 对象就行了。要向客户机输出数据,只需要找 response 对象就行了  HttpServletResponse  HttpServletResponse 对象服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。   response  指定状态码&头信息  状态码(Status Code) setStatus(int) 常用状态码:200、302、304、404、500  头信息 (Header Info) addHeader(String,String) 在原有值添加 setHeader(String,String) 替换原有值 response 状态码和头信息应用  通过 response 实现请求重定向。 请求重定向指:一个 web 资源收到客户端请求后,通知客户端去访问另外一个 web 资源,这称之为请求重定向 302+Location------response.sendRedirect 案例:用户登陆 发送 http 头,控制浏览器定时刷新网页(refresh) 多学一招:HTML标签来控制浏览器行为 发送 http 头,控制浏览器禁止缓存当前文档内容 response 生成响应  获得向客户端进行数据输出的流对象 字节流数据输出 OutputStreamout=response.getOutputStream(); 字符流数据输出PrintWriterpw=response.getWriter(); 指定 body 内容的类型 setContentType("text/html") 指定输出数据的编码格式 setCharacterEncoding("gb2312"); 默认情况下,编码格式是 ISO-8859-1 response 生成响应注意事项  getOutputStream 和 getWriter 方法分别用于得到输出二进制数据、输出文本数据的 ServletOuputStream、Printwriter 对象。 getOutputStream 和 getWriter 这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。 Servlet 程序向 ServletOutputStream 或 PrintWriter 对象中写入的数据将被 Servlet 引擎从 response 里面获取,Servlet 引擎将这些数据当作响应消息的正文,然后再与响应状态 行和各响应头组合后输出到客户端。 Serlvet 的 service 方法结束后,Servlet 引擎将检查 getWriter 或 getOutputStream 方法返回的输出流对象是否已经调用过 close 方法,如果没有,Servlet 引擎 tomcat 将调用 close 方法关闭该输出流对象。调用 close 的时候,应该会调用 flushBuffer 通过 response 实现文件下载  通过超链接实现文件下载 只能下载浏览器不识别的文件格式  通过 Servlet 程序实现文件下载 设置 Content-Type 文件类型头信息 通过 ServletContext 的 getMimeType 方法获得文件类型 设置 Content-Disposition 头信息以附件形式打开 中文文件名通过 URLEncoder 进行编码 输出验证码图片  建立 BufferedImage 对象:指定图片的长度宽度和类型 BufferedImageimage=newBufferedImage(width,height,BufferedImage.TYPE_INT_RGB); 取得 Graphics 对象,用来绘制图片 Graphicsgraphics=image.getGraphics(); 绘制背景颜色 graphics.setColor(Color.WHITE); graphics.fillRect(0,0,width,height); 绘制边界 graphics.setColor(Color.BLUE);graphics.drawRect(0,0,width-1,height-1); 生成随机数 Randomrandom=newRandom(); random.nextInt(n);// 生成 0 到 n 的随机数 前闭后开 绘制干扰线 graphics.drawLine(x1,y1,x2,y2); 设置字体 graphics.setFont(newFont("TimesNewRoman",Font.PLAIN,18)); 如果验证码是中文,要使用中文的字体库 通过词库生成随机验证码内容 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"; 汉字:\u4e00 —— \u9fa5 graphics.drawString(str,x,y); 设置旋转 Graphics2Dgraphics=(Graphics2D)image.getGraphics(); graphics.rotate(theta,x,y); 释放此图形的上下文以及它使用的所有系统资源  graphics.dispose(); 通过 ImageIO 对象的 write 静态方法将图片输出 ImageIO.write(image,"jpg",resp.getOutputStream());  Stringbase=  "\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u7740\u4e2a\u5730\u5230\u5927\u91cc\u8bf4\u5c31\u53bb\u5b50\u5f97\u4e5f\ u548c\u90a3\u8981\u4e0b\u770b\u5929\u65f6\u8fc7\u51fa\u5c0f\u4e48\u8d77\u4f60\u90fd\u628a\u597d\u8fd8\u591a\u6ca1\u4e3a\u53c8\u53ef\u5bb6\u5b66\u53ea\u4ee5\u4 e3b\u4f1a\u6837\u5e74\u60f3\u751f\u540c\u8001\u4e2d\u5341\u4ece\u81ea\u9762\u524d\u5934\u9053\u5b83\u540e\u7136\u8d70\u5f88\u50cf\u89c1\u4e24\u7528\u5979\u56 fd\u52a8\u8fdb\u6210\u56de\u4ec0\u8fb9\u4f5c\u5bf9\u5f00\u800c\u5df1\u4e9b\u73b0\u5c71\u6c11\u5019\u7ecf\u53d1\u5de5\u5411\u4e8b\u547d\u7ed9\u957f\u6c34\u51e0\ u4e49\u4e09\u58f0\u4e8e\u9ad8\u624b\u77e5\u7406\u773c\u5fd7\u70b9\u5fc3\u6218\u4e8c\u95ee\u4f46\u8eab\u65b9\u5b9e\u5403\u505a\u53eb\u5f53\u4f4f\u542c\u9769\u6 253\u5462\u771f\u5168\u624d\u56db\u5df2\u6240\u654c\u4e4b\u6700\u5149\u4ea7\u60c5\u8def\u5206\u603b\u6761\u767d\u8bdd\u4e1c\u5e2d\u6b21\u4eb2\u5982\u88ab\u 82b1\u53e3\u653e\u513f\u5e38\u6c14\u4e94\u7b2c\u4f7f\u5199\u519b\u5427\u6587\u8fd0\u518d\u679c\u600e\u5b9a\u8bb8\u5feb\u660e\u884c\u56e0\u522b\u98de\u5916\u6 811\u7269\u6d3b\u90e8\u95e8\u65e0\u5f80\u8239\u671b\u65b0\u5e26\u961f\u5148\u529b\u5b8c\u5374\u7ad9\u4ee3\u5458\u673a\u66f4\u4e5d\u60a8\u6bcf\u98ce\u7ea7\u8 ddf\u7b11\u554a\u5b69\u4e07\u5c11\u76f4\u610f\u591c\u6bd4\u9636\u8fde\u8f66\u91cd\u4fbf\u6597\u9a6c\u54ea\u5316\u592a\u6307\u53d8\u793e\u4f3c\u58eb\u8005\u5e7 2\u77f3\u6ee1\u65e5\u51b3\u767e\u539f\u62ff\u7fa4\u7a76\u5404\u516d\u672c\u601d\u89e3\u7acb\u6cb3\u6751\u516b\u96be\u65e9\u8bba\u5417\u6839\u5171\u8ba9\u76f8 \u7814\u4eca\u5176\u4e66\u5750\u63a5\u5e94\u5173\u4fe1\u89c9\u6b65\u53cd\u5904\u8bb0\u5c06\u5343\u627e\u4e89\u9886\u6216\u5e08\u7ed3\u5757\u8dd1\u8c01\u834 9\u8d8a\u5b57\u52a0\u811a\u7d27\u7231\u7b49\u4e60\u9635\u6015\u6708\u9752\u534a\u706b\u6cd5\u9898\u5efa\u8d76\u4f4d\u5531\u6d77\u4e03\u5973\u4efb\u4ef6\u611 f\u51c6\u5f20\u56e2\u5c4b\u79bb\u8272\u8138\u7247\u79d1\u5012\u775b\u5229\u4e16\u521a\u4e14\u7531\u9001\u5207\u661f\u5bfc\u665a\u8868\u591f\u6574\u8ba4\u54cd \u96ea\u6d41\u672a\u573a\u8be5\u5e76\u5e95\u6df1\u523b\u5e73\u4f1f\u5fd9\u63d0\u786e\u8fd1\u4eae\u8f7b\u8bb2\u519c\u53e4\u9ed1\u544a\u754c\u62c9\u540d\u5440\ u571f\u6e05\u9633\u7167\u529e\u53f2\u6539\u5386\u8f6c\u753b\u9020\u5634\u6b64\u6cbb\u5317\u5fc5\u670d\u96e8\u7a7f\u5185\u8bc6\u9a8c\u4f20\u4e1a\u83dc\u722c\u7 761\u5174\u5f62\u91cf\u54b1\u89c2\u82e6\u4f53\u4f17\u901a\u51b2\u5408\u7834\u53cb\u5ea6\u672f\u996d\u516c\u65c1\u623f\u6781\u5357\u67aa\u8bfb\u6c99\u5c81\u7ebf \u91ce\u575a\u7a7a\u6536\u7b97\u81f3\u653f\u57ce\u52b3\u843d\u94b1\u7279\u56f4\u5f1f\u80dc\u6559\u70ed\u5c55\u5305\u6b4c\u7c7b\u6e10\u5f3a\u6570\u4e61\u547c\u 6027\u97f3\u7b54\u54e5\u9645\u65e7\u795e\u5ea7\u7ae0\u5e2e\u5566\u53d7\u7cfb\u4ee4\u8df3\u975e\u4f55\u725b\u53d6\u5165\u5cb8\u6562\u6389\u5ffd\u79cd\u88c5\u9 876\u6025\u6797\u505c\u606f\u53e5\u533a\u8863\u822c\u62a5\u53f6\u538b\u6162\u53d4\u80cc\u7ec6"; HttpServletRequest  于洋HttpServletRequest  HttpServletRequest 对象代表客户端的请求,当客户端通过 HTTP 协议访问服务器时,HTTP 请求中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获 得客户这些信息。 通过 Request 对象进行的常用操作 获取客户机信息 获取请求头信息 获取请求参数 利用请求域传递对象  request 获取客户机信息  getRequestURL 方法返回客户端发出请求时的完整 URL getRequestURI 方法返回请求行中的资源名部分 getQueryString 方法返回请求行中的参数部分 getRemoteAddr 方法返回发出请求的客户机的 IP 地址 getRemoteHost 方法返回发出请求的客户机的完整主机名 getRemotePort 方法返回客户机所使用的网络端口号 getLocalAddr 方法返回 WEB 服务器的 IP 地址 getLocalName 方法返回 WEB 服务器的主机名 getMethod 得到客户机请求方式 request 获取请求头信息  获得客户机请求头 getHeader(name)方法 ---String  getHeaders(Stringname)方法 ---Enumeration getHeaderNames 方法 ---Enumeration 获得具体类型客户机请求头 getIntHead(name)方法  ---int getDateHead(name)方法 ---long(日期对应毫秒)案例:通过 referer 信息防盗链 request 获取请求参数  getParameter(name) --- String 通过 name 获得值 getParameterValues --- String[ ] 通过 name 获得多值 checkbox getParameterNames --- Enumeration 获得所有 name getParameterMap --- Map key :name value: 多值 数据非空校验 处理中文乱码 post setCharacterEncoding  //放在 getParameter 前才有效 get newString(str.getBytes(“ISO-8859-1”),”utf-8”) 设置 tomcatConnectorURIEncoding=“utf-8”  可以提交请求的两种方式 1.使用

       执行 form 的 submit,提交 form 表单。 常用表单元素