简单了解 Servlet 相关特性
Servlet 生命周期
什么是Servlet生命周期
容器创建Servlet对象, 为Servlet对象分配资源, 调用Servlet对象方法来处理请求, 以及销毁Servlet对象的整个过程。
生命周期的四个阶段
阶段一: 实例化
- 什么是实例化
容器调用Servlet构造器,创建一个Servlet对象 - 什么时候实例化
- 情形一:
开始容器里面没有Servlet对象,只有收到请求后才会创建Servlet对象 - 情形二:
容器在启动之后就会立即创建相应的实例
- 情形一:
阶段二: 初始化
// 什么是初始化
-容器在创建好Servlet对象之后,会立即调用此对象的init()方法
-一般情况下,我们不用写init()方法,因为GenericServlet已经提供了init()方法的实现(将容器传递过来的ServletConfig对象保存起来,并且提供了getServletConfig()方法来获取ServletConfig对象)
-init()方法只会执行一次
// Servlet的初始化参数如何设置
<servlet>
<servlet-name> </servlet-name>
<servlet-class> </servlet-class>
<init-param>
<param-name>company </param-name>
<param-value>hello </param-value>
</url-param>
</servlet>
// 如何读取Servlet初始化参数
String name = servletConfig.getInitParameter("company");
阶段三: 就绪
-容器收到请求之后调用Servlet对象的service()方法来处理请求
阶段四: 销毁
-容器会依据自身的算法删除Servlet对象,删除前会调用destroy()方法
-只会执行一次
-可以重写destroy()方法来实现自己的处理逻辑
-应用程序在卸载时一定会调用destroy()方法
Servlet 核心接口和类
ServletConfig接口:
用于获取Servlet初始化参数和ServletContext对象
ServletContext接口:
代表当前Servlet运行环境,Servlet可以通过ServletContext对象来访问Servlet容器中的各种资源
HttpServletRequest接口:
用于封装Http请求信息
HTTPServletResponse接口:
用于封装Http响应消息
ServletConfig 类:
获取ServletConfig对象:
使用初始化方法获得一个ServletConfig对象
通过继承父类(GenericServlet)的方法得到一个ServletConfig对象:
ServletConfig config = this.getServletConfig();
- getServletName();
获取servlet的名称,也就是我们在web.xml中配置的servlet-name - getServletContext();
获取ServletContext对象,该对象的作用看下面讲解 - getInitParameter(String);
获取在servlet中初始化参数的值。这里注意与全局初始化参数的区分。这个获取的只是在该servlet下的初始化参数: - getInitParameterNames();
获取在Servlet中所有初始化参数的名字,也就是key值,可以通过key值,来找到各个初始化参数的value值。注意返回的是枚举类型:
ServletContext类:
获取ServletContext对象
1)getServletContext();
2)getServletConfig().getServletContext();
这两种获取方式的区别就跟上面的解释一样,第一种是直接拿,在GenericServlet 中已经帮我们用 getServletConfig().getServletContext();拿到了ServletContext。
作用:
1)web项目中共享数据
在一定范围内(当前应用),使多个Servlet共享数据
1.1)setAttribute(String name, Object obj) 在web项目范围内存放内容,以便让在web项目中所有的servlet都能访问到
1.2)getAttribute(String name) 通过指定名称获得内容
1.3)removeAttribute(String name) 通过指定名称移除内容
2)获取全局配置信息
整个web项目初始化参数 (这个就是全局初始化参数,每个Servlet中都能获取到该初始化值)
2.1)getInitPatameter(String name) //通过指定名称获取初始化值
2.2)getInitParameterNames() //获得枚举类型
3)获取web项目资源
3.1)获取web项目下指定资源的路径:getServletContext().getRealPath("/WEB-INF/web.xml")
String getRealPath(String path);//根据资源名称得到资源的绝对路径
3.2)获取web项目下指定资源的内容,返回的是字节输入流。
InputStream getResourceAsStream(java.lang.String path)
3.3)getResourcePaths(java.lang.String path) // 指定路径下的所有内容。
3.4)实现servlet的转发
RequestDispatcher getRequestDispatcher(String path) ;//参数表示要跳转到哪去
HttpServletRequest类:
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。
request就是将请求文本封装而成的对象,所以通过request能获得请求文本中的所有内容,请求头、请求体、请求行
- 请求行
例:Get http://localhost:8080/day09/servlet/req1?username=zs
http/1.1
getMethod(); //获得请求方式
getRequestURL(); // 返回客户端发出请求时的完整URL。
getRequestURI(); //返回请求行中的资源名部分。
getContextPath(); // 当前应用的虚拟目录
getQueryString() ; //返回请求行中的参数部分。
- 请求头
String getHeader(String name) //根据头名称得到头信息值
long getDateHeader(java.lang.String name) //获得指定头内容Date
int getIntHeader(java.lang.String name) //获得指定头内容int
Enumeration getHeaderNames()// 得到所有头信息name
Enumeration getHeaders(String name) /根据头名称得到相同名称头信息值
- 请求体(请求正文)
1)与表单获取相关的方法
String getParameter(name) 根据表单中name属性的名,获取value属性的值方法
String[] getParameterValues(String name)专为复选框取取提供的方法
getParameterNames() 得到表单提交的所有name的方法
Map<String,String[]> getParameterMap()得到表单提交的所有值的方法 //做框架用,非常实用
getInputStream 以字节流的方式得到所有表单数据
2)与操作非表单数据相关的方法(request也是一个域对象)
void setAttribute(String name, Object value);
Object getAttribute(String name);
Void removeAttribute(String name);
3)与请求转发相关的方法
//得到请求转发或请求包含的协助对象
RequestDispatcher getRequestDispatcher(String path) //获取转发器
forward(ServletRequest request, ServletResponse response) //转发的方法
include(ServletRequest request, ServletResponse response) //请求包含
4)与编码相关的方法
//解决post方式编码
request.setCharacterEncoding("UTF-8"); //告诉服务器客户端什么编码,只能处理post请求方式
//解决get方式编码
String name = new String(name.getBytes(“iso-8859-1”),”UTF-8”);
HttpServletResponse类:
- 响应头:
Accept: 指示HTTP响应可以接收的文档类型集
Accept-Charset: 告知客户可以接收的字符集
Accept-Encoding: 所有响应的字符编码集
Content-Type: 响应体的MIME类型
Content-Language: 响应体的语言类型
Content-Length: 响应体的长度和字节数
Expires: 通知客户端过期时间,防止客户浏览器使用本地缓存副本
Cookie: 包含保存到客户端的Cookie集
Redirect: 提供指定重定向,可以不向浏览器输出响应内容,而是直接重新请求到另一个URL地址,实现重定向响应,即是一种自动定向。
setHeader(String name, String value) //设置响应头信息
- 响应正文:
getWrite(); 字符输出流
getOutputStream(); 字节输出流
setCharacterEncoding(String charset) 告知服务器使用什么编码
setContentType(String type)

ServletContext (Select上下文)
什么是Servlet上下文
- 容器启动之后会为每一个web应用创建唯一的一个符合ServletContext接口要求的对象,这个对象就是Servlet上下文
- 特点:
1)唯一性(一个web应用对应一个ServletContext)
2)一直存在(只要容器不关闭,应用没有被卸载,ServletContext就一直存在)
如何获得servlet上下文
- 方式一:
通过 GenericServlet 提供的 getServletContext() 方法 - 方式二:
通过 ServletConfig 提供的 getServletContext() 方法 - 方式三:
通过 HttpSession 提供的 getServletContext() 方法 - 方式四:
通过 FilterConfig 提供的 getServletContext() 方法
Servlet上下文的作用及特点
作用:
1)使用setAttribute绑定数据
2)使用removeAttribute移除绑定数据
3)使用getAttribute获取绑定数据
特点:
Servlet上下文绑定的数据可以被整个应用上的所有组件共享,并且一直可以访问
Servlet线程安全问题
为什么会有线程安全问题
- 容器在收到请求之后会去启动一个线程来进行相应的处理,默认情况下,容器只会为每个Servlet创建一个实例对象,如果同时有多个请求访问同一个Servlet,则肯定会有多个线程访问这个Servlet实例,如果这些线程要修改Servlet实例的某个属性,就有可能发生线程安全问题
如何保证线程安全
使用synchronized对代码加锁即可
例如:
synchronized(this){
count--;
}
- 请求之后会去启动一个线程来进行相应的处理,默认情况下,容器只会为每个Servlet创建一个实例对象,如果同时有多个请求访问同一个Servlet,则肯定会有多个线程访问这个Servlet实例,如果这些线程要修改Servlet实例的某个属性,就有可能发生线程安全问题
版权声明:本文为weixin_44603464原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。