Commons-Beanutils包
(作者置顶)
ANT之文件操作
ANT之文件操作
在本文中,我们将考察如何执行常见文件操作,比如创建目录和解压缩文件。 Ant 的优秀特性之一在于,执行这些操作的任务一般在所有平台上都是相同的。
创建和删除目录
最基本的文件系统操作之一就是创建目录或文件夹。做这项工作的任务名为 mkdir,毫不奇怪,它非常类似于具有相同名称的 Windows 和 UNIX/Linux 命令。
首先要注意 / 被用作目录分隔符,这是 UNIX 和 Linux 的惯例。您可能认为这不是很平台无关的,但是 Ant 知道如何处理它,并针对它运行所在的平台做恰当的事情,这与我们在前面定义基于位置的属性时所看到的方式相同。我们能够同样容易地使用 \,而不管平台是什么 ?? Ant 能够处理任一种形式,甚至能够处理两种形式的混合。
mkdir 任务的另一个有用特性是它的如下能力:在父目录还不存在时创建它们。考虑一下上面的清单,设想 archive 目录存在,但是 metals 目录不存在。如果使用底层平台的 mkdir 命令,您需要首先显式地创建 metals 目录,然后第二次调用 mkdir 命令来创建 zinc 目录。但是 Ant 任务比这更加智能,它能够一次性创建这两个目录。类似地,如果目标目录已经存在,mkdir 任务不会发出错误消息,而只是假设它的工作已经完成,从而什么也不做。
删除目录同样也很容易:
这将删除指定的目录连同它包含的所有文件以及子目录。使用 file 属性而不是 dir 属性可以指定要删除的单个文件。
复制和移动文件及目录
在 Ant 中制作文件的一份拷贝很简单。例如:
您还可以使用 move 来执行重命名操作而不是拷贝文件:
另一个常用的文件系统操作是将文件复制或移动到另一个目录。做这项工作的 Ant 语法同样也很简单:
默认情况下,Ant 仅输出它执行的移动和复制操作的摘要,包括诸如已移动或复制的文件的数量等信息。如果想看到更详细的信息,包括涉及的文件名称等,您可以将 verbose 属性设置为true。
创建和解压缩 zip 及 tar 文件
在前一节中,我们看到了如何创建 JAR 文件。创建其他归档文件的过程几乎完全相同。下面是创建zip 文件的 Ant 任务:
相同的语法也可用于创建 tar 文件。 还可以使用 GZip 和 BZip 任务来压缩文件。例如:
解压缩和提取文件同样也很简单:
还可以包括 overwrite 属性来控制覆盖行为。默认设置是覆盖与正在被提取的归档文件中的条目相匹配的所有现有文件。相关的任务名称是 untar、unjar、gunzip 和 bunzip2。
替换文件中的标记
我们将在本节考察的最后一个文件系统操作是 replace 任务,它执行文件中的查找和替换操作。token 属性指定要查找的字符串,value 属性指定一个新的字符串,查找到的标记字符串的所有实例都被替换为这个新的字符串。例如:
替换操作将在文件本身之内的适当位置进行。为了提供更详细的输出,可把 summary 属性设置为true。这将导致该任务输出找到和替换的标记字符串实例的数目。
C编程问题精粹
UnixC编程问题精粹
对于c语言,有人认为它已经落伍了.对于这个问题,仁者见仕,智者见智.的确,c++比c有更强大的诸多优势.但c++是建立在c之上的.这也是herbert schildt所著的<>在全世界畅销不衰的原因.更何况,要深入学习linux就必需要有相当的c功底.(这也是我搜集整理本文的根由:-)
现结合个人在编程中的体会,为使新手少走弯路,为老手锦上添花,因此无论你是使用c或c++编程,也无论你是程序设计的初学者还是成熟的专业人员,均会发现,本文将会对你有所收益.当然,我尽力写得清晰易懂,又不古板.
我爱c.(正如世人爱上帝一样:-)..
第一章:前言
对于c语言,有人认为它已经落伍了.对于这个问题,仁者见仕,智者见智.的确,c++比c有更强大的诸多优势.但c++是建立在c之上的.这也是herbert schildt所著的<>在全世界畅销不衰的原因.更何况,要深入学习linux就必需要有相当的c功底.(这也是我搜集整理本文的根由:-)
现结合个人在编程中的体会,为使新手少走弯路,为老手锦上添花,因此无论你是使用c或c++编程,也无论你是程序设计的初学者还是成熟的专业人员,均会发现,本文将会对你有所收益.当然,我尽力写得清晰易懂,又不古板.
我爱c.(正如世人爱上帝一样:-)..
你可以在forum.linuxaid.com.cn上获得此帖的文本.而其html版本正在赶制之中......
第二章:约定
专业的源程书写风格.
先看看世界级c大师的源程书写风格.如 steve maguire 就有许多不错的建议.
[]倡导使用易于理解的"匈牙利式"的命名约定.
所有的字符变量均以ch开始; 如: char ch_****;
所有的字节变量均冠以b; 如: byte b_****;
所有的长字变量均冠以l; 如: long l_****;
所有的指针变量均冠以p; 如: char *p_ch_****;
建议类型派生出的基本名字之后加上一个以大写字母开头的"标签".如:
分析 char **ppchmydata;
其让人一眼就能看出它****一个指向字符指针mydata的指针.
"匈牙利式"命名的最大不足是难念:-(( .但相对于不是总统演讲稿的c源程来说,这又算得了什么?想想看以下的数据命名:
char a,b,c;
long d,e,f;
[]倡导规范书写.
如果你思如泉涌,而不去也不及顾虑书写格式,那也没关系.在将其交出去之前,用cb命令格式化你的源程.虽然源程的格式不会影响到你编译结果的正确性,但切记,能让其他的程序员能轻松地阅读它.否则没人会理你的.
关于cb命令的更多用法,可以用man cb来参考其手册页.
当然除了cb之外,还有更多更好的.但cb是你在任何unix(linux)上都找得到的.更何况它并不差
第三章:开始任务
开始任务之前,先做个深呼吸!
[]其他文档你准备好了吗?
你是不是除了c源之外一无所有了吗?兵马未动,粮草先行.你必须先清楚该程序所要完成的功能.在开始写程序之前,对程序的功能应有规范说明.书写规范书和确知程序功能的一个方法是先编写相应的操作手册.如果你是一人单干,劝你首先写需求书.切记切记,这对你意味着事半功倍的大好事.
一个实例:我计划为本行的信贷子功能模块打一个补丁.我用10周的时间用来写规划书,需求书,操作流程,使用说明等等文档.之后用2周的时间编写程序,在初步测试(1周)后递交给各信贷部门测试使用.然后根据反馈的信息再更改相应文档,并根据文档修改源程.6个月后发布正式版.
[]一定该遵循ansi标准吗?
如果你仅使用ansi的标准首标文件,恭喜你,你的程序有着全世界范围内的广泛支持和兼容.光明无限.但你必须在通用与专用之间做出取舍,对不起,我帮不了你.
我的原则是:核心用ansi,界面按需而取.这样在转换平台时仅需另编用户界面而已.实用至上嘛.
附:ansi 标准c头文件
是不是很寒酸?
[]再续前缘?
在得到新任务之后并在开始该新任务之前应马上回想有哪些是曾经拥有的.旧调重弹远比另起炉灶来的高效与环保.
[]是否该有自已的库?
我的答案是应该有自已的特色库,并与ansi兼容.与3.8不同的是,你仅需在源程序之后附上自已的专用库就可以了.其次在有了自已的库后,源码会很精炼的.不用去羡慕别人了吧.
[]要学会条件编译.注意你的平台特性.(高手的标志?)
除非你确定你要写的程序是在某特定的os特定的硬件平台而量身定做.否则应注意数据类型的长度,精度都是不同的,不要想当然.有时甚至是不同的编译器的差异都要考虑考虑.
....
....(欢迎您来充实此处空白)
....
好了,在任务中,又有哪些细节呢?
[]我是不是葛郎台?
不要那么吝啬.在源程序中加入详尽的注释以使自己和他人即使在许多年以后仍能读明白它是什么样的程序.
用注释行分离各个函数.
[]删除不需要的代码时要小心.
一个好建议是:使用#ifdef del,而不是简单地注释掉甚至是粗暴地直接dd.如果你是使用/* ... */,但一旦要删除的代码有很多行,或注释中以有注释时,这就可能不那么好使了.
[]如何给源程序文件命名?
表现特色且不与任何原有应用名相同.一个简单地方法就是试试看,系统有什么样地反应?
[]一次只修改一个地方.
[]一次只编写一个单一功能的函数。
[]编写通用程序.
只有当程序编写完,并且完成了所需要的性能要求之后,再反过头来优化该程序.
[]不要使用a.out作为结果.你大可以使用与源程相同的可执行文件名.
[]是否一定要用vi编辑?
linux下有许多专用编程编辑器.它们能使你有更高的效率和更低的低级输入错误,但我还是要劝你至少要熟练掌握vi.毕竟vi遍地开花.
[]协同作业.请相信,你不是在孤军作战.因此,你有必要熟练掌握一些其它的工具
第四章:使用lint
lint没有你想象中的那样糟糕.相反,一旦源程序形成了没有lint错误的形式,将很容易保持下去,并享受到如此而带来的好处.
[]在cc(gcc)之前就应使用lint.
lint是一语法检查程序,对于这个多嘴的婆婆来说,你应有足够的耐心.虽然你知道自已在干什么,但在cc之前使用lint总是一个好习惯.
[]lint有哪些特色?
在编译之前使用lint的重要原因是lint不但能发现ansi c中的语法错误,而且也能指出潜在的问题或是难于移植于另一机器的代码问题.除了能指出简单语法错误之外,linut还能基于以下原因指出另外的错误:
a.无法达到的语句.
b.没有进入循环.
c.没有被使用的变量.
d.函数参数从未使用.
e.没有赋值之前自动使用参数.
f.函数在有些地方有返回值,但在其他地方不返回.
g.函数调用在不同地方使得参数个数不同.
h.错误使用结构指针.
i.模糊使用操作符优先级.
呵呵呵,挺有用的吧!
[]如何控制lint的输出?
有时lint会有一大屏一大屏的警告信息.但似乎并未指出错误.为了找出潜在的错误则需费心费力地浏览这些大量的警告信息.
但如果你的程序会分出几个独立的模块,在初级启动lint时不要用可选项.当对这些模块进行更改或扩充时,可以忽略与代码无关的某些警告.为此可用以下选择项:
-h 对判别是否有错,类型是否正确不给出启发式测试.
-v 不管函数中没有定义的参数
-u 不管被使用的变量和函数没有定义或定义了但没有使用.
[]干脆,在程序中插入指令来影响lint运行.它看样子有些像注释.
/*notreached*/ 不可达到的代码不给信息说明.
/*varargsn*/ 函数的变量个数不作通常的检查,只检查开始n个参数的数据类型.
/*nostruct*/ 对下一个表达式不作严格类型检查.
/*argused*/ 下一函数中,不给出没被使用参数的警告信息.
/*lintlibrary*/ 置于文件的开头,它将不给出没被使用函数的警告信息.
关于lint的更多用法,请用man lint来获知
第五章:使用make
[]什么是make?
unix(linux)是一个天生的开发平台,我为此感到高兴.make是一个强力的工具.它能依赖的源代码块并组成一程序,使得很容易建立一可执行程序.make就是这种有依赖关系的部分和代码之间所作的规格说明.
[] 所有的程序都要使用make?
是的.尽管你只有几个简单的模块,但你需要有一种结构来支持它从简单走向复杂.除非你的程序已经盖棺定论.
[]makefile由哪些组成?
makefile由以下几个部分组成:
注释.
^^^^
使用#符号插入.make将忽略#之后的任何内容以及其后的return键.
变量.
^^^^
make允许定义与shell变量类似的有名变量.比如,你定义了sources=prog.c,那么该变量的值$(scoures)就包含了源文件名.
依赖关系.
^^^^^^^^
左边是目标模块,后接一冒号.再接与该模块有依赖关系的模块.
命令.
^^^^
以tab键开始(即使用相同数量的空格也不能代替它).
[]makefile示例
下面介绍一个简单的示例来说明make的用法.假设你的程序有两个源文件main.c和myc.c,一个位於子目录include下的头文件myhead.h,一个库由****源文件myrout1.c,myrout2.c,myrout3.c产生.
其makefile文件为:
#一个基本的makefile文件.
#其中包括个人的头文件和个人库.
headers=include/myhead.h
sources=main.c myc.c
product=$(home)/bin/tool
lib=myrout.a
libsoures=myrout1.c myrout2.c myrout3.c
cc=cc
cflags=-g
all:$(product)
$(product):$(sources)
$(cc)$(cflags) -o $(product)$(sources)
lint:$(product)
lint $(sources)$(libsources)
哈哈,挺象shell编程的.如果你与我一样使用linux下的gcc,那么只要把上面的cc=cc改为cc=gcc即可.怎么样,想来一个更复杂点的吗?
[]一个更为复杂的makefile
你是否注意到,在上例中,只要启动make,就会重新编译所有源代码.
如果你能看懂以下的makefile,恭喜恭喜,你通关了.
#一个更为复杂的makefile
headers=include/myhead.h
soures=main.c myc.c
objects=main.c myc.c
product=$(home)/bin/tool
lib=myrout.a
libsources=myrout1.c myrout2.c myrout3.c
libobjects=$(lib)(myrout1.o)$(lib)(myrout2.o)$(lib)(myrout3.o)
include=include
cc=cc
cflags=-g -xc
lint=lint
lintflags=-xc
all:$(product)
$(product):$(objects)$(lib)
$(cc)(cflags)-o$(product)$(objects)$(lib)
.c.o: $(headers)
$(cc)$(cflags) -c i$(include)$<
$(lib):$(headers)$(libsources)
$(cc) $(cflags) -c $(?:.o=.c)
ar rv $(lib) $?
rm $?
.c.c:;
lint: $(product)
$(lint)$(liniflags)$(sources)$libsources)
第六章:优质无错编程
亲爱的,检查一下,你是否注意到了以下的细节?也就是说,你是否是一个合格的,能编写优质无错代码的程序员?要永远记住,编写无错代码是程序员的责任,而不是测试员.(摘录于本人的"细节页",因此本节将永远不会保持完整,欢迎您来充实她)
[]所有程序员至少出现过的一个错误:
if(a=3){......}如果a等于3,那么......
你至少要养成这样的习惯:当判断一个变量与一个常量是否相等时,将常量写在前面.这样即使你一不小心写成这样:if(3=a){......}在cc 之前就可以很容易发现它.
[]老调重弹:逻辑操作符的优先权.
我不愿多嘴.总之,如果你一定要编写如下代码时:
if(a&0x1&&b&0x2){......}
你的手头最好有一本详尽的指南.或者你是这方面的专家.
[]尽量不使用int数据类型.
这仅是一个忠告.你大可使用char,short,long数据类型.若干年以后,当你成长为高手之时,你会发现此时我的良苦用心.
[]对于非整型函数一定要完整定义.
如 long float jisuan(char charr[],int chnum)
{ long float lmydata;
...
...
return(lmydata); }
[]对于非整型函数的输入要当心.
如 long float lfnum;
...
...
scanf("%lf",&lfnum);
[]float 型的有效数字为7位.当多于7位时,第8位及以后的位将不准确,可以将其定义为long float型.
[]文件的输入出尽量采用fread fwrite函数.只有当另有用途时才用fprintf fscanf 函数
[]对于数组及字符串的比较操作时要确认以''结束.
SQL*PLUS命令的使用大全
JBOSS入门文章
本文是为想在JBOSS环境下进行EJB开发的读者而写的,在阅读本文之前,你最好对EJB有一个基本了解。
JBOSS是一个开放源码的免费EJB服务器,它实现了其它J2EE所规定的大多数功能,现在sun公司已经把JBOSS作为J2EE1.4的标准实现服务器了,本文就带领大家从Jboss3.2.6的安装开始,一直到开发出一个完整的"hello,world"的ejb为止。
前言
本文是为想在JBOSS环境下进行EJB开发的读者而写的,在阅读本文之前,你最好对EJB有一个基本了解。
JBOSS是一个开放源码的免费EJB服务器,它实现了其它J2EE所规定的大多数功能,现在sun公司已经把JBOSS作为J2EE1.4的标准实现服务器了,本文就带领大家从Jboss3.2.6的安装开始,一直到开发出一个完整的"hello,world"的ejb为止。
JBOSS的安装与启动
如果你是第一次使用JBOSS,你一定会感到很沮丧,因为它虽然是开放源码,并可以免费下载,但是它的文档或技术培训却是收费的,而且对于国人来说高不可及(几天的培训大约要10000美元,文档也要几十至几百美一份)!如果你试图在网上找一些关于JBOSS下简单入门的文章,可只是那么寥寥可数的几篇,而且很少有菜鸟级的文章。相反,对其核心设计等高深理论性的文章倒是居多,这样反倒让你越看越糊涂。因此,本文的目的就是:让你的JBOSS尽快地跑起来,并马上可以在其之上开发出简单的EJB!
在安装JBOSS之前,首先要确定你已经安装了jdk1.3或以上版本,由于JBOSS不像weblogic等其它应用服务器捆绑了JDK,因此JBOSS非要jdk的支持才能运行。然后在 http://www.jboss.org网站上下载一个jboss的发行版(我下载的是jboss-3.2.6.zip),在本文中我使用的其稳定的发行版JBOSS3.2.6 (集成了tomcat4.1),需要附带一句的是tomcat是apache基金会旗下著名的开源jsp/servlet服务器,如果要更多的了解tomcat,请访问http://jakarta.apache.org 以获得更详细的信息。
当你把jboss-3.2.6.zip下载之后,下一步就是将它解压缩,如果你是在windows上,可以用winzip或winrar;如果是在linux下,就用unzip命令,以我自己为例,假设我将它解压到了如下目录
c:\ jboss-3.2.6
相对于weblogic,websphere等j2ee服务器来说,JBOSS的启动是简单得出乎意料,如果你是windows用户,只需要进入c:\ jboss-3.2.6\bin下面,输入run.bat命令,JBOSS就跑起来啦;如果是linux用户的话,只需要进入c:\ jboss-3.2.6\bin下面,输入run.sh,那么JBOSS也同样运行。怎么样?是挺简单的吧?
当你输入run.bat或run.sh后,你会发现屏幕上会不断地滚动一些提示信息,过大约1分钟之后(依赖于你机器的配置,我的是P4 1.7G,128M),提示信息就会停止滚动。(注意:如果你是在windows下,那么请让这个DOS窗口一直保持这种状态,千万不可将其中止!)等到它自己停止。
这样,JBOSS就已经处于运行状态了。和其它J2EE服务器一样,JBOSS也提供了一个WEB方式控制台,用方法是在IE浏览器中输入http://127.0.0.1:8080/web-console/,看见欢迎界面,就成功了。
编写第一个EJB:"hello,world"
下面我们正式开始EJB编程。在编写我们的第一个EJB之前,你应该对EJB有一个大致的了解,如果没有的话,建议你先到网上找一些这方面的文章来看,否则你将无法理解下面要讲述的内容。
远程接口
远程接口是指对于客户端而言所能看到了调用接口
//HelloWorld.java
package sample;
/*这是一个远程接口,客户端调用这个接口来使真正的ejb工作*/
public interface HelloWorld extends javax.ejb.EJBObject
{
public String hello() throws java.rmi.RemoteException;
}
Home接口
我们可以把Home接口看做是一个制造EJB的工厂,Home接口告诉EJB容器:"嗨,我的客户要我生成一个EJB,现在我把这个任务交给你啦!"
//HelloWorldHome.java
package sample;
/*Home接口告诉EJB容器怎样生成或销毁EJB的实例*/
public interface HelloWorldHome extends javax.ejb.EJBHome
{
HelloWorld create() throws java.rmi.RemoteException,javax.ejb.CreateException;
}
EJB的实现
这里才是真正的EJB的实现
//HelloWorldBean.java
package sample;
import javax.ejb.SessionContext;
/*这个类具体实现的远程接口HelloWorld*/
pubic class HelloWorldBean implements javax.ejb.SessionBean
{
private SessionContext ctx;
public void setSessionContext(SessionContext ctx)
{
this.ctx = ctx;
}
pubic void ejbRemove()
{
System.out.println("ejbRemove()");
}
public void ejbActivate()
{
System.out.println("ejbActivate()");
}
public void ejbPassivate()
{
System.out.println("ejbPassivate()");
}
/*hello方法是实际的业务逻辑,它可以在客户端显示"hello,world"这个字符串*/
public String hello()
{
System.out.println("hello()");
return "hello,world";
}
}
好了,这个会话EJB的全部代码编写完毕,下一步我们要做的是编写它的部署文件:
ejb-jar.xml
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar>
<description>JBoss Hello World Application</description>
<display-name>Hello World EJB</display-name>
<enterprise-beans>
<session>
<ejb-name>Hello</ejb-name>
<home>sample.HelloHome</home>
<remote>sample.Hello</remote>
<ejb-class>sample.HelloBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Bean</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>
这样我们就完成了一个简单的会话EJB的编写,但其实JBOSS还提供了一个额外的配置文件:JBoss.xml,利用它可以对JBOSS服务器进行更多的定制,但由于本例实在是太简单了,因此我们可以将它省略不写。
虽然我们完成了这个会话EJB的编写,但还有最后的一步工作要做:打包。首先我们进入当前项目的根目录:
cd F:\project\jboss-tutorial
然后执行jar命令将所有的类及ejb-jar.xml打包:
jar cf HelloWorld.jar sample META-INF
这时你会发现,在当前目录下多了一个名为HelloWorld.jar的文件,这就是我们的最终成品。
部署我们的EJB
部署EJB在JBOSS中是一件非常容易的事,你只需简单将HelloWorld.jar拷贝到c:\ jboss-3.2.6\server\default\deploy目录下就可以了。
这时,你可以切换到JBOSS运行的那个DOS窗口下,你会发现屏幕上会新出现如下提示信息:
15:09:21,184 INFO [MainDeployer] Starting deployment of
package: file:/F:/jboss
-3.2.3/server/default/deploy/HelloWorld.jar
15:09:21,324 INFO [EjbModule] Creating
15:09:21,354 INFO [EjbModule] Deploying HelloWorld
15:09:21,464 INFO [EjbModule] Created
15:09:21,484 INFO [EjbModule] Starting
15:09:21,555 INFO [EjbModule] Started
15:09:21,555 INFO [MainDeployer] Successfully completed
deployment of package: file:/F:/jboss-3.2.6/server/default/deploy/HelloWorld.jar
客户端代码
如果没有客户端代码的话,那么EJB对我们来说几乎毫无用处。以下我们将编写客户端代码来调用这个HelloWorld。
如果你在同一台机器上运行客户端代码和JBOSS服务器的话,那以下代码无须任何修改就可以运行,但你的客户端在另一台机器上运行的话,那你要将源码中的相应行改变一下:
/*以下是客户端源码中需要修改的行*/
env.put(Context.PROVIDER_URL, "localhost:1099");
假设EJB部署在一台IP地址为192.168.0.1的机器上,那么就应该将以上源码改为如下:
/*以下是客户端源码中修改后的行*/
env.put(Context.PROVIDER_URL, "192.168.0.1:1099");
/*HelloWorldClient.java*/
package sample;
import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.Hashtable;
public class HelloWorldClient
{
public static void main( String [] args )
{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
env.put(Context.PROVIDER_URL, "localhost:1099");
env.put("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
try
{
Context ctx = new InitialContext(env);
Object obj = ctx.lookup( "HelloWorld" );
HelloWorldHome home =(HelloWorldHome)javax.rmi.PortableRemoteObject.narrow(
obj, HelloWorldHome.class );
HelloWorld helloWorld = home.create();
System.out.println( helloWorld.hello());
helloWorld.remove();
}
catch ( Exception e )
{
e.printStackTrace();
System.out.println( "Exception: " + e.getMessage() );
}
}
}
好了,下面我就就可以编译并运行这个客户端了,如果你在编译的时候JVM报告找不到某些类的话,则可能是你没有将j2ee.jar这个包放在CLASSPATH这个路径变量中。客户端的执行结果虽然只是简单的在屏幕上打印一行"hello,world",但它是来自于另一个世界
——JBOSS的声音!
Tomcat下JSP、Servlet和JavaBean环境的配置
Tomcat4.01全攻略
Linux内核结构详解
Servlet容器工作原理讲解(4)
try {
|
package ex02.pyrmont; |
HttpServer2 |
Servlet容器工作原理讲解(3)
public void process(Request request, Response response) {
|
// create a URLClassLoader |
Class myClass = null; |
Servlet servlet = null; |
Servlet容器工作原理讲解(2)
Listing 2.2. HttpServer1 类的 await 方法 |
public Object getAttribute(String attribute) {
|
public PrintWriter getWriter() {
|
Listing 2.3.StaticResourceProcessor 类的 process方法。 |
Servlet容器工作原理讲解(1)
public void init(ServletConfig config) throws ServletException |
Listing 2.1.PrimitiveServlet.java |