2章 配置kangaroo-egg

 

  kangaroo-egg 安装路径下的conf目录是存放配置文件的,本章将为你介绍如何对kangaroo-egg进行配置使其能够适用于不同的服务情况。

  conf目录下有一个webconfig.xml文件和一个webfile目录,我们都会加以介绍。首先来看webconfig.xml文件,kangaroo-egg所有的配置信息都保存在这个文件中,如果你要更改某个配置项则必须手动修改此文件(将来或许会提供图型化界面修改配置),如果要使修改后的配置生效还必须重新启动kangaroo-egg服务器。

webconfig.xml是一个标准的xml文件,顶层元素是<kangaroo-egg>,其中还含如下内容:

2-0-1

 

 

2.1 webconfig.xmlsystemSet元素

systemSet元素中主要用于设置kangaroo-egg服务的配置。内容如下:

2-1-1

 

 

1. systemPsw

用于设置服务器密码,因为某些对服务器的操作需要此密码(例如10.6节介绍的方法),默认的密码设置为123456,请在初次使用时更改此密码。

 

2. regionSet

用于设置服务器区域,选择不同区域服务器数据编码、信息提示、语言都会有所不同,目前只支持cn即中国大陆区域,将来会支持更多的区域。从这里就可以看出kangaroo-egg服务器从一开始就是按国际化编码的。

 

3. urlEnc
  当请求的url中出现非ASCII字符时有些浏览器和客户端程序会将这些字符进行URL编码。

  那么什么是URL编码呢?简单的说就是将非ASCII字符按某种字符集编码成只含有ASCII字符的方法。比如中文字符“小明”按UTF-8字符集进行URL编码后就会变成“%E5%B0%8F%E6%98%8E”,而按GBK字符集进行编码后就变成了“%D0%A1%C3%F7”。

 

如下面这个请求中出现中文字符“小明”:
http://127.0.0.1/run.dqm?name=
小明
中文版IE默认会按UTF-8字符集将“小明”用URL编码方式编码成%E5%B0%8F%E6%98%8E
http://127.0.0.1/run.dqm?name=%E5%B0%8F%E6%98%8E
而中文版的fireFox默认则会按GBK字符集将“小明” URL编码方式编码成“%D0%A1%C3%F7”:
http://127.0.0.1/run.dqm?name=%D0%A1%C3%F7
于是服务器方就必需将这些已经编码的数据还原,而urlEnc就是设置按哪种字符集来解码,如“%D0%A1%C3%F7”必须按GBK字符集才能还原解码为“小明”,如果按UTF-8则无法解码成功。
默认值default则表示采用regionSet所设置地区的默认编码,如cn中国大陆地区默认编码为GBK。如果不写default则必须填写明确的编码,如GBKBIG5等,例如:
<urlEnc>BIG5</urlEnc>

注意:因为使用UTF-8url解码是http规范中推荐的,所以kangaroo-egg对于所有url中出现的编码都会先采用UTF-8编码来解码,只有UTF-8解码失败才会再用urlEnc指定的编码进行解码,所以请不要在此项中设置值为UTF-8

 

4. dataEnc

用于设置数据解码时的编码(如post方法提交的数据),默认值default则表示采用regionSet所设置地区的默认编码,如cn中国大陆地区默认编码为GBK。如果不写default则必须表明明确的编码,如UTF-8GBKBIG5等,例如:<dataEnc>BIG5</dataEnc>

 

5. bufferSize

   指定服务器的缓存基数即如果服务器需要开辟一个新临时缓存的大小,其单位为K字节,如指定16则表示服务器缓存大小为16K。对于此值我们默认设置为16,但不同的操作系统及环境其最佳设置值可能有所不同。

 

6. threadPriority

  服务器在操作系统中的优先级,可以指定110级,1级最低,10级最高。对于此值我们默认设置为5,但不同的操作系统及环境其最佳设置值可能有所不同。此外因为java虚拟机的关系对于不同的操作系统此值的设定或许无效。

 

7. clearTimeoutSession

  定时清除服务器中已经过期的session(关于session请参见第8章),单位为分钟,指定值60则表示每60分钟检查及清除一次过期的session。因为session会过期,所以需要清除那些已经过期的session用以释放内存。此值如果设置很小则会频繁清除而加重服务器负担,而设置很大又会积累大量已过期的session而占用大量内存。对于此值我们默认设置为60,但不同的访问环境其最佳设置值可能有所不同。

 

8. clearDhtmlInstance

  用于设置是否需要定时清除动态文件的实例。

DQM容器很类似于JSP容器,首先将动态文件(默认扩展名.dqm)翻译成java程序文件,然后将此java文件编译成class文件,在执行class文件前服务器会先实例化class,而后将实例化完成的引用保存在DQM容器中。

这样的好处是如果用户第二次再请求此动态文件可以不用重新实例化而直接从DQM容器中取出,这样提高了效率。但是这样也存在了弊端,首先实例一直保存在系统中必定占用内存,当有太多个实例存放的话系统可能出现内存泄漏,另一个问题如果一个动态文件已经被删除但是DQM容器中对应此动态文件的实例不会自动删除,这样就会造成无用的实例占用保贵的内存资源。为此clearDhtmlInstance用于提供定时清除DQM容器中所有的动态文件实例。

如果enable属性的值为true则表示启动此功能,如果值是其他字符则表示关闭此功能。clearTime属性指定每隔多久将清除一次,单位为天,如指定值为7则表示7天清除一次所有的动态文件实例。我们默认设置开启此功能且7天清除一次,但不同的操作系统及环境其最佳设置值可能有所不同。clearTime属性仅在enable属性开启的条件下才会启作用。

 

9. saveLogs

  用于设置是否需要将访问日志记录到文件。此项共有3个属性

1.       enable属性表示是否需要将访问日志记录到文件,如果值为true则表示记录到文件,如果值是其他字符则表示不记录到文件。

2.       bufSize属性表示缓存日志大小,每当产生一条记录后服务器是不会立即将此记录输出到日志文件的,而是先放入缓存中,只有缓存日志存满时才会一次性输出至文件。本属性的单位为K字节,如指定256则表示缓存大小为256K

3.       logFileMaxSize属性用于指定保存日志文件所允许的最大容量。当日志文件超过了此属性设定的值,则系统会将日志保存在新的日志文件中(日志文件是以编号命名且递增的,保存的日志文件位于kangaroo-egglogs目录下)。本属性的单位为K字节,如指定204800则表示缓存大小为204800K200M

 

以上第23个属性必须在第1个属性开启的条件下才会起作用。当关闭日志保存到文件的功能(第一个属性值不为true),则当前的访问日志就不会写进日志缓存和保存至文件。参考10.6节介绍的方法用以查看当前缓存中的日志。

 

注意:如果bufSize的值大于logFileMaxSize的值,则保存的日志文件最大容量就以bufSize的值为准。如果logs目录下的日志文件如果太多,则有可能影响kangaroo-egg的首次启动速度,请定期清理日志文件。

 

kangaroo-egg采用通用日志格式(CLF),日志里的每条记录都对应了单一的请求-响应对,每条记录中又包括了单一的请求-响应对的信息,每个信息用“|”符号隔离。从左到右所表示的信息如下:

1.       处理本次请求的线程。

2.       处理本次请求的开始时间。

3.       发起本次请求主机的IP地址(远程主机地址)。

4.       请求内容,此内容就是HTTP请求标头的第一行,由请求方法、请求URI和协议版本组成。

5.       服务器对于请求的响应码,由三位数字组成,如200代表请求成功,503代表服务器暂时无法响应。

6.       响应内容的长度,如果是-1则表示未知,如采用chunked编码输出相应内容则就无法得知具体长度。

7.       处理本次请求的结束时间,注意这里时间是服务器处理请求结束的时间,响应内容传输的时间不算在内。

8.       身份验证的用户,如果请求的资源有密码保护则就会提示用户输入(参见2.4节的needPassword项),此时记录下用户输入的用户名,否则不记录。

 

 

2.2 webconfig.xmlconnectors元素

connectors元素中主要用于设置kangaroo-egg服务器连接的配置。内容如下:

2-2-1

 

1. coreConnectionNumber

  设置服务器核心连接池可允许的连接数,连接数增加会消耗系统资源,核心连接池是不会消亡的,即永远都保持待命状态的。

 

2. maxConnectionNumber

