随笔-159  评论-114  文章-7  trackbacks-0
 
Atomic Consistent  Isolated  Durable

An atomic database transaction is one which is guaranteed to complete successfully or not at all. If an error prevents a partially-performed transaction from proceeding to completion, it must be "backed out" to prevent the database being left in an inconsistent state.

ACID is an acronym used to describe the properties that a transaction should have in an enterprise environment. A transaction should be Atomic, and its results should be Consistent, Isolated, and Durable. A transaction is Atomic if it either completes itself or is completely undone. The results of a transaction should consistently change the system from one state to another, be isolated or independent of one another, and, once completed, be durable or permanent.

什么是事务

   事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。

   
   事务的结束有两种,当事务中的所以步骤全部成功执行时,事务提交。如果其中一个步骤失败,将发生回滚操作,撤消撤消之前到事务开始时的所以操作。



事务的ACID

事务具有四个特征:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持续性(Durability)。这四个特性简称为ACID特性。


    

1、原子性

    事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做

2、一致性

     事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是不一致的状态。 

3、隔离性

    一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。

4、持续性

   也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。

事务的属性

   

一个事务的属性控制了事务的使用范围。EJBSpring以及.net下的事务属性都很类似的,事务属性有如下几种:


   Required:
      如果在一个事务中调用,就把该方法加到此事务中来,如果还没有启动事务,就启动一个新事务。

   RequiredNew:
不管当前有没有事务,都会启动一个新事务,如果当前有事务,会被挂起直到方法结束。

NotSupported:
不能在事务中执行此方法。如果有事务,将会被挂起直到方法结束。

Supports:
如果当前有事务,此方法会加到当前事务,如果没有,容器也不会启动新事务。

Mandatory:
必须在事务中调用此方法,否则抛出异常。

Never:
必须不在事务中调用此方法,否则抛出异常。


三.事务的回滚

CMT在以下两中情况下,事务将回滚。第一,如果产生一个系统异常,容器将自动回滚该事务。第二,通过调用EJBContext接口SetRollbackOnly方法,Bean方法通知容器回滚该事务。如果Bean抛出一个应用异常,事务将不会自动回滚,但可以调用SetRollbackOnly回滚。

五.隔离级别

事务不仅保证事务界限内的数据库操作全部完成(或回滚)同时还隔离数据库更新语句。隔离级别描述被修改的数据对其他事物的可见度。隔离级别的控制会跟具体的DBMS厂商不同而不同。

     隔离级别与并发性是互为矛盾的:隔离程度越高,数据库的并发性越差;隔离程度越低,数据库的并发性越好。

通过一些现象,可以反映出隔离级别的效果。这些现象有:

l         更新丢失(lost update):当系统允许两个事务同时更新同一数据是,发生更新丢失。

l         脏读(dirty read):当一个事务读取另一个事务尚未提交的修改时,产生脏读。

l         非重复读(nonrepeatable read):同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生非重复读。

l         幻像读(phantom read):同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻像读。

 

SQL-99 标准定义了下列隔离级别:

l         未提交读(read uncommitted)(隔离事务的最低级别,只能保证不读取物理上损坏的数据)

l         已提交读(read committed)(数据库引擎 的默认级别)当一个事务运行在这个隔离级别时,一个 SELECT 查询只能看到查询开始之前提交的数据,而永远无法看到未提交的数据,或者是在查询执行时其他并行的事务提交做的改变。

l         可重复读(repeatable read),不会脏读和非重复读,可能发生幻像读

l         可序列化(serializable)(隔离事务的最高级别,事务之间完全隔离)

posted @ 2006-03-28 23:30 北国狼人的BloG 阅读(314) | 评论 (0)编辑 收藏
启动Weblogic服务器,由于JMS,需要一个消息中间件,Tuxedo。本文使用的是WebLogic 9.1,与8.1的有所不同。

登录

logon.jpg

创建JMS servers

server.jpg


设置完JMS服务器以后,要设置JMS的Modules,以便JMS客户端和接受端能查找相应的JMSFactory和JMSdestination。

module.jpg


C:\bea\user_projects\domains\base_domain\config\jms

