Servlet技术(上)
Servlet技术(上)
Tomcat的<CATALINA_HOME>/lib/servlet-api.jar文件为Servlet API的类库文件。Servlet API主要由两个Java包组成:
- Javax.Servlet 包中定义了Servlet接口以及相关的通用接口和类
- Javax.servlet.http 主要定义了与HTTP协议相关的HttpServlet、HttpServletRequest接口和HttpServletResponse接口
Servlet接口
所有的Servlet类都必须实现这个接口,Servlet接口中定义了5个方法,其中3个方法都由Servlet容器来调用,容器会在Servlet的生命周期的不同阶段调用特定的方法
- init(ServletConfig config) 该方法负责初始化Servlet对象,容器在创建好Servlet对象后,就会调用该方法
- service(ServletRequest req,ServletResponse resp):负责响应客户的请求,为客户提供相应服务。容器接收到客户端要求访问特定Servlet对象的请求,就会调用该Servlet对象service()方法。
- destory()方法:负责释放Servlet对象占用的资源。当Servlet对象结束生命周期时,容器会调用此方法
Servlet接口还定义了连个返回Servlet的相关信息的方法。Java Web应用中的程序代码可以访问Servlet的这两个方法,从而获取Servlet的配置信息以及其他相关信息:
- getServletConfig():返回一个ServletConfig对象,该对象中包含了Servlet的初始化参数信息
- getServletInfo():返回一个字符串,该字符串中包含了Servlet的创建者、版本和版权等信息
GenericServlet抽象类
GenericServlet抽象类为Servlet接口提供了通用实现,GenerivcServlet除了实现Servlet接口,还实现了ServletConfig接口和序列化Serializable接口
HttpServlet抽象类
HttpServlet类是GenericServlet类的子类,HttpServlet类为Servlet接口提供了与HTTP协议相关的通用实现。HttpServlet对象社和运行在客户端采用HTTP协议通信的Servlet容器或Web服务器中。
HttpServlet为所有针对特定请求的方式的doXXX()方法提供了默认的实现。在HttpServlet类的默认实现中,doGET()、doPost()、doPut()和doDelete()都可以向客户端返回一个错误:
- 405
- 400
ServletRequest接口
Servlet接口的Service方法中有一个ServletRequest类型的参数。ServletRequest类表示来自客户端的请求。当Servlet容器接收到客户端要求访问特定Servlet的请求时,容器先解析客户端的原始请求数据,将它包装成一个ServlertRequest对象。当容器调用Servlet对象的service()方法时,就会把ServletRequest对象作为参数传给service()方法
- getContentLength() 返回请求正文的长度。如果请求正文的长度未知 返回-1
- getContentType() 获得请求正文的MIME类型,如果请求正文的类型未知返回null
- getInputStream() 返回用于读取请求正文的输入流
- getLocalAddr() 返回服务器端IP地址
- getLocalName() 返回服务器端的主机名
- getLocalPort() 返回服务器端的FTP端口号
- getParameter(String name) 根据指定的请求参数名,返回来自客户请求中匹配的请求参数
- getProtocol():返回客户端与服务器端通信所用的协议的名称以及版本号
- getReader():返回用于读取字符串形式的请求正文的BufferedReader对象
- getRemoteAddr():返回客户端IP地址
- getRemoteHost():返回客户端的主机名
- getRemotePort():返回客户端的FTP端口号
HttpServletRequest接口
HttpServletRequest接口时ServletRequest接口的子接口,HttpServlet类的重载service()方法以及doGet()和doPost()等都有一个HttpServletRequest的形参
- getContextPath() 返回客户端所请求访问的Web应用的URL入口。项目路径
- getCookies() 返回请求中的所有cookie
- getHeader(String name) 返回HTTP请求头部的特定项
- getHeaderNames() 返回包含所有HTTP请求头部的所有项目名
- getMethod() 返回HTTP请求方式
- getRequestURI() 返回HTTP请求的头部URI
- getQueryString() 返回请求中的查询字符串 URL中?后面的内容
HTTPServletResponse接口
Servlet通过ServletResponse对象来生成响应结果,当Servlet容器接收到客户端要求访问特定Servlet的请求时,容器会创建一个ServletResponse对象,并传递给Servlet的service()方法
- setCharacterEncoding(String charset)设置响应正文的字符编码
- setContentLength(int len) 设置响应正文的长度
- setContentType(String type) 设置响应正文的MIME类型
- getCharacterEncoding() 返回响应正文的字符编码
- getContentType() 返回响应正文的MIME
- setBufferSize(int size) 设置存放响应正文数据的缓冲区大小
- getBufferSize() 获取存放响应正文数据的缓冲区大小
- reset() 清空缓冲区内的正文数据,并且清空响应状态码以及响应头
- resetBuffer() 仅清空缓冲区内的正文数据,不清空响应状态码以及响应头
- flushBuffer() 强制性地把缓冲区内的响应正文发送到客户端
- isCommitted() 用于返回数据是否以及发送到客户端
- getOutputStream() 返回一个ServletOutputStream对象,Servlet用来输出二进制正文数据
- getWriter() 返回PrintWriter对象,Servlet用来输出字符串形式的正文数据
在Tomcat的实现中,如果Servlet的service()方法没有调用ServletOutputStream或PrintWriter的close()方法,那么Tomcat在调用完Servlet的service()方法后,会关闭ServletOutputStream或PrintWriter
HttpServletResponse接口
HttpServletResponse接口是ServletResponse的子接口。
HttpServletResponse接口提供了与HTTP协议相关的一些方法,Servlet可通过这些方法来设置HTTP响应头或客户端写Cookie
- addHeader(String name,String value)向HTTP响应头中加入一项内容
- sendError(int sc) 向客户端发送一个代表特定错误的HTTP响应状态代码
- setHeader(String name,String value):设置HTTP响应头中的一项内容,如果响应头中以及存在,原先所做的设置将被覆盖
- setStatus(int sc):设置HTTP响应的状态代码
- addCookie(Cookie cookie):向HTTP响应中加入一个Cookie
ServletConfig接口
当Servlet容器初始化一个Servlet对象时,会为这个Servlet对象创建一个ServletConfig对象。ServletConfig对象中包含了Servlet的初始化参数信息,ServletConfig还与当前Web应用的ServletContext对象关联。Servlet容器调用Servlet对象的init(ServletConfig config)方法时,会把ServletConfig对象作为参数传给Servlet对象。
HttpServlet继承GenericServlet类,GenericServlet实现ServletConfig接口,因此在HttpServlet类或GenericServlet类以及子类中都可以直接调用ServletConfig接口中的方法
ServletContext接口
ServletContext是Servlet与Servlet容器之间进行通信的接口,Servlet容器在启动一个Web应用时,会为它创建一个ServletContext对象。每个Web应用都有唯一的ServletContext对象。Servlet对象们可以通过这个类来访问Servlet容器中的各种资源
1. 用于在Web应用范围内存取共享数据
- setAttribute(String name,Object object) 把java对象与一个属性名绑定,存入ServletContext中。name指定属性名
- getAttribute(String name) 根据参数给定的属性名,返回一个Object类型的对象
- getAttributeNames():返回所有存放在ServletContext中的属性名
- removeAttribute(String name):根据参数指定的属性名,从ServletContext中删除匹配的属性
2. 访问当前Web应用的资源
- getContextPath() 放回当前Web应用的URL入口
- getInitParameter(String name):根据指定的参数名,返回Web应用范围内的匹配的初始化参数值
- getInitParameterNames() 返回包含Web应用范围内所有的初始化参数名
- getServletContextName() 返回Web应用的名字
- getRequestDispatcher(String path):返回一个用于向其他Web组件转发请求的RequestDispathcer对象
3. 访问Servlet容器中的其他Web应用
- getContext(String uripath) 根据参数指定的URI返回当前Servlet容器中其他Web应用的ServletContext对象
4. 访问Servlet容器的相关信息
- getMajorVersion():返回Servlet容器支持的Java Servlet API的主版本号
- getMinorVersion():返回Servlet容器支持的Java Servlet API的次版本号
- getServerInfo() 返回Servlet容器的名字和版本
5. 访问服务器端的文件系统资源
- getRealPath(String path) 根据参数指定的虚拟路径,返回文件系统中的一个真实路径
- getResource(String path)返回一个映射到参数指定的路径的URL
- getResourceAsStream(String path):返回一个用于读取参数指定文件的输入流
6. 输出日志
- log(String msg) 向Servlet的日志文件中写日志
- log(String message,Throwable throwable) 向Servlet的日志文件中写 错误日志,以及异常的堆栈信息
JavaWeb应用的生命周期
Java Web应用的生命周期是由Servlet容器来控制,Java Web应用的生命周期包括三个阶段
- 启动阶段:加载Web应用的有关数据,创建ServletContext,对Filter和一些Servlet进行初始化
- 运行时阶段:为客户端提供服务
- 终止阶段:释放Web应用所占用的各种资源
启动阶段
Servlet容器在启动JavaWeb应用时,会完成以下操作
- 把web.xml文件中的数据加载到内存中
- 为JavaWeb应用创建一个ServletContext对象
- 对所有的Filter进行初始化,Filter的初始化是在JavaWeb容器启动时完成的
- 对需要在Web应用启动时就初始化的Servlet进行初始化。
运行时阶段
在这个阶段,它的所有Servlet都处于待命状态,随时可以响应客户端的特定请求,提供相应的服务。如果客户端请求的Servlet还不存在,Servlet容器会先加载并初始化Servlet,然后再调用它的service()服务方法
终止阶段
Servlet容器在终止JavaWeb应用时,会完成以下操作
- 销毁JavaWeb应用中所有处于运行时状态的Servlet。
- 销毁JavaWeb应用中所有处于运行状态的Filter
- 销毁所有与JavaWeb应用相关的对象,如ServletContext对象等,并且释放Web应用所占用的相关资源
Servlet的生命周期
初始化阶段
- Servlet容器加载Servlet类,把它的.class文件中的数据读入到内存中
- Servlet容器创建ServletConfig对象。
- Servlet容器创建Servlet对象
- Servlet容器调用Servlet对象的init方法
经过初始化步骤创建了Servlet对象和ServletConfig对象,并且Servlet对象与ServletConfig对象关联,而ServletConfig对象与当前Web应用的ServletContext对象关联。当Servlet容器初始化完Servlet后,Servlet对象只要通过getServletContext() 就能得到当前Web应用的ServletContext对象
Servlet进入初始化阶段的情况
- 当Web应用处于运行时阶段,Servlet被客户端首次请求访问,Servlet会被Servlet容器初始化
- 如果在web.xml中为Servlet设置了<load-on-startup>元素,当Servlet容器启动Servlet所属的Web应用时,就会初始化这个Servlet
- Web应用被重新启动时,Web应用中的所有Servlet都会重新初始化
运行时阶段
在这个阶段中,Servlet可以随时响应客户端的请求,当Servlet容器接收到要求访问特定Servlet的客户请求,Servlet容器创建针对于这个请求的ServletRequest对象和ServletResponse对象,然后调用相应的Servlet对象的service()方法。service()方法从ServletRequest对象中获得客户请求信息并处理该请求,通过ServletResponse对象生成响应结果。
销毁阶段
当Web应用被终止时,Servlet容器会先调用Web应用中所有Servlet对象的destroy)方法,然后再销毁这些Servlet对象。在destory()方法的实现中,可以释放Servlet所占用的所有资源。
容器还会销毁与Servlet关联的ServletConfig对象
ServletContext与Web应用范围
当Servlet容器在启动一个Web应用时,会为它创建唯一的ServletContext对象。当Servlet容器终止一个Web应用时,就会销毁它的ServletContext对象、
Web应用范围的含义
- Web应用范围表示由Web应用的生命周期构成的时间段
- 表示在Web应用生命周期内所有Web组件的集合
特点
-
共享数据的生命周期位于Web应用的生命周期中的一个时间片段内
-
共享数据可以被Web应用中的所有Web组件共享
-
Web应用范围内可以存放各种类型的共享数据。Java对象可有与ServletContext对象关联,该Java对象的生命周期会依附ServletContext对象的生命周期。Web组件可以通过ServletContext对象来访问它
常用API
- setAttribute(String name,Object obj) 向Web应用范围内存入共享数据。参数name指定属性名,参数object表示共享数据
- removeAttribute(String name):根据参数给定的属性名,从Web应用范围内删除匹配的共享数据
- getAttribute(String name):根据参数给定的属性名,返回Web应用范围内匹配的共享数据
ServletContextListener 监听器
Servlet API中有ServletContextListener接口,它能够监听ServletContext对象的生命周期。当Servlet容器启动或终止Web应用,会触发ServletContextEvent事件,该事件由ServletContextListener处理
- contextInitialized(ServletContextEvent sce) 当Servlet容器启动Web应用时调用该方法,调用完该方法后,会对Filter初始化,并对需要在Web应用启动时就需要初始化的Servlet进行初始化
- contextDestroyed(ServletContextEvent sce) 当Servlet容器终止Web应用时调用该方法。在调用该方法之前,容器会销毁所有的Servlet和Filter过滤器
防止页面被客户端浏览器缓存
浏览器为了快速向用户展示所请求的页面,会将来自服务器端的网页存放在客户端的缓存中。如果浏览器的缓存中已经存在该网页,那么浏览器只需从缓存中获取该网页,而不再请求服务器上的网页
但是有一些情况我们不希望数据被浏览器缓存
- 当网页包含随时会被更新的动态内容。防止数据展示出现异常
- 网页中包含敏感数据
服务器端的HttpServlet可通过设置特定HTTP响应头来禁止客户端缓存网页
response.setHeader("Cache-Control","no-cache");
或者
response.setHeader("Expires","0");
Expires用于设定网页过期的时间,如果为0,表示立即过期