3月25日——培训第89天

Composite模式:

Junit中的TestCase和TestSuite就是组合模式,
Test接口派生出TestCase、TestSuite、TestDecorator
TestSuite有一个add方法,里面传入的是Test接口引用,这样它
就又可以添加TestCase,也可以添加TestSuite了。

java.awt中也用到了这种设计模式。

计算机主板上可以插入CPU和显卡,显卡和CPU上还可以再插风扇,风扇又可以
直接插到主板上。

组件上不能再添加新的组件的模式是安全式模式
还有一个透明式的组合模式。

-----------------------------------------------------------------------------------

decorator模式:在不修改类的前提下,改变类的方法和行为。

比如在不修改ArrayList的情况下,改变ArrayList的add方法,使得
它在每次执行前打印出一段日志,并能够将对象添加到集合里面去,而
其他的方法不受到任何的影响。

//装饰类
public class ListDecorator extends ArrayList
{
 private ArrayList list ;
 
 public ListDecorator(ArrayList list)
 {
  this.list = list ;
 }
 
 public boolean add(Object arg0)
 {
  System.out.println("In add method");
  return list.add(arg0)
 }
}

IO中的很多类都用到了Decorator,如BufferedReader等。

----------------------------------------------------------------------------------
Facade模式:

子系统十分复杂,包含很多类和接口,如何让用户不用完全了解所有的接口和类,就可以顺利
使用子系统呢?

如何对子系统进行整理

一个保安系统由是个录像机Camera、20个电灯Light、5个遥感器Sensor、和一个警报器Alarm组成,
定义这个系统,并在客户端操作这个系统。

----------------------------------------------------------------------------------
Flyweight模式:
文本编辑器中,一个字可能要在文章中出现几十次,那么采用面向对象的编程是否要为每个创建一个
实例对象呢?

如果创建,存储空间浪费太大,因为它们都是对的同一个字,具有相同特征。,如果不创建,又如何
去标识这个对象的存在呢?

文本编辑器必须为每个字幕创建一个对象,如何实现?

有点像伪单例模式

在TextEditor里面创建一个对象的集合,里面装的是字体对象实例。
比如使用Map
---------------------------------------------------------------------------------

代理模式:
Hibernate和Spring里面都用到了。

在实现上和装饰模式一样,但是二者的目的不一样

java.lang.reflect.Proxy
java.lang.reflect.InvocationHandler

===============================================================================

行为模式:

chain of responsibility模式:
如果存在不同种类消息,它们分别由一个特定的对象处理,如何实现?
使用switch case吗?

使用switch case的问题在于当新类型的消息类型出现时,必须要修改
switch case代码,增加处理新消息类型的内容

写一段代码,当一个异常传给这段代码可以根据代码的类型不同而生成不同的友好信息,
要保证异常全面并可扩展。

把所有处理异常的方法做成一个链,每一个节点只处理一种异常

public abstract class ExceptionHandler
{
 protected ExceptionHandler nextHandler
 
 public void setNextHandler(ExceptionHandler n)
 {
  nextHandler = n ;
 }

 public abstract String handleException(Exception e);

}

public class SqlExceptionHandler extends ExceptionHandler
{
 public String handleException(Exception e)
 {
  if(e instanceof SQLException)
  {
   return "发生了数据库异常" ;
  }

  else
  {
   if(nextHandler!=null)
   {
    return nextHandler.handleException(e);
   }
  }

  return "无法识别的异常" ;
 }
}

 

public class NullpointerExceptionHandler extends ExceptionHandler
{
 public String handleException(Exception e)
 {
  if(e instanceof NullPointerException)
  {
   return "发生了空指针异常" ;
  }

  else
  {
   if(nextHandler!=null)
   {
    return nextHandler.handleException(e);
   }
  }

  return "无法识别的异常" ;
 }
}

public static void main(String[] args)
{
 ExceptionHandler sql = new SqlExceptionHandler();
 ExceptionHandler np = new NullpointerExceptionHandler();
 sql.setNextHandler(np);//构造成链

 System.out.println(sql.handleException(new NullPointerException()));
}


特征描述

主要是所有的处理者都要实现同一个方法,并将它们构造成链,当自身无法处理时,将请求传给下一个处理者。
职责链模式的最大好处是回避了switch case的使用。

应用场景

有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
可处理一个请求的对象集合应被动态指定。

------------------------------------------------------------------------------
Command模式

问题描述:
在常见的文本编辑器中,撤消与重做是两个经常要用到的操作,如何实现?

问题难点:
同一个命令要对各种不同的操作做撤消或重做工作,程序不仅要记住都进行了哪些操作,
还必须记住每个操作的撤消操作或重做操作是什么,如果不使用好的模式,根本无法实现。
各种操作的对象也可能不同,比如同样是设置大小,可能是针对文字,
也可能是针对图片;即使都是针对文字,也必须记录是哪一个或哪些文字。

房间内有一盏灯和一台电风扇,灯可以打开、熄灭,风扇可以打开、关闭、加速、减速。
用户进入房间后,可以以任意顺序对灯和风扇进行操作。设计程序,要求可以对用户操作
做撤消和重做。

public abstract class Command
{
 public abstract void redo() ; //重做
 public abstract void undo() ; //撤销
}

public class Light
{
 public void on()
 {
  System.out.println("开灯了!");
 }

 public void off()
 {
  System.out.println("熄灯了!");
 }
}

public class Fan
{
 public void rotate()
 {
  System.out.println("电风扇转动了!");
 }

 public void stop()
 {
  System.out.println("电风扇停止转动!");
 }

 public void speedUp()
 {
  System.out.println("风扇加速转动!");
 }

 public void slowDown()
 {
  System.out.println("风扇减速转动!");
 }
}


public class LightOnCommand extends Command
{
 private Light light ;
 public LightOnCommand(Light light)
 {
  this.light = light ;
 }

 public void redo()
 {
  light.on();
 }
 
 public void undo()
 {
  light.off();
 }
}


public class LightOffCommand extends Command
{
 private Light light ;

 public LightOffCommand(Light light )
 {
  this.light = light ;
 }

 public void redo()
 {
  light.off();
 }
 
 public void undo()
 {
  light.on();
 }
}


//同理、FanStopCommand、FanSpeedUpCommand、FanSlowDownCommand
//类也可以像下面一样定义
public class FanRotateCommand extends Command
{
 private Fan fan ;

 public FanRotateCommand(Fan fan)
 {
  this.fan = fan ;
 }

 public void redo()
 {
  fan.rotate();
 }
 
 public void undo()
 {
  fan.stop();
 }
}


public class FanStopCommand extends Command
{
 private Fan fan ;

 public FanStopCommand(Fan fan)
 {
  this.fan = fan ;
 }

 public void redo()
 {
  fan.stop();
 }
 
 public void undo()
 {
  fan.rotate();
 }
}

//房间类就相当于界面了……
public class House
{
 private Vector redoList = new Vector() ;
 private Vector undoList = new Vector() ;

 public void executeCommand(Command c)
 {
  c.redo() ;
  undoList.add(c) ;
 }

 public void undo()
 {
  //取出最后一次加入的那个命令
  Command c = (Command)undoList.lastElement();
  c.undo();
  redoList.add(c) ;//加入到重做的集合中去
  undoList.remove(c) ;
 }

 public void redo()
 {
  Command c = (Command)redoList.lastElement() ;
  c.redo() ;
  undoList.add(c) ;
  redoList.remove(c) ;
 }
}


public static void main(String[] args)
{
 House n = new House() ;
 Command on = new LightOnCommand(new Light()) ;
 Command rotate = new FanRotateCommand(new Fan()) ;
 n.executeCommand(on) ;
 n.executeCommand(rotate) ;

 n.undo() ;
 n.redo() ;
 n.undo() ;
 n.undo() ;
}

//上述命令模式的结构很清晰,而且这种设计真的很牛逼……

命令独立于对象存在,比如TestCase就是典型的命令模式,本来
是你写的类去运行,结果运行的反倒是TestCase,让TestCase
去调用你的类中的方法。