会出现配置相关的配置文件

建立两个资源

一个是ConnectionFactory,配置一个JNDI。

另外一个是Queue-0,配置一个JNDI。

resource.jpg

import javax.jms.*;
import java.util.Hashtable;
import javax.naming.*;
import java.io.*;

public class QueueSend
{
    
    
public static void main(String[] args) throws Exception
    
{
        Hashtable hash 
= new Hashtable();
        hash.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
        hash.put(Context.PROVIDER_URL,
"t3://localhost:7001");
        
        InitialContext ic 
= new InitialContext(hash);
        
        
//找工厂
        QueueConnectionFactory factory = (QueueConnectionFactory)ic.lookup("jms/factory");
        
        System.out.println(factory.getClass());
        
        
        
//找文件夹,也就是目的地
        Queue queue = (Queue)ic.lookup("queue");
        
        System.out.println(queue.getClass());
        
        
        
//查API,接口有什么方法阿        
        QueueConnection conn = (QueueConnection)factory.createQueueConnection();
        
        
        
//消息的接受者,是否给消息中间件回复,否则重复发送。第二参数使用自动确认
        QueueSession session = conn.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
        
        
//根据目的地,确定发送者
        QueueSender sender = session.createSender(queue);
        
        
        
//Message的创建要使用Session
        
        BufferedReader buffer 
= new BufferedReader(new InputStreamReader(System.in));
        
        
while(true)
        
{
            String line 
= buffer.readLine();
            
if(line.equals("quit"))
            
{
                TextMessage message 
= session.createTextMessage("over");
                sender.send(message);         
                
break;                
            }

            TextMessage message 
= session.createTextMessage(line);
            sender.send(message);         
        }

        
              
        
    }



}


察看一下Queue资源,就能看到自己发送的TextMessage。

下回分解MDB。
posted @ 2006-03-25 21:34 北国狼人的BloG 阅读(398) | 评论 (0)编辑 收藏
为了解决RMI无法解决的分布式事务控制,安全,并发等问题。

EJB解决访问就是一种可以高校的开发分布式应用的解决方案。

编写EJB,其实只需要编写2个接口和一个Bean类,和一个部属描述就可以了。

服务接口:

import javax.ejb.*;
import java.rmi.*;
//business   remote
public interface Compute extends EJBObject{
    
public double add(double a,double b) throws RemoteException;
}


Home接口:

import javax.ejb.*;
import java.rmi.*;

public interface ComputeHome extends EJBHome{
    
public Compute create() throws RemoteException,CreateException;
}

Bean,业务逻辑实现的地方

import javax.ejb.*;

public class ComputeBean implements SessionBean
{
    
public void setSessionContext(SessionContext ctx)
                       
throws EJBException,
                              java.rmi.RemoteException
{
    }

    
public void ejbRemove()
               
throws EJBException,
                      java.rmi.RemoteException
{
    }

    
public void ejbActivate()
                 
throws EJBException,
                        java.rmi.RemoteException
{
    }

    
public void ejbPassivate()
                  
throws EJBException,
                         java.rmi.RemoteException
{
    }

    
public void ejbCreate() throws CreateException{
    }

    
public double add(double a,double b){
        
return a*b;
    }

}


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
    
<enterprise-beans>
        
<session>
            
<display-name>Compute</display-name>
            
<ejb-name>abc</ejb-name>

            
<home>ComputeHome</home>
            
<remote>Compute</remote>
            
<ejb-class>ComputeBean</ejb-class>

            
<session-type>Stateless</session-type>
            
<transaction-type>Container</transaction-type>     
        
</session>
    
</enterprise-beans>
    
<assembly-descriptor>
        
<container-transaction>
            
<method>
                
<ejb-name>abc</ejb-name>
                
<method-name>*</method-name>
            
</method>
            
<trans-attribute>Required</trans-attribute>
        
</container-transaction>
        
    
</assembly-descriptor>
</ejb-jar>

JNDI的实现各个服务器的实现不同,所以需要依赖于服务器的一个xml。

JNDI也是一种面向接口编程,工厂模式的典范。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE weblogic-ejb-jar PUBLIC '-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN' 'http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd'>
<weblogic-ejb-jar>
    