设置服务器可允许的最大可用连接数,此值必须大于等于核心连接池数。

如果本项的值大于核心连接池数,则大于的部分为非核心连接池可允许的连接数,如图2-2-1所示核心连接池数为40个,最大连接数为200个,则非核心连接池数为160个。那么什么是非核心连接池呢?非核心连接池中的连接会在不活动时间超过指定值时自动消亡,本项timeOut属性就是指定非核心连接最大允许的不活动时间,如果超过了这个时间则自动消亡,此属性单位为分钟,如图2-2-1所示此值为20分钟。

那么连接流程又是如何呢?如果核心连接池没有用完则首先使用,如果用完了则使用非核心连接池,比如同一时刻有42个连接,因核心连接池只能同时处理40个连接,于是留下的2个连接就会由非核心连接池处理。在使用非核心连接时如果非核心连接池中有可用的连接则直接使用,如果没有的话还要判断非核心连接池是否也达到了最大可连接数,如果没有则初始化一个新的连接用于处理请求,如果连非核心连接池的连接也用完的话则提交503错误。

如果本项的值等于核心连接池数,则表示非核心连接池将不会使用,这种情况下所有请求都会使用核心连接池中的连接,核心连接池用完的情况下则提交503错误。

非核心连接的作用就是在访问量大时提供更多的连接数,而当访问量小时自动释放多余的连接,这样可以尽可能优化系统资源。

当同一时刻可用连接数全部用完时其他用户就无法继续访问了。当客户端要向服务器获取资源时就需要建立一个连接。当今如IE浏览器这样的客户端还会并发连接,如访问一个内嵌二张图片的网页时IE就会同时建立三个个连接,一个连接用于获取网页html文件,另二个连接用于获取内嵌的二张图像,所以一个用户有可能同时占有好几个连接。而且由于持久连接的关系被占用的连接即便使用完毕后也不会立即释放(使用完毕后多久释放连接参见本节的45点),所以必须根据访问量情况设置核心连接池和最大可用连接数的值。连接数增加会消耗系统资源,一般您可以设置为200400之间。如果连接数设置的很大(比如800)有可能会造成系统内存泄漏,因为连接数需要占用资源,为了使用大连接数正常必须分配给kangaroo-egg服务器更多的内存以防止内存泄漏。还记得前面run.batrun.sh二个启动文件吗?在这二个文件中加入-Xmx参数,此参数表示kangaroo-egg可使用内存的最大数,当然这指的内存容量都是指物理内存,不能超出你的机器的物理内存的总容量。

  举一个例子,比如我将最大可用连接数设为了800,我的系统物理内存是1G,为了不发生内存泄漏将最大512M内存分配给kangaroo-egg使用,那么run.bat修改后的内容如下:

2-2-2

 

run.sh修改后的内容如下:

2-2-3

 

3. maxServerUnavailableNumber

  设置服务器可允许的最大提示503信息的连接数,当同一时刻可用连接数全部用完时(即上面maxConnectionNumber所设定的值)服务器就会返回503信息即服务器繁忙暂时不可用。不过返回503信息也需要占用资源,此值就是设定当可用连接数用完时最大同时可返回的503信息数,如果连503信息连接数都用完则服务器直接关闭请求连接。建议此值设置较小。

 

4. maxPersistentConnectionsNumber

  设置服务器可允许的最大持久连接数。前面提到过由于持久连接的关系,被占用的连接即便使用完毕也不会立即释放,这样就会造成用户已经使用完成但还是占用着连接,导致的结果就是其他用户无法访问。kangroo-egg服务器提供了二个参数解决这个问题,本参数就是其中之一,另一个参数就是下面提到的connectionTimeout参数。用户使用单一连接次数如果超过了本参数值则立即关闭连接以释放连接数。设定这个值的意义在于公平访问者获取连接,不至于一个用户获得一个连接后永远占有这个连接。本值设置的最小值为1,设置成最小值则每次访问完毕后立即关闭连接,即不提供持久连接,最大可设置为2147483647,服务器没有提供设置永久持久连接的参数,因为设置最大值几乎就等于永久连接了。

 