特征描述
将命令独立出来,而在内部包含真正的执行者。命令可以单独处理,也可以拿到任何其它的
地方再次运行,这就保证了回退的可能。

应用场景
抽象出待执行的动作以参数化某对象,Command 模式是回调机制的一个面向对象的替代品。
在不同的时刻指定、排列和执行请求,可将负责该请求的命令对象传送给另一个不同的进程并
在那儿实现该请求。

支持取消操作。
支持修改日志,这样当系统崩溃时,这些修改可以被重做一遍。
用构建在原语操作上的高层操作构造一个系统。
----------------------------------------------------------------------
Interpreter模式

当有一个语言需要解释执行, 并且你可将该语言中的句子表示为一个抽象语法树时,

可使用解释器模式。而当存在以下情况时该模式效果最好:
该文法简单对于复杂的文法, 文法的类层次变得庞大而无法管理。此时语法分析程序生成器
这样的工具是更好的选择。它们无需构建抽象语法树即可解释表达式, 这样可以节省空间而
且还可能节省时间。

效率不是一个关键问题最高效的解释器通常不是通过直接解释语法分析树实现的, 而是首先
将它们转换成另一种形式。例如,正则表达式通常被转换成状态机。但即使在这种情况下,
转换器仍可用解释器模式实现, 该模式仍是有用的。

------------------------------------------------------------------
Iterator模式:

问题描述
对于一种存储结构,如何能够在不暴露其存储结构细节的情况下,实现对其内部元素的顺序访问?

问题难点
不暴露内部存储结构基于两方面考虑
不希望存储结构被不正确的使用
便于程序员访问元素,而无需了解其内部实现细节

给ArrayList设计一个Iterator,使它能够按顺序返回集合中的对象

Iterator里面肯定也是个对象组合的思想,ArrayList的Iterator肯定包含一个ArrayList,
然后Iterator中的next或是hasNext要通过ArrayList的方法来间接的实现。

特征描述
一般会在迭代器中包含集合的引用,在迭代方法中通过访问集合的相应方法实现对集体的迭代
应用场景
访问一个聚合对象的内容而无需暴露它的内部表示。
支持对聚合对象的多种遍历。
为遍历不同的聚合结构提供一个统一的接口(即, 支持多态迭代)。

这种模式可以不暴露具体集合的结构

------------------------------------------------------------------------

Mediator模式

问题描述
如果多个对象间需要相互协作,每个对象都必须知道所有的其它对象,这将使对象间的关系变得十分复杂。
如何简化这种关系?

问题难点
主要的难点在于多个对象协作时,一个对象的变化可以会直接影响到另一个对象,甚至所有对象。
如果将所有对象变化引起的连带变化都定义出来,这将会使系统变得混乱

法人(Corporation)实体间会发生一些关系,比如,一个公司(Company)需要和工商(ICAdmin)、
税务(TaxAdmin)等机构打交道,其中任何一方发生变化时,其它两方都要进行调整,试写一程序
模拟这种变化。

//法人
public abstract class Corporation
{
 public abstract void change() ;
 public abstract void acceptChanges() ;

}

public class ICAdmin extends Corporation
{
 private Mediator mediator ;

 public ICAdmin(Mediator mediator)
 {
  this.mediator = mediator ;
  mediator.register(this) ;
 }
 public void acceptChanges()
 {
  System.out.println("工商部门接受到了变化!");
 }
 
 public void change()
 {
  mediator.corporationChanged(this) ;
 }
}


public class Company extends Corporation
{
 private Mediator mediator ;

 public Company(Mediator mediator)
 {
  this.mediator = mediator ;
  mediator.register(this) ;
 }
 public void acceptChanges()
 {
  System.out.println("公司接受到了变化!");
 }
 
 public void change()
 {
  mediator.corporationChanged(this) ;
 }
}

public class TaxAdmin extends Corporation
{
 private Mediator mediator ;

 public TaxAdmin(Mediator mediator)
 {
  this.mediator = mediator ;
  mediator.register(this) ;
 }
 public void acceptChanges()
 {
  System.out.println("税务接受到了变化!");
 }
 