<weblogic-enterprise-bean>
        
<ejb-name>abc</ejb-name>        
        
<jndi-name>efg</jndi-name>
    
</weblogic-enterprise-bean>
</weblogic-ejb-jar>


想编译EJB,需要j2ee jar,那就用\bea\weblogic81\server\lib\weblogic.jar

做一个META-INF放置两个xml文件

jar -cvf Compute.jar *.class META-INF/*.xml

c创建,v看到它创建的过程,f文件名



部属EJB,看看Weblogic帮助吧。

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

那么会发现jar文件中并没有出现_stub或者_skeleton文件阿,那是因为由容器在运行EJB时动态创建在容器内部了。

那么怎么才能看到呢?我们要分析阿。

java weblogic.appc ejb.jar

如果抱错,在classpath中添加\jdk142_04\lib\tools.jar

如果想看原文件的话,就是-keepgenerated

rmi2.jpg

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

开始分析EJB工作原理

看下面一张图,就清楚了,实际就是两次RMI 调用。

27229257.ejb2.jpg

要细致来说。

基本是这样的。

定义Home接口,主要是为让客户端有可能在创建EJB Bean对象时,给予初始化。

import javax.ejb.*;
import java.rmi.*;

public interface ComputeHome extends EJBHome{
    
public Compute create() throws RemoteException,CreateException;
}


这只是一个接口,weblogic.appc会生成一个HomeImpl,并生成Stub和Skeleton对象。在客户端JNDI查找时,返回就是这个HomeImpl的Stub对象,注意类文件也会动态下载的。

create()与ejbcreate()方法是对应的。

可有参数。

//Bean

   
public void ejbCreate(String param) throws CreateException {
        
// TODO Auto-generated method stub
        this.userName = param;
    }



//Home

public com.infogo.interfaces.Shopping create(java.lang.String param)
      
throws javax.ejb.CreateException,java.rmi.RemoteException;

===========

那么客户端实际调用的是HomeImpl的Stub对象的方法,通过网络传送到服务器上的Skeleton,Skeleton再调用真正的HomeImpl对象的方法,创建一个创建Bean对象放入实例池,Impl调用Bean的ejbcreate方法,初始化参数。

并且HomeImpl,还要创建一个业务业务接口的实现类,并把业务接口实现类(EOImpl)对象的Stub返回给客户端。

客户端拿到Stub,调用响应服务方法(别忘了,真正的服务方法实现可是在Bean类里),所以调用Stub方法,通过网络传递EOImpl的Skeleton对象,然后调用EOImpl的响应方法。

这是注意,EOImpl被称为请求拦截器,因为它会在这时察看ejb-jar.xml,看一看方法声明的事务类型,并调用容器提供的API(安全、事务等)。所以这种服务器或者容器叫做隐式容器,它有工具生成的类来调用容器相关API。而不是用户直接调用。

在EOImpl调用完容器API之后,就会调用Bean的业务方法。

最后将接口-Skeleton-Stub-客户端。

所以是两次RMI调用。

这就是EJB工作原理。

import javax.naming.*;
import java.util.*;
import javax.rmi.*;


public class Client
{
    
public static void main(String[] args) throws Exception
    
{
        Hashtable hash 
= new Hashtable();
        hash.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
        hash.put(Context.PROVIDER_URL,
"t3://localhost:7001");
        InitialContext ic 
= new InitialContext(hash);
        
        ComputeHome home 
= (ComputeHome)ic.lookup("efg");
        
        
//(ComputeHome)ProtableRemoteObject.narrow(ic.lookup("efg"),ComputeHome.class);
       /*
        * 客户端从服务器获得HomeImpl_stub .class文件,并获得HomeImpl_stub的对象
        * 
        * home.create()-->HomeImpl_stub.create()-->网络发送-->HomeImpl_skel.create()-->HomeImpl创建ComputeBean对象-->ComputeBean.ejbcreate()&&HomeImpl还要创建EOImpl_stub对象,返回HomeImpl_skel--->[网络往回传输]--->HomeImpl_stub--->客户端拿到EOImpl_stub对象。
        *
        * 这时完成了第一次rmi
        *
        * c获得了EOImpl_Stub对象,
        * 
        * c.add(32,32)----> EOImpl_Stub.add()--->网络发送--->EOImpl_Skel.add()--->EOImpl--->[根据xml描述的事务,进行事务描述]--->判断add方法是否开始事务--->调用创建好Bean对象的add方法---->方法结果给EOImpl_Skel---->网络往回传输---->EOImpl_Stub----客户端拿到结果。
        *
        * 第二次rmi完成。
        
*/

        
        
        
        Compute c 