5. connectionTimeout

  设置服务器连接超时。本参数也是用于解决占用持久连接的问题。一个用户使用完一个连接后因为持久连接关系并不会立刻关闭连接(收回连接),此参数就是设置当没有数据传输(使用完连接)多久后便关闭连接。此参数单位为秒,如指定50则表示如使用完连接50秒后关闭连接。

 

6. HTTP

  设置http服务项。共有二个属性。

1.  enable属性表示是否启用http服务,如果值为true则表示启用http服务,如果值是其他字符则表示关闭http服务。

2.  port属性表示http服务所监听的端口(当然前提是在启用http服务的情况下),此属性值只能是165535之间的正整数,默认设置为8080

 

7. HTTPS

  设置https服务项。共有七个属性。

1.       enable属性表示是否启用https服务,如果值为true则表示启用https服务,如果值是其他字符则表示关闭https服务。

2.       port属性表示https服务所监听的端口(当然前提是在启用https服务的情况下),此属性值只能是165535之间的正整数,默认设置为8443

3.       keystoreFile属性表示启用https所用证书文件(如何生成证书请参考附录4)。

4.       keystoreType属性表示keystoreFile属性所指定的证书文件类型,用JDK配备的keytool程序生成的证书类型是jks

5.       keystorePass属性表示keystoreFile属性所指定的证书文件的存储密码。

6.       keyPass属性表示keystoreFile属性所指定证书文件的密码。

7.       needClientAuth属性表示是否需要验证客户端证书,如果值为true则表示需要验证,如果值是其他字符则表示不需要验证。

 

以上27属性必须在第1个属性开启的条件下才会起作用。

 

注意:必须至少启用httphttps中的一项。

 

 

2.3 webconfig.xmluserApps元素

userApps元素中主要用于配置需要和服务器一同启动的用户java程序,比如数据连接池程序等。因为这些程序必须随着服务器启动时一并启动(初始化),所以设置了此配置项。

 

注意:kangaroo-egg并没有内置数据库连接池,如果您需要可以采用其它第三方产品。一些数据持久化产品也内置了一些第三方数据库连接池。

 

userApps元素中可以包含一个或多个userApp元素,每个userApp元素代表着需要同服务器一同启动的java程序,而userApp元素中的标签则是用于配置本项需启动的java 程序,接下来我们来介绍userApp中的属性和各个标签:

1.       userApp本身有二个属性enablenumberenable属性表示是否启用本项,如果值为true则表示本项所配置的用户程序会随服务器启动时一并启动,如果值是其他字符则表示本项所配置的用户程序不会随服务器启动时一并启动,就相当于忽略本项。number属性是可有可无的,主要是起到注释作用,比如有多个userApp项,那么可以注释用于区分,在这里我们采用数字做注释,我们也推荐这样,因为如果userApp某些设置不合法则系统会报错,而报错信息中会含有是第几个userApp出错(最上方为1,从上到下依次增加)。

2.       className表示用户程序的启动类,必须写完整的名称即包括包路径。当服务器启动时会同时初始化此类,当然指定的类可能有多个构造函数,至于初始化此类时用哪个构造函数则以parameter标签的设置决定。

3.       parameter标签用于设置用户程序启动类构造函数的参数,比如className定义的一个类,此类有多个构造函数,其中一个构造函数有2String型的参数,则定义2parameter则就会使用这个构造函数进行初始化类,而此构造函数中2String型的参数就是已定义的2parameter的值。

4.       parameter标签还有一个属性commentcomment属性是对此parameter标签的注释,当然您可以修改为自己更能理解的注释,注释属性也是可有可无。

 

注意:className中指定类的构造函数参数必须与parameter标签一一对应,否则初始化此类时会报错。同时parameter标签只适用于向构造函数提供String型参数,如果构造函数中含有其它类型的参数则会出错,为此如需要通过parameter提供参数则构造函数的参数必须全部为String类型。

 

为了便于更好的理解,在这里我们举些例子,首先我们配制一个用于打印出服务器启动时间的程序。此程序的类名为example.StartupTime,序源代码如下:

1

2

3

4

5

6

7

8

9

public class StartupTime {

  public StartupTime(String info) {

    System.out.println(info + new java.util.Date());

  }

 

  public StartupTime() {

    System.out.println(new java.util.Date());

  }

}

 

webconfig.xml配置参数如下:

<userApps>