 public void change()
 {
  mediator.corporationChanged(this) ;
 }
}

public class Mediator
{
 private ICAdmin ic ;
 private TaxAdmin tax ;
 private Company c ;

 public void register(Corporation c)
 {
  if(c instanceof Company)
  {
   this.c = (Company)c ;
  }
  else if(c instanceof ICAdmin)
  {
   this.ic = (ICAdmin)c ;
  }
  else
  {
   this.tax = (TaxAdmin)c ;
  }
 }

 //以下最好使用职责链来实现
 public void corporationChanged(Corporation c)
 {
  if(c instanceof Company)
  {
   ic.acceptChanges() ;
   tax.acceptChanges() ;
  }
  else if(ic instanceof ICAdmin)
  {
   this.c.acceptChanges() ;
   tax.acceptChanges() ;
  }
  else
  {
   this.c.acceptChanges() ;
   ic.acceptChanges();
  }
 }
}

public static void main(String[] args)
{
 Mediator m = new Mediator() ;
 Company c = new Company(m) ;
 ICAdmin ic = new ICAdmin(m) ;
 TaxAdmin tax = new TaxAdmin(m) ;

 c.change() ;

 ic.change() ;
}

特征描述
同事间互不相实,由中介者完成同事间交互
同事不知道任何其它同事,只知道中介者,也即具有一个中介者属性

应用场景
一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
想定制一个分布在多个类中的行为,而又不想生成太多的子类。

典型应用
界面元素内的相互约束关系
广义上说,MVC中的controller是M、V的中介者,例如Spring中的DispatcherServlet
即为HandlerMapping、Controller、ViewResolver、View之间的中介者。这些对象不
直接打交道,而是通过DispatcherServlet完成交互


-----------------------------------------------------------------------
Memento模式(备忘录)
问题描述
如何记住系统的某一刻状态,以便可以恢复到这个状态上
问题难点
在记住系统状态的同时,又不能暴露系统的内部结构

一个三角形,具有三边长、颜色等特性,当修改了它的这些属性后,如何能够让它恢复到
前一次的状态中?

public class Triangle
{
 private int a ;
 private int b ;
 private int c ;
 private String color ;
 //getter、setter方法略
 public Triangle(int a ,int b , int c , String color)
 {
  this.a = a ;
  this.b = b ;
  this.c = c ;
  this.color = color ;
 }

 public TriangleMemento createMemento()
 {
  TriangleMemento memento = new TriMemento() ;
  memento.setA(a) ;
  memento.setB(b) ;
  memento.setC(c) ;
  memento.setColor(color) ;

  return memento ;
 }

 public void restore(TriangleMemento memento)
 {
  a = memento.getA() ;
  b = memento.getB() ;
  c = memento.getC() ;
  color = memento.getColor() ;
 }

 public String toString()
 {
  return "a = " + a
   + ", b = "+b+" , c = "+c+", color = "+color ;
 }
}

public class TriangleMemento
{
 private int a ;
 private int b ;
 private int c ;
 private String color ;

 //getter、setter方法。
}

public static void main(String[] args)
{
 Triangle t = new Triangle(1,2,3,"red") ;
 TriangleMemento memento = t.createMemento() ;
 System.out.println(t) ;
 t.setA(3) ;
 t.setB(4) ;
 System.out.println(t);
 t.restore(memento);
 System.out.println(t) ;
}

特征描述
重点是将对象具备的状态提出到备忘录中,以使不暴露原有对象的结构信息。
应用场景
必须保存一个对象在某一个时刻的(部分)状态, 这样以后需要时它才能恢复到先前的状态。
如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。

典型应用
广义上说,session/cookies都是Memento模式的应用
Struts中,当提交表单的数据出现错误时,要返回包含表单的页面,并恢复其中的数据,
使用了ActionForm也是备忘录的一种应用

--------------------------------------------------------------------------

Observer模式

问题描述
系统中往往会有这样的需求,当一对象的状态发生改变时,必须要通知所有与它相关联的对象,如何实现?

