1.servlet的生命周期
如果servlet没有初始化,则要么正在初始化(运行其构造函数或init()方法)、正在撤销(运行其destroy()方法),要么就是不存在
servlet实例被创建之后,并在servlet能为客户请求提供服务之前,容器要对servlet调用init()。
当第一个客户请求到来时,容器会开始一个新线程,或者从线程池分配一个线程,并调用servlet的service()方法。
service()方法根据请求的HTTP方法(GET、POST等)来调用doGet()或doPost()。
每个请求都在一个单独的线程中运行。
容器运行多个线程来处理对一个servlet的多个请求。对应每个客户请求,会生成一对新的请求和响应对象。
2.ServletConfig 和 ServletContext
ServletConfig:
每个servlet有一个ServletConfig对象
用于向Servlet传递部署时信息
用于访问ServletContext
参数在部署描述文件中配置
ServletContext:
每个Web应用有一个ServletContext
用于访问Web应用参数(也在部署描述文件中配置)
相当于应用中的一个公告栏,可以在这里放消息(称为属性),应用的其他部分可以访问这些消息
用于得到服务器信息,包括容器的名字和版本,以及所支持的API版本
3.service()的参数
4.GET和POST
除此之外,GET请求可以建立书签,POST请求则不能
GET的数据内容会显示在地址栏中,POST不会,POST更安全
GET是幂等的,POST是非幂等的
5.幂等请求
HTTP GET只是要得到一些东西,不会修改服务器上的任何内容,所以是幂等的。
POST不是幂等的,POST体中的提交数据可能用于不可逆转的事物,所以用户doPost()功能时必须特别小心。
6.表单和HTTP
让一个Servlet同时支持GET 和 POST
public void doPost(...) throws ... {
doGet(request, response);
}
使用HTML传递来的数据
request.getParameter("name");
request.getParameterValues("sizes");
7.HTTP和HttpServletRequest
a)HttpServlet的doGet()方法取一个HttpServletRequest和一个HttpServletResponse作为参数。
b)service()方法根据HTTP所请求的HTTP方法(GET POST等)来确定运行doGet()还是doPost()。
c)POST请求有一个体;GET请求没有,不过GET请求可以把请求参数追加到请求URL的后面
d)GET请求本质上讲(根据HTTP规范)是幂等的。它们应当能多次运行而不会对服务器产生任何副作用。GET请求不应该修改服务器上的任何东西,但是你也可以写一个非幂等的doGet()方法(这是很糟糕的做法)
e)POST本质上讲不是幂等的,所以要由你来适当地设计和编写代码,如果客户错误地把一个请求发送了两次,你也能正确地加以处理
f)如果HTML表单没有明确地指出“method=POST”,请求就会作为一个GET请求发送,而不是POST请求。如果你的servlet中没有doGet(),这个请求就会失败。
g)可以用getParameter("paramname")方法从请求得到参数。返回值总是一个String。
h)如果对应一个给定的参数名有多个参数值,要使用getParameterValues("paramname")方法来返回一个String数组。
i)从请求对象还可以得到其他东西,包括首部、cookie、会话、查询串和输入流。
8.HttpServletReponse
a)使用响应向客户发回数据
b)对响应对象(HttpServletResponse)调用的最常用的方法是setContentType()和getWriter()。
c)得到书写器的方法是getWriter(),而不是getPrintwriter()
d)利用getWriter()方法可以完成字符I/O,向流写入HTML(或其他内容)。
e)还可以使用响应来设置首部、发送错误、以及增加cookie。
f)在实际中,大多数HTML响应都可能使用JSP发送,但仍有可能使用一个响应流向客户发送二进制数据。
g)要得到二进制流,需要在响应上调用getOutputStream()方法。
h)setContentType()方法告诉浏览器如何处理随响应到来的数据。常见的内容类型为“text/html”、"application/pdf"和"image/jpeg"。
i)可以使用addHeader()或setHeader()设置响应首部。二者的区别是这个首部是否已经是响应的一部分。如果是,setHeader()会替换原来的值,而addHeader会向现有的响应增加另一个值。如果首部不是响应的一部分,setHeader()和addHeader()的表现完全不一样。
j)如果你不想对一个请求作出响应,可以把请求重定向到另一个URL。浏览器负责把新请求发送到你提供的URL。
k)不能在响应已经提交之后才调用sendRedirect()!换句话说,如果已经向流中写了东西,再向重定向就晚了。
l)请求重定向与请求分派完全是两码事。请求分派在服务器端发生,重定向在客户端进行。请求分派把请求传递给服务器上的另一个组件(通常在同一个Web应用中)。请求重定向只是告诉浏览器去访问另一个URL。