<userApp enable="true" number="1">

          <className>example.StartupTime</className>

          <parameter comment="prompt_info">Startup time=</parameter>

</userApp>

</userApps>

 

从上面配置来看example.StartupTime这个类会在服务器启动时初始化,而此类有二个构造函数,其中一个构造函数需要一个String类型的参数(源程序24行),而我们正好用一个parameter标签提供此参数,参数值为“Startup time=”,当启动服务器时就会看到控制台会打印出“Startup time=Fri Jan 06 16:10:04 GMT+08:00 2006”这条信息,可以看出此条信息前部分是parameter标签传入的值,而后半部分是服务器启动的时间(即服务器在启动时初始化此类的时间)。

另一个疑问是example.StartupTime还有一个无参数的构造函数用于仅打印服务器启动的时间(源程序68行),如何使用这个构造函数呢,很简单,不提供parameter参数就可以了,配置如下:

<userApps>

<userApp enable="true" number="1">

          <className>example.StartupTime</className>

</userApp>

</userApps>

当启动服务器时就会看到控制台会打印出“Fri Jan 06 16:10:04 GMT+08:00 2006”这条信息,可以看出仅仅打印出服务器启动的时间。

 

接下来再配置第二个用户程序,此程序用于每次间隔用户指定的时间后打印当前时间,很显然此程序需要用到线程,此程序类名为example. PrintTime,源程序如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

public class PrintTime implements Runnable {

  long sleepTime;

  public PrintTime(String isleepTime) {

    sleepTime = Long.parseLong(isleepTime) * 1000 * 60; //分钟

    new Thread(this, "printTime").start();

  }

 

  public void run() {

    while (true) {

      try {

        Thread.sleep(sleepTime);

        System.out.println(new java.util.Date());

      }

      catch (InterruptedException ex) {

        //此处忽略了错误

      }

    }

  }

}

 

webconfig.xml增加userApp参数,增加后的内容如下:

<userApps>

<userApp enable="true" number="1">

          <className>example.StartupTime</className>

          <parameter comment="prompt_info">Startup time=</parameter>

</userApp>

<userApp enable="true" number="2">

          <className>example. PrintTime</className>

          <parameter comment="sleepTime(minute)">10</parameter>

</userApp>

</userApps>

源程序第5行启用了一个线程来定时打印当前时间,818行就是线程运行的主体,而打印间隔的时间是由构造函数传入的值所决定的(源程序411行)。当启动服务器时不但会打印出服务器启动的时间(example.StartupTime这个类),而且还会每隔10分钟打印出当前时间,当然你可以修改打印间隔时间,只需要将parameter参数修改即可。

 

注意:用户自定义的程序,如上面2个例子,都要通过公用类的方法载入,具体请参见附录4

 

 

2.4 webconfig.xmlmainHost元素

mainHost元素中主要用于设置kangaroo-egg主机的配置。内容如下:

2-4-1

 

1. webPath

  设置服务器主机根目录。目录可以写绝对路径也可以写相对路径。

 

2. defaultHttpFile

  设置当前主机服务默认的访问的文件,即用户未输入所需要访问的文件名时系统默认打开此文件提供给客户。比如指定了默认文件为index.html,主机为myhost,则当访问http://myhost时就默认等于访问http://myhost/index.html了。

 

3. dhtmlExtName

  设置当前主机可执行动态文件扩展名。前面介绍过DQM容器可以让用户指定可执行动态文件扩展名,在这里您可以随意设置您希望的可执行动态文件扩展名,你甚至可以设置成htmlhtm,使访问者以为他们在访问一个静态的文件,默认是dqm,即以dqm为扩展名的文件都是可以执行的。稍后我们会来学习如何编写DQM容器下的动态文件。

 

注意:设置的动态文件扩展名前面不要加上点号,即.dqm是非法的。同时不区分大小写,dqmdQmDqm等都是一样的。

 

