容器控制着 servlet 的一生,它会创建请求和响应对象. 为 servlet 创建一个新线程或分配一个线程,另外调用 servlet 的 service() 方法,并传递请求和响应对象的引用作为参数。
servlet 完整的的生命周期如下所示:
Web 容器加载 Servlet 类
初始化 servlet ( 构造函数运行 )
- Servlet 的无参构造函数运行( 只需要使用编译器提供的默认构造函数即可)
init():在 servlet 的一生中只调用一次,而且必须在容器调用 service() 之前完成
service():处理客户请求,会执行 doGet(). doPost() 等
- 每个请求都在一个单独的线程中运行
destroy():在 servlet 被杀死之前清理资源
如下图,servlet 接口中三个粗体显示的是生命周期方法。
大多数 servlet 行为都由超类方法处理,你只需要覆盖所需的 HTTP 方法
| 何时调用 | 作用 | 是否覆盖 | |
|---|---|---|---|
| init() | servlet 实例创建后,并在 servlet 能为客户请求提供服务之前,容器要对 servlet 调用 init() | 使你在 servlet 处理客户请求之前有机会对其初始化 | 有 如果有初始化代码,就要覆盖其 init() 方法 |
| service() | 第一个客户请求到来时,容器会开始一个线程池,或分配一个线程,并调用 servlet 的 service() 方法 | 查看请求,确定 HTTP 方法,并在 servlet 上调用对应的方法 | 否 |
| doGet() 或 doPost() | service() 方法根据请求的 HTTP 方法来调用 doGet() 或 doPost() | 写具体的代码,Web 功能由这个方法负责 | 至少要覆盖其一,不论覆盖哪一个,都能告诉容器支持什么类型的请求 |
容器会运行多个线程来处理对一个 servlet 的多个请求,对应的每个客户请求,都会生成一对新的请求和响应对象。
也就是说,每个客户为每个请求得到一个单独的线程,而且容器会分配一对新的请求和响应对象
容器启动时,会寻找已经部署的 Web 应用,然后开始搜索 servlet 类文件。找到类后,就开始加载,这可能在容器启动时发生,也可能在第一个客户使用时进行。不管如何,在 servlet 没有完全初始化之前决不能运行 servlet 的 service() 方法
servlet 从 “不存在” 状态迁移到 “初始化” 状态,首先是 执行构造函数。这时它会成为一个对象,而不是一个 servlet。容器会 为该对象建立一个 ServletConfig,调用 init()方法 使其而变成一个 servlet。
作为 servlet,有了一些特性,如能够记录事件日志,得到其他资源的引用,保存其他 servlet 的属性等
service 方法会根据 HTTP 请求的 HTTP 方法来确定运行的 doGet() 还是 doPost()
| 方法 | 作用 |
|---|---|
| GET | 要求得到所请求 URL 上的一个东西( 资源/文件 ) |
| POST | 要求服务器接收附加到请求的体信息,并提供所请求 URL 上的一个东西 |
| HEAD | 只要求得到 GET 返回结果的首部部分 |
| TRACE | 要求请求消息回送 |
| PUT | 指出要把所包含的信息( 体 ) 放在请求的 URL 上 |
| DELETE | 指出删除所请求 URL 上的一个东西 |
| CONNECT | 要求连接以便建立通道 |
1.POST 有一个体。GET 和 POST 都能发送参数,但 GET 对参数数据有所限制,参数数据只能放在请求行的内容
2.安全性。使用 GET 时,参数会显示在输入栏中,放在实际的 URL 的后面
3.是否需要或是否希望最终用户对请求页面建立书签。 GET 请求可以建立书签, POST 不能建立书签
4.这些方法如何使用。GET 用于得到某些东西,POST 则用于发送数据来进行处理
5.幂等性:指一次和多次请求某一资源应具有同样的副作用。可以反复做同一件事。
- GET 只是要等到某些东西,不会修改服务器上的任何内容。所以,GET 是幂等的,而且不会产生任何不好的副作用
- POST 不是幂等的,POST 体中的提交数据可能用于不可逆转的事务
简单的超链接就是 GET 请求
<a href="http://www.wickedlysmart.com/index.html/">click here</a> 如果指出 method = “POST”,那就是 POST 请求
<form method="POST" action="SelectBeer.do"> Select beer characteristics<p> Color: <select name="color" size="1"> <option value="light">light </option> <option value="amber"> brown </option> <option value="dark"> dark </option> <option value="amber"> amber </option> </select> <br /><br /> <div style="text-align:center"> <input type="submit"> </div> </form> 如果没有在表单中指出 method = “POST”,则会默认为 HTTP GET 请求。但是如果 servlet 中没有 doGet() 方法,这个请求就会失败
HTML 表单
<form method="POST" action="SelectBeer.do"> Select beer characteristics<p> <select name="color" size="1"> <option>light <option>brown <option>dark <option>amber </select> <div> <input type="submit"> </div> </form> HTTP POST 请求
POST /advisor/selectBeerTaste.do HTTP/1.1 Host:www.wichedlysmart.com User-Agent:Mozilla/5.0 (Macintosh;U;PPC Max OS X Mach-O;en-US;rv:1.4) Gecko/20030624 Netscape7.1 Accept:text/xml,application/xml,application/xhtml+xml,text/html,q=0.9,text/plain,q=0.8,video/x-mng,image/png,image/jpeg,image/gif,q=0.2,*/*;q=0.1 Accept-Language:en-US,en;q=0.5 Accept-Encoding:gzip,deflate Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive:300 Connection:keep-alive color:dark Servlet 类
public class BeerSelect extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String c = request.getParameter("color"); ・・・ } } 可以用 getParamter("paramname") 方法从请求得到参数。返回值总是一个 String。例如:
String c = request.getParameter("color"); 如果对应一个给定的参数名有多个参数值,要使用 getParamterValues("paramname") 方法来返回一个 String 数组。例如:
String[] sizes = request.getParameterValues("sizes"); | 作用 | 使用 |
|---|---|
| 获取客户的平台和浏览信息 | String client = request.getHeader("User-Agent"); |
| 与请求相关的cookie | Cookie[] cookies = request.getCookies(); |
| 与客户相关的会话 | HttpSession session = request.getSession(); |
| 请求的 HTTP 方法 | String theMethod = reqeust.getMethod(); |
| 请求的输入流 | InputStream input = request.getInputStream(); |
如果有任何问题,欢迎交流学习。