问题难点
必须保证当有新对象加入进来时,不用修改原有代码

老师和学生都关心学校发布的各项消息,当学校有新的制度发布时,必须要向老师和学生发布。
如果政府也关心学校发布的消息,如何能够在不修改原有代码的情况下,保证消息也能发到政府那里?

让政府也实现一个Observer接口

public class School extends Observable
{
 public void publish()
 {
  System.out.println("学校发布了一个消息!") ;
  setChanged() ; //调用Observable的protected方法

  notifyObservers() ;
 }
}

public class Student implements Observer
{
 public void update(Boservable o , Object arg)
 {
  System.out.println("学生接收到了一个消息");
 }
}

public class Teacher implements Observer
{
 public void update(Boservable o , Object arg)
 {
  System.out.println("老师接收到了一个消息");
 }
}

public static void main(String[] args)
{
 School s = new School() ;
 s.addObserver(new Student()) ;
 s.addObserver(new Student()) ;
 s.addObserver(new Teacher()) ;
 s.addObserver(new Student()) ;
 s.publish() ;
}

//现在如果要加入政府的话、和老师学生是一个道理。
特征描述
观察者要向被观察者注册,当状态发生变化时,观察者要迭代向所有观察者发消息。

应用场景
必须保存一个对象在某一个时刻的(部分)状态, 这样以后需要时它才能恢复到先前的状态。
如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。
比如监听器。

Java对Observer模式提供了内置支持,参见
java.util.Observer
java.util.Observable :被观察者

--------------------------------------------------------------------------

State模式:

问题描述
当一个对象在不同状态下的行为完全不同时,如何根据状态影响行为?

问题难点
想当然的实现是使用switch case或if语句,判断条件,然后给出行为。
但当对象增加了新状态时,这种条件判断语句就必须更改。

蝴蝶(butterfly)一生要经历幼虫(grub)、蛹(pupa)、成虫(imago)
三种状态,在不同的状态下它的行(walk)、飞(fly)、吃(eat)是完全不
同的,如何设计类,能够使得在加入新的状态时,不用改变原有代码,也可改变
以上行为?

在状态(幼虫、蛹、成虫)中定义行为(行走、飞、吃),在蝴蝶中持有状态对象。

public class ButterFly
{
 private State state ;

 public void setState(State state)
 {
  this.state = state ;
 }
 public void walk()
 {
  state.walk() ;
 }
 public void fly()
 {
  state.fly() ;
 }
 public void eat()
 {
  state.eat() ;
 }
}

public abstract class State
{
 public abstract void walk();
 public abstract void fly() ;
 public abstract void eat() ;
}

public class Grub extends State
{
 public abstract void walk()
 {
  System.out.println("我只能爬");
 }
 public abstract void fly()
 {
  System.out.println("我还不能飞");
 }
 public abstract void eat()
 {
  System.out.println("我爱吃青菜");
 }
}

public class Pupa extends State
{
 public abstract void walk()
 {
  System.out.println("我现在走不动");
 }
 public abstract void fly()
 {
  System.out.println("我还不能飞");
 }
 public abstract void eat()
 {
  System.out.println("我现在什么都不吃");
 }
}


public class Imago extends State
{
 public abstract void walk()
 {
  System.out.println("我飞,不走");
 }
 public abstract void fly()
 {
  System.out.println("我可以飞了");
 }
 public abstract void eat()
 {
  System.out.println("我现在采蜜");
 }
}

public static void main(String[] args)
{
 State grub = new Grub() ;
 State pupa = new Pupa() ;
 ButterFly bf = new ButterFly() ;
 bf.setState(grub) ;
 bf.eat();bf.walk();bf.fly() ;

 bf.setState(pupa) ;
 bf.eat();bf.walk();bf.fly() ;
}

特征描述
将行为提取到状态中,对象行为通过状态实现

应用场景
一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。
一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常
用一个或多个枚举常量表示。通常, 有多个操作包含这一相同的条件结构。State模式将每
一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一
个对象,这一对象可以不依赖于其他对象而独立变化。