4. maxPostLen

  设置当前主机最大允许接受数据的大小。当编写可执行程序时可以从客户端接受数据,如上传文件、验证时用户输入的用户名和密码(虽然用户名和密码的数据量很小,但有些攻击会传输很大数据量的用户名和密码),这些上传的数据kangaroo-egg服务器会先将其暂放内存中,所以如果客户端上传大量数据则有可能会造成内存溢出,同时非法的攻击也可以产生类似效果,而设定服务器最大能够接受的数据量就是为了解决这些问题。当超出服务器所能接受的范围时就会直接拒绝请求且提示出错。此参数单位为K字节,如指定16则表示服务器最多能接受16K的数据量,在设置时需要根据系统内存及程序需要处理的数据量来综合考虑。

 

注意:此参数值不要设置的太大,否则会造成溢出,最大设置极限为2097150,即2GB,但通常是不会需要上传如此大的文件,即使需要但采用http协议也有很多缺陷,比如无法断点续传,解决方法是采用第三方或自己编写插件来实现。

 

5. session

  用于设置当前主机的session配置(关于session请参见第8章),共有二个属性。

1.       timeOut属性表示当前session默认的过期时间,单位为分钟,如指定20则表示过期时间为20分钟。

2.       allowedMaxNumber属性表示当前主机最大允许的session数。每个session都需要占用内存,如果session过多就会导致服务器内存溢出,而这个属性就是用于设置当前主机能够容许的最大session数,如果有新的session生成首先会检测当前已存在的session数是否已达到最大值,如果达到则清除所有已存在的session后再生成新的session。如果此属性设置为负数则表示不限制session数。此值需要根据访问人数及内存大小来制定。

 

6. listFile

设置当前主机是否允许客户端浏览目录,即列出文件列表。如果值为true则表示允许客户端浏览目录,如果值是其他字符则表示不允许。那么在什么情况下会列出文件呢?例如defaultHttpFile项指定了默认文件为index.html,主机为myhost,则当访问http://myhost时就默认等于访问http://myhost/index.html了,但是如果index.html也不存在时就会检查是否允许客户端浏览目录,如果允许则列出请求的目录下所有文件,否则提示文件未找到。

 

注意:如果设置允许客户端浏览目录,那么有可能会有安全问题,访问者能够看到所有的文件名且有可能访问它们。

 

7. needPassword

设置访问当前主机特定资源时是否需要密码。如果enable的值为true则表示访问需要密码,如果值是其他字符则表示不需要密码。如果启用访问密码则访问当前主机时浏览器会提示用户输入用户名和密码(如图2-4-2),确认后才能访问否则会提示重新确认。

2-4-2

 

本项中还有其它五项标签,分别表示:

1.       className表示服务器采用的验证密码的程序,这里默认为default即采用服务器默认的验证程序,稍后会介绍如何使用自己编写的验证程序。

2.       parameter标签且属性commenttitlecomment属性是对此标签的注释,当然您可以修改为自己更能理解的注释,注释属性也是可有可无的。从注释中就可以看出此标签是设置验证框中的标题,如图2-4-2中红框标出部分。用户可以设置成自己需要的标题。

3.       parameter标签且属性commentuserName,从注释就可看出这里是设置访问保护资源时需正确输入的用户名。

4.       parameter标签且属性commentuserPsw,从注释就可看出这里是设置访问保护资源时需正确输入的密码。

5.       parameter标签且属性commentsecurityPath,这个是用来设置需要密码保护的范围的,比如要整个网站都要有密码保护则值定义为"/",但有时我们只想对于特定的目录下资源进行密码保护,如图2-4-1中值为"/security/",则表示访问security目录下的资源都需要进行验证。

 

服务器默认的验证程序只能指定一组用户名和密码,但是这样任何人要访问当前主机的保护资源就只能使用这一组用户名和密码。那么如何实现更加复杂的验证呢?比如从数据库中查询用户名和密码。为了实现更强大的功能,kangaroo-egg可以让用户自己编写验证密码程序,从而实现用户需要的功能。

为了让用户能够使用自己编写的验证密码程序kangaroo-egg提供一个接口com.kangaroo_egg.webserver.CheckServerPSW,此接口非常简单,只有有二个方法:

 

方法一:

public String getPswTitle()

用于返回提示输入密码框时的标题,如图2-4-2中标题是mainHost(红框标出)。

 

方法二:

public boolean checkPSW(String username, String password, String requestPath, String queryData)

