2)、容器环境也将根据客房请求创建一个Servlet对象实例,或者创建多个Servlet对象实例,并把这些实例加入到Servlet实例池中。
3)、容器环境调用Servlet的初始化方法HttpServlet.init()进行Servlet实例化。在调用初始化时,要给init()
方法传入一个ServletConfig对象,ServletConfig对象包含了初始化参数和容环境的信息,并负责向servlet传递信息,如果传递失败,则会发生ServletException。Servlet将不能正常工作。
4)、容器环境利用一个HttpServletRequest和HttpServletResponse对象,封装从Web客户接收到的HTTP请求和由Servlet生成的响应。
5)、容器环境把HttpServletRequest和HttpServletResponse对象传递给HttpServlet.Service()方法。这样,一个定制的Java Servlet就可以访问这种HTTP请求和响应接口。Servlet()方法可被多次调用,各调用过程运行在不同的线程中,互不干扰。
6)、定制的Java Servlet从HttpServletRequest对象读取HTTP请求数据,访问来自HttpSession或Cookie对象的状态信息,进行特定应用的处理,并且用HttpServletResponse对象生成HTTP响应数据。
7)、当WEB服务器和容器关闭时,会自动调用HttpServlet.destroy()方法关闭任何打开的资源,并进行一些关闭
前的处理。
补充:jvm第一次加载后驻留在内存中,所有请求共享同一个servlet,包括init(),service(),start(),stop(),destrop(),doGet(),doPost()等方法。
servlet 运行在servlet 容器中,其生命周期由容器来管理。servlet 的生命周期通过 javax.servlet.Servlet接口中的init(),servce(),和destory();方法表示。
1,加载和实例化
servlet 容器负责加载和实例化servlet 当容器启动或在容器中检测到需要这个servlet来响应一个请求时。创建servlet实例。容器通过java 的反射API来创建servlet实例.所以servlet中不应该提供带参数的构造函数。
2,初始化
在servlet实例化后,容器必须调用 init() 方法来初始化这个对象。初始化的目的是为了让servlet对象在处理客户请求之前完成一些初始工作。对于每一个servlet实例,init() 方法只会调用一次。
3,请求处理
servlet 容器调用service()方法对请求处理。servlet 实例通过ServletRequest对象获得客户端的相关信息和请求信息。在对请求处理后调用ServletResponse对象设置响应信息。
4,服务终止
当容器检测到一个servlet实例应该从服务器中移除时,容器调用实例的destory方法。让实例释放它所占用的资源。如果在次发请求就会 创建一个新的servlet 实例。
在整个servlet 的生命周期中,创建servlet实例,调用实例的init()和destory()方法都只执行一次,当初始话完成后,servlet容器将该实例保存在内存中,通过servlce() 方法为接受请求服务。
=============================================================================================实例持久化Instance Persistence:
一个servlet 实例一旦加载,就开始处理对这个servlet的所有请求,换句话说就是一个servlet只生成一个实例。这样的做法对于性能的提高很有好处,能够有效地降低系统开销,而且也能有效实现持久化(例如数据库连接,cache数据)
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SimpleCounter extends HttpServlet {
int count = 0;
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
count++;
out.println("Since loading, this servlet has been accessed " +
count + " times.");
}
}
上例是一个简单的反映servlet持久化的例子,每个请求均增加本地变量count,然后打印显示。 但是上例存在多线程风险,对于访问servlet的每个请求都可以看作是一个线程对象,他们均访问同一个servlet实例,所以会出现并发问题。特别是存在对共享变量的读写操作时(例如上例的本地变量count),这种危险性更大。
解决的办法是增加synchronized块。
PrintWriter out = res.getWriter();
synchronized(this) {
count++;
out.println("Since loading, this servlet has been accessed " +
count + " times.");
}
事实上,server上对每一个servlet的注册名称都对应servlet的一个实例,用来访问servlet的请求名称决定哪个实例来处理请求,
===================================================================================
Servlet生命周期:
- 初始化(1次)
默认情况下:在第一次使用servlet程序时初始化
也可以在容器启动时初始化Servlet程序,通过配置web.xml文件:<load-on-starup>1</load-on-startup>
2. 服务(doGet、doPost),直接输入地址就是get请求
调用多次
3. 销毁(1次):
- 服务器关闭
- 此Servlet长时间不使用
对于一个基本的Servlet程序必须注意以下几点:
- 首先一定要符合Servlet程序的开发结构
- 配置 web.xml文件
发现 Servlet的问题
- 不适合于输出大量的HTML代码
JSP程序的功能与Servlet一致,也就意味着Servlet程序同样可以被外部所访问,就必须有一个地址,只能通过WEB映射解决。
修改web.xml文件,可以配置映射地址。
//表示要使用一个Servlet
<servlet>
//在web.xml文件内部起作用的名字
<servlet-name>simple</servlet-name>
//Servlet程序所在的包.类名称
<servlet-class>cn.mldn.lxh.servlet.SimpleServlet</servlet-class>
</servlet>
//Servlet映射地址
<servlet-mapping>
//在web.xml文件内部起作用的名字,此名字与上面的一致
<servlet-name>simple</servlet-name>
//具体的映射路径,前面必须有一个/
<url-pattern>/demo</url-pattern>
</servlet-mapping>
=========================================================================一.Servlet生命周期全过程:
1.加载 ClassLoader
2.实例化 new :当第一个请求到来时
3.init(ServletConfig) :new完之后就调用
4.处理请求 service(),doGet(),doPost() :当请求到来了,tomcat帮忙调用service(),由service()调用protected的service(),然后有后者调用doGet()或者doPost()
5.退出服务 destroy() :服务退出或者重新加载时。
二.强调点:
1.在Servlet整个生命周期中,在服务器端只有一个Servlet对象。
2.多线程机制。当处理请求时是按照多线程的方式进行的。tomcat内部有个线程池,当Servlet的访问量很大时,tomcat会把池内闲着的线程分配给过来的请求。而所有的线程访问的都是那一个Servlet对象。
========================================================
doget 是接收网页用get方法时调用的
dopost 是用来接收post方法的
get方法就象你在网页的地址栏里看到的一堆乱码,也就是url后面有参数
post就是用表单传过去的,就好象把数据都打成包发过去一样
doGet方法只能提交256个字符。
通常我们使用的都是doPost方法,你只要在servlet中让这两个方法互相调用就行了,例如在 doGet方法中这样写
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
再把业务逻辑直接写在doPost方法中。servlet碰到doGet方法调用直接就会去调用doPost因为他们的参数都一样。而且doGet方法处理中文问题很困难,要写过滤器之类的。
1,三者之间的关系:doGet()和doPost()是由函数service()调用才执行的。也就是说,当从HttpServlet类继承时可以绕过doGet()和doPost()直接override service()函数,也可以override doGet()和doPost()
2,service() 该函数使用起来不像duPost()与duGet()那样有约束,但几乎失去了HttpServlet的意义。很类似于GeneratServlet
3,doGet() 超链接或直接在浏览器地址栏访问时起作用
4,doPost() form提交时起作用
如果两者均有,则可用service() 或者
protected void doGet(HttpServletRequest rst, HttpServletResponse resp) throws ServletException , java.io.IOException {
doPost(req,resp);
}
===============================================================
首先要明确servlet的生命周期和HTTP协议.
Serlvet接口只定义了一个服务方法就是service,而HttpServlet类实现了该方法并且要求调用下列的方法之一:
doGet:处理GET请求
doPost:处理POST请求
当发出客户端请求的时候,调用service 方法并传递一个请求和响应对象。Servlet首先判断该请求是GET 操作还是POST 操作。然后它调用下面的一个方法:doGet 或 doPost。如果请求是GET就调用doGet方法,如果请求是POST就调用doPost方法。doGet和doPost都接受请求(HttpServletRequest)和响应(HttpServletResponse)。默认调用为doGet(),根据form提交的方式,进行不同的调用.
一个是繁文传输,一个是秘文传输,post调用会自动将调用人排序,而get不是
当form的method="Get"时执行doGet(),method="post"时,执行doPost()
. get传递的参数大小限制在1024个字节,并且传递的参数附加在url后面,在地址栏里可以看到
. post传递的参数大小没有限制,参数打包后在进行传递
从安全性来讲post()要更为安全一些
===========================================================
1.doGet和doPost的区别,在什么时候调用,为什么有时doPost中套用doGet
2.提交的form method=Post就执行DOPOST,否则执行GOGET 套用是不管method是post还是get都执行dopost方法
3.get:你可以通过URL传参数。http://www.csdn.net/index.asp?user=1234 , Post不行
4.你的表单提交都有方法的,如果提交为get就调用get方法,用post就调用post方法. get显示你传过去的参数,post则不显示.
5.通常的写法:先用doGet(),然后在doPost()中调用doGet(),这样就万无一失了,当然也可以反过来调用。
6. 简单的说,get是通过http header来传输数据,有数量限制,而post则是通过http body来传输数据,没有数量限制。
7.还有一点:get和post提交的数据量是不一样的. get最多只能在url后跟255个字符 post没这个限制
8.还有url刷新时get好像可以不用重复提交原来提交的数据, 而post则会说内容已提交,想刷新请再提交.