= home.create();
        System.out.println(c.add(
32,32));
        
    }
   
}
posted @ 2006-03-19 23:45 北国狼人的BloG 阅读(952) | 评论 (0)编辑 收藏
简单来说,要实现A机器上JVM上运行的Java程序,远程调用B机器上JVM上的Java程序,计算完毕,返回给A机器。

在没有RMI的情况下,我们使用普通的网络传输技术能完成么?当然,两种选择,Socket直接通讯,将参数传给B,B在通过Socket返还给调用者。或者通过Servlet也可以远程调用阿。

那么这样解决问题时没有问题,但对于A和B来说,代码量、程序复用程序、维护性都不会太理想。

如果能让调用者不知道网络操作,实现对于用户透明,也就是像调用本地一样,对象名.方法名。

那么就是RMI规范涉及到一些接口。

面向接口的编程方式,就可以达到代码的实现与声明分离。

这样用户就只关心接口了。很多细节让遵守规范(也就是一些编写好的工具)的实现类去完成吧。[就是Stub和Skeleton]

那么就先定一个用户A要知道怎么用,B要知道方法签名完成实现,的同一接口吧。

import java.rmi.*;

public interface Compute extends Remote{
    
    
public double add(double a,double b) throws RemoteException;
    
}

两点要求

1,继承标记接口Remote。

identify interfaces whose methods may be invoked from a non-local virtual machine.

标识该接口可以被非本地VM调用呗。

2,里面每个方法都要抛出RemoteException


业务接口的实现类,也就是做实事的类

import java.rmi.server.*;
import java.rmi.*;

public class ComputeImpl extends UnicastRemoteObject implements Compute
{
    
//要在构造方法抛出异常
    public ComputeImpl() throws RemoteException{}
    
    
public double add(double a,double b){
        
return a+b;
    }

}


=====================
javac *.class

rmic -keep ComputeImpl
带参数,可以保留Stub和Skeleton源码。

通过ComputeImpl的实现类来生成负责通讯的Stub(存根)和Skeleton(框架)

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

那么就是要把这个对象绑定到一个端口上。

以便别人来使用

编写一个Server

import java.rmi.*;

public class Server
{

    
public static void main(String[] args) throws Exception
    
{
        ComputeImpl c 
= new ComputeImpl();
        Naming.bind(
"rmi://localhost:8888/compute",c);//compute别名
    }


}

客户端

import java.rmi.*;

public class Client
{
    
public static void main(String[] args) throws Exception
    
{
        Compute c 
= (Compute)Naming.lookup("rmi://localhost:8888/compute");//rmiregistry首先响应
        
//实际c是Stub对象
        System.out.println(c.getClass());
        System.out.println(c.add(
12.3,34));
    }
   
}


 看到没有,客户端通过rmi协议到服务器上寻找/compute资源对象。那个Naming是RMI专用,不是JNDI。

那么Server类并没有负责监听阿。

哦,最后有一个强大的工具在JAVA_HOME/bin/下,叫做rmiregistry,专门负责监听固定端口上,rmi协议的请求。

=================
rmiregistry 8888

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

启动Server,绑定远程对象阿

java Server

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

启动一个Client,调用一下

java Client

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

rmi.jpg

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

另外一些小问题

由于rmiregistry 工具的不断强大,jdk1.4已经可以不再使用skeleton,到1.5,根本就不生成skeleton了。

rmiregistry可以充当skeleton角色完成功能。

记住EJB中,还不行,因为没有rmiregistry工具了。呵呵,明白了?

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

所以什么呢,RMI就是一种代理模式的应用Stub,就是实际实现类的客户代理。

但需要统一的接口,才能对于用户、调用者透明啊!

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


我说的比较通俗。还有很多深刻的东西。
posted @ 2006-03-19 22:42 北国狼人的BloG 阅读(1324) | 评论 (0)编辑 收藏
     摘要: public   class  ValidatorPlugIn     implements  PlugIn {.     public  String getPathnames()     ...  阅读全文
posted @ 2006-03-12 18:14 北国狼人的BloG 阅读(1525) | 评论 (1)编辑 收藏

^

输入或行的起始部分。

^T 匹配"This good earth"中的"T",但与"Uncle Tom's Cabin"中的"T"不匹配

$

输入或行的结尾部分。

h$ 匹配"teach"中的"h",但与"teacher"中的"h"不匹配

*

0 个或多个前置字符。

um* 匹配"rum"中的"um"、"yummy"中的"umm"和"huge"中的"u"

+

1 个或多个前置字符。

um+ 匹配"rum"中的"um"和"yummy"中的"umm",但在"huge"中没有任何匹配项

?

前置字符最多出现一次(即,指示前置字符是可选的)。

st?on 匹配"Johnson"中的"son"和"Johnston"中的"ston",但在"Appleton"或"tension"中没有任何匹配项

.

除换行符外的任何单字符。

.an 匹配短语"bran muffins can be tasty"中的"ran"和"can"

x|y

x 或 y。

FF0000|0000FF 匹配 bgcolor="#FF0000" 中的"FF0000"和 font color="#0000FF" 中的"0000FF"

{n}

恰好 n 个前置字符。

o{2} 匹配"loom"中的"oo"和"mooooo"中前两个"o",但在"money"中没有任何匹配项

{n,m}

至少 n 个、至多 m 个前置字符。

F{2,4} 匹配"#FF0000"中的"FF"和"#FFFFFF"中的前四个"F"

[abc]

用括号括起来的字符中的任何一个字符。用连字符指定某一范围的字符(例如,[a-f] 等效于 [abcdef])。

[e-g] 匹配"bed"中的"e"、"folly"中的"f"和"guard"中的"g"

[^abc]

未在括号中括起来的任何字符。用连字符指定某一范围的字符(例如,[^a-f] 等效于[^abcdef])。

[^aeiou] 最初匹配"orange"中的"r"、"book"中的"b"和"eek!"中的"k"

\b

词边界(例如空格或回车符)。

\bb 匹配"book"中的"b",但在"goober"或"snob"中没有任何匹配项

\B

词边界之外的任何内容。

\Bb 匹配"goober"中的"b",但在"book"中没有任何匹配项

\d

任何数字字符。等效于 [0-9]。

\d 匹配"C3PO"中的"3"和"apartment 2G"中的"2"

\D

任何非数字字符。等效于 [^0-9]。

\D 匹配"900S"中的"S"和"Q45"中的"Q"

\f

换页符。

 

\n

换行符。

 

\r

回车符。

 

\s

任何单个空白字符,包括空格、制表符、换页符或换行符。

\sbook 匹配"blue book"中的"book",但在"notebook"中没有任何匹配项

\S

任何单个非空白字符。

\Sbook 匹配"notebook"中的"book",但在"blue book"中没有任何匹配项

\t

制表符。

 

\w

任何字母数字字符,包括下划线。等效于 [A-Za-z0-9_]。

b\w* 匹配"the barking dog"中的"barking"和"the big black dog"中的"big"和"black"

\W

任何非字母数字字符。等效于 [^A-Za-z0-9_]。

\W 匹配"Jake&Mattie"中的"&"和"100%"中的"%"


<script>
    
    function testfn(str)
    
{
        var ex 
= "^\\w+$";
        var re 
= new RegExp(ex,"i");
        alert(re.test(str));
    }

</script>

<script>
testfn(
"dfda");
testfn(
"123");
testfn(
",");
testfn(
".");
testfn(
"123.3");
</script>

自己试验一下

实际应用,Email验证
<script>
    function testmail(str)
    
{
        var ex 
= "^\\w+@[\\w]+\\.+[a-z]{2,3}$";
        var re 
= new RegExp(ex,"i");
        alert(re.test(str));   
    }

</script>

<script>
testmail(
"aacom@fda.com");
</script>

注意.的转义处理,因为.本身在正则表达式中有含义,代表非换行的单个字符

而我们想要的是.的实际标点


<script>
    function spliturl(str)
    
{
        var ex 
= "\\w{3}\.\\w+\.\\w{2,3}\\.\\w{2,3}";
        var re 
= new RegExp(ex);
        var arr 
= re.exec(str);
        alert(arr[
0]);
    }

</script>

<script>
spliturl(
"www.itnow.com.cn");
</script>


 

<script>
    function spliturl(str)
    
{
        var ex 
= "(\\w{3})\.(\\w+)\.(\\w{2,3})\\.(\\w{2,3})";
        var re 
= new RegExp(ex);
        var arr 
= re.exec(str);
        alert(arr);
        alert(RegExp.$
1);
        alert(RegExp.$
2);
    }

</script>

<script>
spliturl(
"www.itnow.com.cn");
</script>


加了小括号就是定义了一个变量,可以使用,js中保存在RegExg.$1 ---- RegExg.$9中
posted @ 2006-03-11 13:23 北国狼人的BloG 阅读(260) | 评论 (0)编辑 收藏
准备使用IBM收购Rational以后的最新产品RSA 6.0,作为开发建模工具。

人写程序与类在打交道,而在程序运行时,是对象在运行。

人写的是类型,而动态的是对象,使机器在运行代码。

OO是一种系统建模的技术,是一个过程!

对对象进行描述。

在这个过程中,要使用UML语言进行类型的描述。

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

比如模拟达内,可以说有很多老师对象和学生对象,但在达内,关注学生这个个体什么呢?只关心姓名,性别,背景,而绝对不关心它的婚姻情况。

可以对这些对象进行共性的提取,变为老师类型和学生类型。而运行时就是一个个有特性的实例。

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

什么是对象,就是一个属性确定的实体。比如找对象,这个对象在你心中早就有特定的要求,那么这样的一个对象肯定是有确定属性的对象。是单个的,唯一的,识别的实体。

那么由于成员变量的值不同,方法调用的结果不同。

所以对象是构建系统的基石。
它包括:<1>标识也就是引用名
             <2>数据
             <3>方法

什么是Class,它是对对象的定义。对于在某一个环境下的对于对象关心属性的提取和抽象。

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

面向对象编程的特点

1抽象,就是一个提炼过程
2封装,隐藏细节(属性和私有方法)
3继承,上下层次
4多态
--------------------------------------------
5,关联,对象的依赖程度
6,聚合
7,组合
8,内聚&耦合

1,抽象的目的,主要是隐藏细节,可以简化信息,看到显著特征。
2,封装的目的,隐藏数据和行为,
      
                  注意,类有两个视图,对外视图(别人使用此类,不关心实现)
                                                         内视图(自己拿着代码,要知道实现)

3,关联
            一个类型使用其他类型对象的服务。
4,聚合
            一种强关联,一个是另外一个的组成部分,而不是必要部分。
            一个汽车和一个音响。
5,组合
            一个对象包含另外一个对象
            一个是另外一个组成部分
            大的东西决定着组成部分的生命周期

6,继承,是一种实现代码复用的手段,语言的特性。另外一种代码复用的方式就是组合。

      减少代码量,维护方便。


组件的开发

在开发过程中,要遵循高内聚,低耦合的规律。

组件内部要相互的调用,来统一对外实现一个功能,而外界为实现这个功能,基本不需要再做什么,那么这个组件的重用性,就愈高。依赖于别人的越少,那么组件的复用价值也就愈高。


多态

有统一的接口,而行为有它的子类型的行为确定。

运行时多态,就是子类型重写了父类型virtual方法。

能使用编译时多态就是用编译时多态。

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

所以可以将上面的几个特点按类别分类,比如,单个类型、类型之间、层次结构、编程规则。





posted @ 2006-02-28 23:57 北国狼人的BloG 阅读(541) | 评论 (1)编辑 收藏
     摘要: 在继承于HttpServlet,进行实际的HTTP开发中,可以获得很多来自父类功能的封装。来自于GenericServlet的部分函数getInitParameter(java.lang.String name)相当于ServletConfig.getInitParameter(String name)。public ServletConfig getServletConfig()拿到S...  阅读全文
posted @ 2006-02-25 22:11 北国狼人的BloG 阅读(244) | 评论 (0)编辑 收藏
     摘要: 容器就是负责运行和销毁servlet的一组类的程序,一组代码的运行环境。为了开发方便,可以从javax.servlet.GenericServlet 继承实现主要业务方法。注意几点,1.有一个无参数的init()方法,是GenericServlet实现的,它不是Servlet接口中的方法,所以不会由容器调用,而是因为GenericServlet本身已经覆盖了带参数的init方法,并且在方法的最后调...  阅读全文
posted @ 2006-02-11 12:10 北国狼人的BloG 阅读(432) | 评论 (0)编辑 收藏

javax.servlet
Interface Servlet

是规范的接口,为了深入了解Servlet原理,要实际开发一个实现该接口的类,来作为第一个Servlet。

public void init(ServletConfig config)
          throws ServletException

这个方法,是由容器在实例化一个Servlet实例后,确切会调用该方法一次。通过判断是否抛出异常来确认Servlet是否被正确初始化。

public void service(ServletRequest req,
                    ServletResponse res)
             throws ServletException,
                    java.io.IOException

这个方法,是我们实现业务逻辑的方法,req和res就是由Web服务器对于请求和相应的有效封装。

没有什么神秘的,java网络编程中,ServerSocket的accept方法返回之后,会获得相应的一个Socket对象,通过该对象可以进而获得对应客户端的输入流和输出流。在对其进行封装就进而到Request和Response对象。

传入service方法,req可以获得请求的头部信息,res.getWriter,获得一个输出,进行输出信息,作为真正响应。

public void destroy()

 This method is only called once all threads within the servlet's service method have exited or after a timeout period has passed.

只有在service方法运行完,或者一个timeout后,会被调用。

After the servlet container calls this method, it will not call the service method again on this servlet.

一旦调用它,就不会再提供服务。

public ServletConfig getServletConfig()

返回传入init方法的那个ServletConfig,也就是服务器的ServletConfig。这个方法主要为了其他实例来使用ServletConfig实例。

public java.lang.String getServletInfo()

好比普通的toString()方法,返回注册信息。


编译注意事项:

要在环境变量的classpath中将servlet-api.jar的路径加上,这样编译才能通过。

所以最好先准备好tomcat服务器,以便利用它内置的jar文件。

D:\jakarta-tomcat-5.0.19\common\lib\servlet-api.jar

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

编译好后,是一个带包结构的.class文件目录层次。

如何部署呢?

很简单,在D:\jakarta-tomcat-5.0.19\webapps中建立一个自己的应用文件夹,例如:imshark

这时就可以将静态网页放入该文件夹了,然后要按照java web 应用的规范,建立一个WEB-INF的文件夹,然后里面放置一个标准的web.xml文件,就可以访问了。

web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version
="2.4">
    

</web-app>


然后部署servlet,在WEB-INF文件夹中,建立一个classes的目录,然后,将带目录结构的.class文件放入该文件夹,然后修改web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version
="2.4">
    
     
<servlet>
        
<servlet-name>TimeServlet</servlet-name>
        
<servlet-class>imshark.servlet.basic.TimeServlet</servlet-class>
    
</servlet>
    
     
<servlet-mapping>
        
<servlet-name>TimeServlet</servlet-name>
        
<url-pattern>/getTime.jsp</url-pattern>
    
</servlet-mapping>

</web-app>

1.gif

http://localhost:8080/imshark/getTime.jsp

所以可看出getTime.jsp是一个虚拟的路径地址,并不实际存在,完全有web.xml构造的。

以上就是最基本的Servlet的知识点。

posted @ 2006-02-09 00:01 北国狼人的BloG 阅读(1720) | 评论 (0)编辑 收藏
仅列出标题
共17页: First 上一页 7 8 9 10 11 12 13 14 15 下一页 Last