用于验证用户名和密码是否有效,usernamepassword是用户输入的用户名和密码,requestPath是用户当前访问资源的路径及名称,不过requestPath是未经过编码的(参见2.1节的urlEnc项)。queryData是当前用户访问url所附带的数据(即url中问号后面附带的数据),如果用户访问的url中没有附带数据则queryDatanull。而方法返回一个boolean值,如果是true则表示验证通过,如果是false则表示验证失败。

 

用户自己编写的验证程序必须继承这个接口,同时实现这二个方法,然后把className标签中的default值改成自己编写的验证程序类名,类名必须写全名。而parameter标签是初始化验证密码类的构造参数,可以根据自己编写的构造函数所含的参数增加或减少,不过构造函数的参数必须都是String类型,如果构造函数中含有其它类型的参数则会出错。而parameter标签属性comment只是用于标注当前参数的注释,这样当构造函数的参数很多时就能够清楚理解各个参数的含义。

  我们来个例子,当className值为default时其实用系统默认提供的一个验证密码类,此类名为com.kangaroo_egg.webserver.DefaultCheckServerPSW,所以直接在className中写此类名和写default是一样的,因为系统默认密码验证类名比较长所以才增加了default这个值。那么我们就来看看这个默认的密码验证类。

首先这个类肯定是继承了com.kangaroo_egg.webserver. CheckServerPSW接口。

public class DefaultCheckServerPSW implements CheckServerPSW

 

其次这个类构造函数有四个String型的参数,因为默认有四个parameter标签。

1

2

 

3

4

5

6

7

private String username, password, pswtitle, requestPath;

public DefaultCheckServerPSW(String ipswtitle, String iusername, String ipassword, String irequestPath) {

  pswtitle = ipswtitle;

  username = iusername;

  password = ipassword;

  requestPath = irequestPath;

}

 

从源代码可以看到构造函数四个参数分别是验证框的标题内容(第3行)、设定的用户名(第4行)、密码(第5行)和密码验证范围(第6行)。而从上到下的四个parameter标签的注释和值也与其吻合。

 

再来看看默认密码检验类的public String getPswTitle()方法。

1

2

3

public String getPswTitle() {

  return pswtitle;

}

 

直接返回初始化时保存下来的由第一个parameter标签传入的值(第2行)。

 

最后看看默认密码检验类的方法。

1

 

2

3

4

5

6

7

8

9

public boolean checkPSW(String iusername, String ipassword, String irequestPath, String iqueryData) {

  if (!irequestPath.startsWith(requestPath)) {

    return true;

  }

  if (iusername.equals(username) && ipassword.equals(password)) {

    return true;

  }

  return false;

}

 

首先源程序24行比较用户当前访问的范围是否需要验证,如果不需要验证则直接返回true表示通过。如果访问的范围需要验证则接下来源程序57行用于比较用户输入的用户名和密码(iusername, ipassword)与指定的合法用户名和密码(username, password)是否相等。如果相等返回true表示验证通过,否则返回false表示验证失败(源程序第8行)。本类中并没有使用到iqueryData这个参数,用户可以在需要的情况下在自己的密码检验类中使用,从而进行判断。

 

  以上可以看出自己编写的类也是如此,只要负责构造函数、public String getPswTitle()public boolean checkPSW,至于如何通过密码检验和返回的密码框标题都由用户自己在方法中实现。

 

注意:密码验证类的构造函数参数必须与parameter标签一一对应,否则初始化此类时会报错。密码验证类在第一次启动kangaroo-egg时进行初始化,而后将实例存入缓存,每次验证密码时都使用同一个实例,并不是每次检验密码时都重新初始化密码检验类,为此请注意同步问题。因为http协议的原因含有冒号的用户名会出现异常,请不要使用。用户自定义的密码验证程序,都要通过公用类的方法载入,具体请参见附录4

 

8. needCompress

设置当前主机动态资源是否需要压缩。对于动态可执行可以将其输出的内容进行压缩,这样可以节约网络流量,但是会耗用一部分cpu资源,所以必须衡量。kangaroo-egg支持多数主流的压缩格式(如gzip),能够与大多数浏览器兼容,对于不支持解压缩的浏览器kangaroo-egg会自动不压缩输出。如果此值为true则表示所有动态文件输出的内容都需要压缩,如果值是其他字符则表示无需压缩输出。

 