TCP连接:关闭、打开、监听等状态,各种不同的状态对于同一个“打开”命令的响应是绝对
  不同的,将状态独立出去,分别对不同的行为进行各自独立的响应就可以了。

---------------------------------------------------------------------------

Strategy模式

问题描述
一种业务可以通过几种算法实现,如何实现?

问题难点
想当然的作法依然是使用switch case或if,但当有新算法加入进来时,
如何能够在不改变原有代码的基础上,加入新算法?

网上商城对不同种类的客户采用不同的折扣计算方法,但折扣计算方法可能
会发生变化或增加新的算法,如何给它们解耦合?

 

特征描述
在对象中包含算法对象

应用场景
许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间/时间权衡的算法。
算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
一个类定义了多种行为, 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的
条件分支移入它们各自的Strategy类中以代替这些条件语句。

典型应用
AWT中的Layout
-----------------------------------------------------------------------------

Template Method模式

问题描述
在许多的应用中,业务流程的骨架是完全相同的,只是其中的某些内容不同,
如何简化这种开发,使得程序只关心其中变化的部分呢?

特征描述
模板定义逻辑骨架,由子类给出步骤中的实现

应用场景
一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
控制子类扩展。

典型应用
Java类库中大量的应用了模板模式
Spring在数据层的封装也大量的使用了模板模式

-----------------------------------------------------------------------------
Visitor模式:

问题描述
如果存在一个较复杂的结构,它内部元素的结构已经固定不变,行为也不变。
如何在不暴露其内部组织结构的情况下,为结构中的元素增加新的行为?

应用场景
一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。
需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。
当该对象结构被很多应用共享时,用Vi s i t o r模式让每个应用仅包含需要用到的操作。
定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者
的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。

public class Visitor
{
 public void visitComponentA(ComponentA a)
 {
  a.setValue(100) ;
 }

 public void visitComponentB(ComponentB b)
 {
  b.setValue(100) ;
  
 }
}

public class ComponentA
{
 int value ;
 //getter和setter方法
}

public class ComponentB
{
 int value ;
 //getter和setter方法
}


public class ComplexObject
{
 List list = new ArrayList() ;
 public ComplexObject(ComponentA a, ComponentB b)
 {
  list.add(a);
  list.add(b);
 }

 public void accept(Visitor visitor)
 {
  Iterator it = list.iterator() ;
  while(it.hasNext())
  {
   Object obj = it.next() ;
   if(obj instanceof ComponentA)
   {
    visitor.visitComponentA((ComponentA)obj) ;
   }
   else if(obj instanceof ComponentB)
   {
    visitor.visitComponentB((ComponentB)obj);
   }
  }
 }
}

以后要扩充行为的时候只要增加访问者就可以了,不用更改ComplexObject这个
复杂对象类。

m o s s t v c c i i m

=================================================================

复习:

BS模式分层:表述层、逻辑层、数据层(j2EE规范)
在每一层都使用了什么样的技术实现?
表述层:Servlet
逻辑层:EJB(SessionBean、消息驱动的Bean如JMS)
数据层:实体Bean

表述层(Servlet、Filter、Listener)

Listener监听两类事件:生命周期和属性的增删改,
Session里面多了个钝化和激活的问题,所以多了个监听器。
一共9个。

过滤器、监听器和Servlet属于一体系。

get和post请求:参数的封装位置不同导致get的数据长度有限,post的
参数封装在体里面。

jsp里面相对来说东西多一些:模版(翻译过程中不会改变)和元素(行为元素、指令元素、
脚本元素:脚本声明、脚本表达式、脚本片段)

include指令和include动作一个是编译前包含、一个是编译后包含(都可以包含WEB-INF
文件夹里面的东西)

RequestDispatcher的forward方法和include方法也可以访问WEB-INF里面的东西。

pageEncoding影响容器翻译时候读时采用的编码
contentType影响的是浏览器

contentType和pageEncoding只设定一个就可以,另外一个会和已经配置的这个保持一致。

exception内置对象:仅仅在isErrorPage为true的时候才可以使用。

