原文链接:http://blog.csdn.net/wangzijian777/article/details/6194326
Servelt的生命周期
- Servelt的生命周期是由容器维护的,因此Servelt中必须包含无参构造器,以提供给容器创建Servelt对象。
- 如果设置了load-on-startup,则当服务器启动时就会加载servelt,并且创建对象,进行初始化。如果没有设置则暂不加载。
- 当用户访问Servelt时,容器会根据url中的信息加载对应的servelt,进行实例化和初始化,并且为这个请求创建一个独立的线程,创建request和response对象,并把servelt的实例交给这个线程。也就是说多个请求的线程拿到的是同一个servelt实例的引用。
- 初始化完成后,进入执行阶段调用servelt的service()方法,在根据Method调用doGet或者是doPost方法。
- 执行完成后,会终止给请求的线程,但是servlet对象并不会销往。
- 一般情况下只有当服务器认为servlet不会被任何线程使用,或者是服务器中断等操作时servlet才会消亡,再这之前会执行destory方法。
Servelt的初始化
创建实例之后的第一件事情就是初始化。
初始化的目的有两个,一个是把容器中的配置信息ServletConfig和ServletContext传入servelt使其能够跟容器发生关系。
另外一个目的是利用Init只执行一次的特点,把一些大的对象,如数据库连接在init中进行初始化。能够节约资源。
servlet中有两个init方法,一个是有参的,一个是无参的,通常我们覆盖无参的,如果需要覆盖有参的则需要保留super.init()方法,否则在servelt中使用ServletConfig的时候会出现空指针错误。
初始化后servlet获得了两个对象ServletConfig和ServletContext。分别说明一下:
ServletConfig
- 一个Servelt一个。
- 用于在DD中获取参数信息。DD中的内容为:<init-param><param-name>testParam</param-name><param-value>1</param-value></init-param>
- 在servlet中通过getServletConfig().getInitParameter()方法,或者是直接用getInitParameter()获取配置信息
ServletContext
- 一个容器一个。
- 包括了容器的信息,比如版本号等等。
- 能够获取容器配置信息,在DD中的内容为:<context-param>可以通过getServletContext().getInitParameter("")获取配置的全局参数。
servelt在初始化后就进入到了可以提供服务的状态,当需要的时候会调用service()方法,并且传入request和response两个参数。
这两个参数是容器把HTTP中的request和response封装成的对象。
request
已经知道了HTTP中的request主要包括了Method,url,头,如果是POST方法还会有包含了form表单信息的体部分。
request包括了很多的方法,以操作真正的HTTP request。主要有:
- getParameter()得到form中或者是url中的一个参数。
- request.getHeader("")。根据名称得到属性的值。
- Cookie[] cookies = request.getCookies()得到Cookies。
- getMethod()得到方法名称。
- getSession()得到session。
- getInputStream()得到输入流。当特殊情况下,比如需要传文件的时候可以使用流,流的内容只包含体,不包含头。
从request中获取数据
表单元素有填充域,单选,多选等几种,我们都能够在request中进行获取。
比如页面元素如下:
<form action=""><!-- 填写Servlet的URL -->
<table>
<tr>
<td>名称</td>
<td><input name="username" type="text"/><input name="username" type="text"/></td>
</tr>
<tr>
<td>性别</td>
<td><input name="sex" type="radio" value="1"/>男<input name="sex" type="radio" value="0"/>女</td>
</tr>
<tr>
<td>爱好</td>
<td><input name="taste" type="checkbox" value="0"/>篮球<input name="taste" type="checkbox" value="1"/>足球</td>
</tr>
<tr>
<td>班级</td>
<td>
<select name="grade">
<option value="1">一班</option>
<option value="2">二班</option>
</select>
</td>
</tr>
<tr>
<td>科目</td>
<td>
<select name="subject" multiple="multiple" >
<option value="1">数学</option>
<option value="2">语文</option>
<option value="3">英语</option>
</select>
</td>
</tr>
<tr>
<td>备注</td>
<td>
<textarea rows="2" cols="30"></textarea>
</td>
</tr>
<tr>
<td colspan="2"><button type="submit">提交</button></td>
</tr>
</table>
</form>
- 不指定method的情况下默认为:GET。
- 以GET方式提交数据时,所有的数据都将显示在URL中,多选的数据比如爱好,将会显示为taste=0&taste=1的形式。
- 当text不填写时获取的值为""。当其他不填写是为null
- 在servelt中进行获取的时候,使用request.getParameterValues("taste");方法得到值的数组。
- 使用request.getParameter("username")能够换取单项数据或者是多项数据的第一个。
response
- 一般情况下只是用来发送数据给客户端。
- 使用setContentType()设置MIME,浏览器能够根据这个值来判断怎样处理传过来的数据时,播放音乐,还是展示文件等等。
- 使用getWtiter()得到Writer,把HTML写回到浏览器
- 还有一些其他的方法能够设置Cookie等等。
- 当然通常情况下我们不会直接使用把HTML写回浏览器的方式,而是需要转到JSP中来代替这一过程的。
除了发送HTML到客户端外,还能够通过设置ContentType来写入文件到客户端实现下载功能:
response.setContentType("text/txt");
// response.setHeader("Content-Disposition", "filename=index.jsp");
// response.setHeader("Content-Disposition", "attachment;filename=index.jsp");
// response.setHeader("Content-Disposition", "inline;filename=index.txt");
response.setHeader("Content-Disposition", "attachment;filename=" + new String("你好.jsp".getBytes(),"ISO8859-1"));
InputStream is = getServletContext().getResourceAsStream("/index.jsp");
// 以/开始,位置是相对于功能根目录的。
OutputStream os = response.getOutputStream();
int read = 0;
byte[] bytes = new byte[1024];
while((read = is.read(bytes)) != -1){
os.write(bytes, 0, read);
}
os.flush();
os.close();
- 代码比较简单,主要是分为两部分,一是设置头信息。
- Disposition-Disposition是MIME的描述信息,帮助浏览器判断如何处理文件,attachment是作为附件下载,inline是在浏览器中打开,filename是文件的名称。如果有中文名的时候需要转码。
- 第二部分是把要传到浏览器的文件写入到response中获取到的输出流中。
- 如果只是下载静态文件,也不需要这么麻烦,只需要使用a标签指向到一个可下载的路径就可以了。
response除了把信息返回给客户端外,还能够对请求进行转发dispatch或者是重定向redirect,他们的区别在于:
- redirect是在客户端进行的。服务器把状态码301发送给客户端,客户端会重新发送那个请求给服务器。
- 使用response.sendRedirect("")进行重定向。参数以/开头的是相对于服务器跟目录的,没有/是相对路径。
- 重定向之后浏览器地址栏显示新的地址,并且不能够共享request.
- response是服务器端进行的,服务器访问一个地址,然后把结果传回浏览器。
- 使用request.getRequestDispatcher("").forword()加上相对路径。
- 能够共享request,并且浏览器的地址是没有变化的。
- 转发的操作是不能够在out.write执行完之后进行的。
到此servlet的相关功能介绍完毕。