注意:动态可执行文件中有单独语句可以关闭或开启压缩(参见4.3节),如果动态文件中指定了压缩状态则以动态文件中指定的状态为准。

 

9. autoCompile

设置当前主机是否自动编译已经过期的动态可执行文件。前面介绍过动态可执行文件(默认扩展名.dqm)必须翻译成java程序文件,然后将此java编译成class文件后初始化放入容器中执行。但是有些情况下需要重新上面的编译过程,例如动态可执行文件修改后就必须重新编译。在开发阶段这是合理的,因为要不断修改动态文件且查看修改后结果,但是在运行阶段动态文件很少或者几乎不改变,于是就无需消耗资源监视动态文件是否改变从而重新编译。如果此值为true则表示监视动态文件是否改变且自动编译,如果值是其他字符则不自动编译动态文件。关于关闭自动编译后的流程请参见F1.3节。

 

 

2.5 webconfig.xmlvHost元素

vHost元素中主要用于设置kangaroo-egg虚拟主机的配置。可以为服务器配置多个虚拟主机,只需要依次增加vHost元素,number属性用于注释当前项是第几个虚拟主机,此注释可有可无,当然也可以修改成自己更能理解的内容,不过推荐还是用数字编号,因为如果配置项有问题服务器会按编号提示哪个虚拟主机项有问题(最上方为1,从上到下依次增加)。

 

同时vHost元素的内容与mainHost及其相似,内容如下:

2-5-1

 

从上图中可看出配置了2个虚拟主机,第2个虚拟主机项中的内容也是这些,只是值不一样,我们以第2个虚拟主机为例子,下图为第2个虚拟主机的内容图:

 

2-5-2

 

1. hostName

  这项内容是mainHost项所没有的,用于设置当前虚拟主机所对应的主机头(域名)。当然一个虚拟主机可以设置多个主机头,用“|”符号分割,如图2-5-2中主机头就设置了“www.kangaroo-egg.com”和“kangaroo-egg.com”2个。

  为了便于更清楚理解,我们来举个例子,假设我们服务器的IP地址是210.52.216.34,同时www.kangaroo-egg.com和kangaroo-egg.com这2个域名也都指向此IP地址,那么当用户通过这2个域名访问时就会访问到虚拟主机2的内容。从图2-5-1看到虚拟主机1的主机头是mybride.kangaroo-egg.com,如果此域名也是指向我们服务器的IP,那么输入此域名就会访问到虚拟主机1的内容。那么如果用户直接输入IP地址进行访问呢?因为在所有虚拟主机中无法找到对应的主机头,所以会访问2.4节所介绍的主机内容,这也就是为什么主机内容中没有hostName这一项的原因。

 

2. webPath

设置服务器当前虚拟主机根目录。目录可以写绝对路径也可以写相对路径。此项和mainHost的内容一样。

 

3. defaultHttpFile

  设置当前虚拟主机服务默认的访问的文件,其功能同mainHost的相应项。

 

4. dhtmlExtName

  设置当前虚拟主机可执行动态文件扩展名。其功能同mainHost的相应项。

 

5. maxPostLen

  设置当前虚拟主机最大允许接受数据的大小。其功能同mainHost的相应项。

 

6. session

  用于设置当前虚拟主机的session配置。其功能同mainHost的相应项。

 

7. listFile

  设置当前虚拟主机是否允许客户端浏览目录,即列出文件列表。其功能同mainHost的相应项。

 

8. needPassword

  设置当前虚拟主机访问时是否需要密码。其功能同mainHost的相应项。

 

9. needCompress

  设置当前虚拟主机动态资源是否需要压缩。其功能同mainHost的相应项。

 

10. autoCompile

  设置当前虚拟主机是否自动编译已经过期的动态可执行文件。其功能同mainHost的相应项。

 

 

2.6 webfile目录

前面提到过conf目录下还有一个webfile目录,这个目录主要是存放http的错误信息,比如用户访问了一个不存在的文件那么服务器就会从这个目录下寻找代表相应错误的文件返回,用户可以用自定义的文件覆盖默认的文件,不过这些文件名必须符合一定的规范。首先文件扩展名必须是html,主文件名必须以下划线加上区域名,例如区域为中国大陆地区(区域设置参见2.1节)则主文件名都以_cn结尾。