pageContext通过getOut方法得到的未必是Out对象(JspWriter:进行了缓存)。

response.getWriter得到的是PrintWriter(没有缓存)

这里面有个bodyContent、pushBody和popBody的问题!!

EL表达式中的11个内置对象:配置里面有个isELIgnored,默认为false
四个作用域(实际上是Map)、param、paramValues、header、headerValues、cookies、
pageContext(可以得到所有的内置对象)

sessionID:Cookie和URL两种形式生成。

转发与重定向:是否生成临时响应、地址栏是否变化、是否处于同一个请求作用域里面。
请求转发最多能够在一个容器范围的不同Web工程中跳来跳去,但是重定向可以随便的跳。


jsp的行为元素:useBean(在service方法内部开放一个脚本变量供表达式使用、将这个脚本
变量存储到指定的作用域里面,注意作用域里面存的是引用!!)
setProperty和getProperty,我们设置的属性只要有getter和setter方法就可以,不需要有
属性名,其实就是利用javaBean的自省机制找属性的getter方法和setter方法。

表达式的点操作符也是用了javaBean的自省机制。

注意jsp的forward和servlet里面的forward就是差了个return,servlet执行完forward
之后还要执行剩下的代码,而jsp就忽略forward后面的代码了。
------------------
自定义标签:标签的处理类、tld文件、taglib引入jsp页面。

标签分为两大类:传统标签和简单标签(其实还有标签文件)

传统标签和简单标签的顶层是JspTag,它扩展出Tag和SimpleTag两个体系。

Tag:doStartTag、doEndTag

如果不处理体,就把体直接输出到out内置对象上;如果处理体(返回的必须是EVAL_BODY_BUFFERED)
,先调用pushBody,然后得到的out就不是内置对象了,而是bodyContent!

标签如果要处理属性的话……

SimpleTag:doTag
jspFragment的invoke方法,这里还有个StringWriter的东西(见以前的笔记)

TagFile(标签文件)

EL表达式中函数的声明问题、国际化问题、核心标签库问题

数据库表首先支持gbk、然后数据库驱动也要支持gbk、然后才是服务器端和客户端的支持gbk编码。
------------------------------------------

晚上是王勇讲WebServices:
SOAP、WSDL、UDDI等

Simple Object Access Protocal:是轻量级协议,用于在分散型、
分布式环境中交换结构化信息。SOAP利用XML技术定义一种可以扩展的消息处理框架。

SOAP消息结构:

WebServices 是指由企业发布的完成其特别商务需求的在线应用服务。

WebServices协议栈:基于传输层。

面向商务、消费者、设备、系统

WSDL(Web Service Description Language)是在这种
.com时代需要一种解决方案来描述它所提供的服务

UDDI(Universal Description Discovery and Integration)
它的核心组件是UDDI商业注册,使用一个XML文档来描述企业以及其提供的WebService。
商业注册提供的信息包括黄页、白页、绿页三部分。

白页:地址、联系方法、企业标识
黄页:基于标准分类法的行业类别。
绿页:企业提供的WebService的技术信息,可能是一些指向文件或者URL的指针。

基于Apache Axis的开发示例:

客户端采用java和delphi
服务器采用webservice发布,主要使用java

环境:java2平台、Delphi7、Tomcat、Apache Axis
解压缩Axis安装包,将webapps下的axis目录拷贝到tomcat中的webapps
里面去。

Service代码:
public class MyMath
{
 public int squared(int x)
 {
  return x * x ;
 }
}

保存代码为.jws文件(JavaWebService文件)
将这个文件拷贝到axis工程目录中去(也就是和WEB-INF同级的目录)
Axis会自动发现该文件并且部署和编译

http://localhost:8080/axis/MyMath.jws
就可以访问了

点击“Click to see the WSDL”后可以看到WSDL文件。

Java2WSDL:该工具用于将java文件转换为WSDL文件
WSDL2Java:将WSDL文件转换成Stub和skeleton相关java文件。

www.ayandy.com:    提供商地址
www.ayandy.com/Service.asmx?WSDL:   WSDL描述信息


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值