您的位置:首页 > 其它

我学习servlet的体会

2008-03-04 23:29 148 查看
我个人一直认为,学习servlet需要集合tomcat的源码一起看(如果你使用其他的servlet
容器,当然可以看其他容器相应的源码).个人觉得学习servlet有几点需要注意,我觉得
把这几点弄明白了,那么参看api就可以动手编程了(当然前提是需要把HTTP协议弄清楚
了)。
1、一定明白servlet就像插件一样,是被web服务器(具体来说是里面的servlet引擎)
调用的。那么也就是你,你只管把你的代码在servlet里写好,servlet引擎自
动会来调用。因为serlvet引擎调用一个servlet的时候,先创建这个servlet的实例(当
然已经载入这个servlet了),其实是Servlet xxx=new YourServet()的形式,也就是说
servlet引擎只知道调用的是servlet这个接口里定义好的方法!!!(这个就是J2EE标准
的一个简单的体现,对具体厂商和开发者而言,各自按照标准来做事。) 。之后执行se
rvlet的顺序如下:
1)执行init(ServletConfig config)方法,注意,这里执行的是带参数的init方法,因
为这个init方法里的代码里对ServletConfig这对象进行了初始化,而通过ServletConf
ig对象的getServletContext()方法又可以得到ServletContext对象。那么,也就是只要
建立好一个servlet实例后,关于这个servlet的配置信息ServletConfig类对象和servl
et所处的上下文环境(一个web应用程序)ServletContext对象都可以得到了(其实你要
注意:这些ServletConfig对象和ServletContext对象都是servlet引擎为你创建你),
这样不是很爽么?得到这些对象后,你想怎么操作就怎么操作了。
2)再调用了init方法后,那么开始执行service()方法了。那么为什么我们要可以把代
码写在service()方法里,或者doXXX方法里呢?如果你是继承GenericServlet来写的se
rvlet,那么servlet引擎直接调用你servlet里的service()方法。如果你是继承Http
Servlet来写的servlet,那么servlet引擎也是直接调用你servlet里的service()方法
,只不过如果你没有重写service方法的话,那么HttpServlet里的service()方法里的
代码会根据浏览器请求类型调用相应的doXXX()方法,所以我们一般都直接重写doGet
(),或者doPost()方法等。(上面讲的这些大家可以参看tomcat的源码)。
3)最后在调用service方法后,当servlet不再有用时,要销毁这个对象时,那么调用S
ervlet接口里的destroy()进行资源的释放和清扫。
其实对servlet的运行过程,一句话:servelt引擎只根据servlet接口定义的方法来

进行调用init()---->service()――――>destroy()。当然根据多态的特性,它会
调用你创建servlet的类的对象里的相应的方法的。
2、servlet引擎再调用一个相应的servlet对象的service()方法时,会同时创建两个
对象,一个是HttpServletResponse,一个是HttpServletRequest。前者先创建一个内容
是空的输出信息,后者把请求的信息包装起来对象。我们可以从HttpServletRequest取
出我们想要的信息,之后可以向HttpServletResponse输出我们想输出的内容。这里就要
提到过滤器了。过滤器的作用也就是说在把这个两个对象传给一个servlet的service(
)方法之前,先对对象进行处理。比如,我们可以根据request对象,进行阻止不要让它请
求到想请求的资源,而进行重定向。对输出内容呢?我们传给servlet的response对象是
个更换过response对象,也就是说让servlet在输出的时候不是直接输出到客户端,我是
输出到我们更换过的response对象里,比如让它输出到一个CharArrayWiter字符数组里
。再从这个字符数组里取出servlet输出的内容,我们进行我们想要的更改后,再发送到
客户端。再了解了这些细节后你会发现写过滤器原来这么easy!你也许会问,怎么知道
要访问那些servlet的时候会执行哪些过滤器呢?这个可以在web.xml里进行的配置的。

3、对于servlet与jsp或者数据库中的中文乱码问题:
其实抓住一点就ok:在这个程序处理过程中,最开始(起点)字符是采用什么编码
集(当然它有一个对应的编码值),程序最后处理(终点)字符是采用什么编码集(当
然它此时也有一个对应的编码值)。看这个两个字符集之间是否可以进行转换的,如果
可以,进行了正确的转换了吗?如果进行了正确的转换,那么就不会出现乱码问题,否
则就出现了乱码问题。这些编码集涉及到iso8859-1,utf8,gb2312,unicode。注意中文
字符在utf8,gb2312,unicode中都是存在的。iso8859-1中是不存在的。其中注意,由
于java中采用的是unicode的编码,
所以我们在应用程序中,unicode就相当于枢纽一样,很多编码都是先解码到unicode,
再从unicode编码到其他一些具体字符。
像gb2312--->unicode--->gb2312,utf8--->unicode--->utf8,
gb2312--->unicode--->uft8,uf8---->unicode--->gb2312等,都是可以正确
进行转换的。但是要注意,我写的gb2312,utf8,unicode,字符必须是在它们编码集下
的正确编码值才能正确转换。例如:"中"的gb2312编码是"0xD6D0",这个时候进行gb231
2--->unicode的转换是正确的。但是如果进行utf8-->unicode的转换肯定错误,因为ut
f8中的"中"字的编码值是:0xE4B8AD,而不是0xD6D0,所以要注意。很多时候的乱码就
是就这样产生的。现在分析一下一种最常见的情况,我们把"中"这个字符(以gb2312编
码0xD6D0)进行下面的转换iso8859-1---->unicode--->iso8859-1--->gb2312最后能正
常显示中文吗?答案是能。其实这可以说是一种巧合。0xD6D0我们把它当作iso8859-1解
码到unicode时候变成的是0x00D6 00D0,所以这个时候打印unicode出来看时是乱码。因
为"中"在unicode里编码值是0x4E2D。但是我们将他再次的编码为iso8859-1呢,现在编
码值又变成了0xD6D0,这个时候再用gb2312显示,就是正确的中文"中"了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: