1.概览
-
1.1 什么是 Servlet?
Servlet 是基于 Java 技术的 web 组件,容器托管的,用于生成动态内容。像其他基于 Java 的组件技术一样, Servlet 也是基于平台无关的 Java 类格式,被编译为平台无关的字节码,可以被基于 Java 技术的 web server 动态加载并运行。容器,有时候也叫做 servlet 引擎,是 web server 为支持 servlet 功能扩展的部分。客户端 通过 Servlet 容器实现的请求/应答模型与 Servlet 交互。 -
1.2 什么是 Servlet 容器?
Servlet 容器是 web server 或 application server 的一部分,提供基于请求/响应发送模型的网络服务,解码基 于 MIME 的请求,并且格式化基于 MIME 的响应。Servlet 容器也包含了管理 Servlet 生命周期。 所有 Servlet 容器必须支持基于 HTTP 协议的请求/响应模型,比如像基于 HTTPS(HTTP over SSL)协议的 请求/应答模型可以选择性的支持。容器必须实现的 HTTP 协议版本包含 HTTP/1.0 和 HTTP/1.1。因为容器 或许支持 RFC2616 (HTTP/1.1)描述的缓存机制,缓存机制可能在将客户端请求交给 Servlet 处理之前修改它 们,也可能在将 Servlet 生成的响应发送给客户端之前修改它们,或者可能根据 RFC2616 规范直接对请求 作出响应而不交给 Servlet 进行处理。 -
1.3 一次典型的事件序列:
1、客户端(如 web 浏览器)发送一个 HTTP 请求到 web 服务器; 2、Web 服务器接收到请求并且交给 servlet 容器处理,servlet 容器可以运行在与宿主 web 服务器同一个进 程中,也可以是同一主机的不同进程,或者位于不同的主机的 web 服务器中,对请求进行处理。 3、servlet 容器根据 servlet 配置选择相应的 servlet,并使用代表请求和响应对象的参数进行调用。 4、servlet 通过请求对象得到远程用户,HTTP POST 参数和其他有关数据可能作为请求的一部分随请求一 起发送过来。Servlet 执行我们编写的任意的逻辑,然后动态产生响应内容发送回客户端。发送数据到客户 端是通过响应对象完成的。 5、一旦 servlet 完成请求的处理,servlet 容器必须确保响应正确的刷出,并且将控制权还给宿主 Web 服务 器。
2.Servlet
-
2.1 Servlet 接口
Servlet 接口是 Java Servlet API 的核心抽象。所有 Servlet 类必须直接或间接的实现该接口,或者更通常做法 是通过继承一个实现了该接口的类从而复用许多共性功能。目前有 GenericServlet 和 HttpServlet 这两个类实 现了 Servlet 接口。大多数情况下,开发者只需要继承 HttpServlet 去实现自己的 Servlet 即可。 具体步骤: 1)创建类继承HttpServlet类 2)覆盖doGet和doPost 3)在web.xml中进行servlet的配置 -
2.1 请求处理方法
Servlet 基础接口定义了用于客户端请求处理的 service 方法。当有请求到达时,该方法由 servlet 容器路由到 一个 servlet 实例。 Web 应用程序的并发请求处理通常需要 Web 开发人员去设计适合多线程执行的 Servlet,从而保证 service 方法能在一个特定时间点处理多线程并发执行。(注:即 Servlet 默认是线程不安全的,需要开发人员处理 多线程问题) 通常 Web 容器对于并发请求将使用同一个 servlet 处理,并且在不同的线程中并发执行 service 方法。 -
2.2 Servlet 生命周期
1.Servlet 是按照一个严格定义的生命周期被管理,该生命周期规定了 Servlet 如何被加载、实例化、初始化、 处理客户端请求,以及何时结束服务。该声明周期可以通过 javax.servlet.Servlet 接口中的 init、service 和 destroy 这些 API 来表示,所有 Servlet 必须直接或间接的实现 GenericServlet 或 HttpServlet 抽象类。 2.由 Servlet 容器初始化的某个 Servlet实例在服务期间,可以在其生命周期中不处理任何请求 1)Servlet何时创建 默认第一次访问该servlet时该servlet创建 为什么是“默认”? 因为存在<load-on-startup>配置,可以让服务器一起动就创建servlet对象 语法:<load-on-startup>正整数</load-on-startup> 其中 正整数越小创建对象优先级越高 建议不要将1占用 该servlet对象创建执行init方法 Servlet对象有一个 2)Servlet何时销毁 服务器关闭/从服务器中将web应用移除 销毁servlet对象之前执行destroy方法 3)每次访问必然执行的方法 service方法---每次访问该servlet资源都会执行的方法 -
2.3 web.xml配置servlet
<servlet>
<servlet-name>ServletDemo</servlet-name>
<servlet-class>com.servlet.ServletDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo</servlet-name>
<url-pattern>/servlet</url-pattern>
</servlet-mapping>
url-pattern的配置方式:
三种配置方式:
1) 完全匹配 客户端的访问资源的地址与配置的地址完全一致
2) 目录匹配 语法:以/开始 以*结束
示例:/aaa/bbb/* --- 代表访问/aaa/bbb下的任何资源都匹配
3) 扩展名匹配 语法:以*开始 以扩展名结束
示例:*.abc
注意:第二种与第三种不能混合使用
例如:/aaa/bbb/*.abc ---- 错误的
缺省Servlet(了解)
缺省的servlet:当所有的servlet匹配都不成功时,缺省servlet负责响应
当url-pattern配置成/时,那么该servlet就是缺省的servlet
其实 所有的资源的响应都是通过servlet
-
2.4 ServletContext
1.什么是ServletContext对象 ServletContext:直译servlet的上下文对象,ServletContext就代表一个web应用 ServletContext内部维护着该web应用的一些相关信息 2.怎样获得ServletContext对象 ServletContext context = config.getServletContext() ServletContext context = this.getServletContext(); 3.ServletContext的作用 1.初始化信息 <context-param> <param-name>name</param-name> <param-value>servlet</param-value> </context-param> ServletContext servletContext = getServletContext(); String name = servletContext.getInitParameter("name"); 2.获取文件绝对地址(web应用的下的文件) String realPath = servletContext.getRealPath("WEB-INF/simple.txt"); 3.获取类路径(src)下的文件的绝对地址 String path = ServletDemo.class.getClassLoader().getResource("simple.txt").getPath(); 4.域对象,存储对象 servletContext.setAttribute("key", "value"); String str = (String) servletContext.getAttribute("key"); servletContext.removeAttribute("key");
3.Request
-
3.1.Http请求
Http请求分为部分:请求行,请求头,请求体 请求行:请求方式;请求资源;http协议版本 请求头:http协议参数 请求体:get请求无请求体,post的请求参数存在请求体中 -
3.2.request是对请求参数的封装对象,api中大多数get方法
-
3.3.get和post请求中文乱码的解决方式
request默认查询iso-8859-1码表 post处理方式: request.setCharacterEncoding("UTF-8"),只设置请求体中的编码,所以只能结局post请求中的参数中文乱码情况。 get处理方式 String Key = new String(req.getParameter("Key").getBytes("iso8859-1"),"UTF-8"); -
3.4.域对象
request.setAttribute("key", "value");
String str = (String) request.getAttribute("key");
request.removeAttribute("key");
- 3.5.转发(转发与重定向不能一起使用)
RequestDispatcher requestDispatcher =request.getRequestDispatcher("/servlet2");
requestDispatcher.forward(request, respoinse);
- 3.6.注意
注意:ServletContext域与Request域的生命周期比较?
ServletContext
创建:服务器启动就创建context对象
销毁:服务器关闭
作用范围:整个web应用
Request
创建:请求时创建
销毁:请求结束销毁
作用范围:一次请求链中
注意:转发与重定向的区别?
注意:客户端地址与服务器端地址的写法?
什么是客户端地址:客户端直接访问服务器的地址是客户端地址通过客户端访问web应用 地址必须加上web应用的名称
什么是服务器端地址:web应用内部访问的地址服务器端地址特点,访问时,不用写web应用名称
写地址时怎么区分是否加上web应用的名称看在web应用内还是外
1)直接在地址栏中写url地址 --- 客户端地址
2)a标签的href --- 客户端地址
3)form表单的action-----客户端地址
4)location.href ---- 客户端地址
目前记住一个服务器端地址:转发 --- 服务器端地址
4.Response
-
4.1.Http响应
Http请求分为部分:响应行,响应头,响应体 响应行:http协议版本;返回的状态码;状态码描述 响应头:http协议参数 响应体:请求的响应内容 -
4.2.response是对请求参数的封装对象,api中大多数set,add方法
-
4.3.重定向
1. response.set(302);
response.setHeader("Localhost","/servlet2")
2. response.sendRedirect("/servlet2");
- 4.4.解决中文乱码问题
1.response缓冲区的默认编码是iso8859-1
2.response.setCharacterEncoding("UFT-8") ;设置响应体编码,但是页面还是乱码,是因为页面是GBK解析的
3.response.setContentType("text/html;charset=UTF-8");设置页面解析方式,并包含了response.setCharacterEncoding("UFT-8"),实际开发中只用这一句就可以了
-
4.5 注意
response细节点: 1)response获得的流不需要手动关闭,Tomcat容器会帮助我们关闭 2)getWriter和getOutputStream不能同时调用
5.Cookie&Session
1.Http协议是无状态的,无法记录状态,所有需要会话技术记录状态,所以有了Cookie和Session
2.Cookie:数据存储在客户端本地,减少服务器端的存储的压力,安全性不好,客户端 可以清除cookie
3.Session:将数据存储到服务器端,安全性相对好,增加服务器的压力
4.session基于cookie技术,session内存区域借助于cookie存储内存编号id
cookie
1.Cookie cookie = new Cookie(String cookieName,String cookieValue);
示例:
Cookie cookie = new Cookie("key","vlaue");
那么该cookie会以响应头的形式发送给客户端:Set-Cookie:"key=value"
注意:cookie只能设置非中文
2.设置Cookie在客户端的持久化时间:
cookie.setMaxAge(int seconds);
注意:如果不设置持久化时间,cookie会存储在浏览器的内存中,浏览器关闭cookie信息销毁,如果设置持久化时间,cookie信息会被持久化到浏览器的磁盘文件里
示例:
cookie.setMaxAge(10*60);
设置cookie信息在浏览器的磁盘文件中存储的时间是10分钟,过期浏览器自动删除该cookie信息
3.设置Cookie的携带路径:
cookie.setPath(String path);
注意:如果不设置携带路径,那么该cookie信息会在访问产生该cookie的资源所在的路径下的任何资源都携带cookie信息
示例:
cookie.setPath("/Path");
代表访问Path应用中的任何资源都携带cookie
4.向客户端发送cookie:
response.addCookie(Cookie cookie);
5.删除客户端的cookie:
如果想删除客户端的已经存储的cookie信息,那么就使用同名同路径的持久化时间为0的cookie进行覆盖即可
6.服务器端怎么接受客户端携带的Cookie
cookie信息是以请求头的方式发送到服务器端的:
1)通过request获得所有的Cookie: Cookie[] cookies = request.getCookies();
2)遍历Cookie数组,通过Cookie的名称获得我们想要的Cookie
7.浏览器(客户端)具有自动保存和发送cookie的能力
cookie默认是会话级别的,设置持久化时间是会持久化到磁盘上
session
Session技术是将数据存储在服务器端的技术,会为每个客户端都创建一块内存空间存储客户的数据,但客户端需要每次都携带一个标识ID去服务器中寻找属于自己的内存空间。所以说Session的实现是基于Cookie,Session需要借助于Cookie存储客 户的唯一性标识JSESSIONID
1.获得Session对象
HttpSession session = request.getSession();
此方法会获得专属于当前会话的Session对象,如果服务器端没有该会话的Session 对象会创建一个新的Session返回,如果已经有了属于该会话的Session直接将已有的Session返回
2.session是一个域对象
Session也是存储数据的区域对象,所以session对象也具有如下三个方法:
session.setAttribute(String name,Object obj);
session.getAttribute(String name);
session.removeAttribute(String name);
3.Session对象的生命周期(重点)
创建:
当客户端携带id与服务器端的session区域都对不上号 就创建
销毁:
1)服务器关闭时
2)session过期/失效(默认30分钟)
何时开始计时?
从最后一次访问该web应用计算
可以在工程的web.xml中进行配置
<session-config>
<session-timeout>30</session-timeout>
</session-config>
3)手动销毁session
session.invalidate();
作用范围:
默认在一次会话中,也就是说在,一次会话中任何资源公用一个session对象
4.、三个域对象的生命周期的比较?
ServletContext
创建:服务器启动
销毁:服务器关闭
作用范围:整个web应用
session
创建:本质jsessionid与服务器端的任何session都不匹配时,调用 request.getSession()就创建
销毁:服务器关闭 session失效 手动关闭
作用范围:默认一次会话
request
创建:请求
销毁:请求结束
作用范围:一次请求链
浏览器关闭 对应的session就销毁了?不对
6.listener
1.什么是监听器?
监听器就是监听某个对象的的状态变化的组件 监听器的相关概念:
事件源:被监听的对象,三个域对象 request session servletContext
监听器:监听事件源对象 事件源对象的状态的变化都会触发监听器
响应行为:监听器监听到事件源的状态变化时 所涉及的功能代码
八大监听器:
ServletContext:
域对象创建和销毁: ServletContextListener
域对象属性的变化: ServletContextAttributeListener
HttpSession:
域对象创建和销毁: HttpSessionListener
域对象属性的变化: HttpSessionAttributeListener
ServletRequest:
域对象创建和销毁: ServletRequestListener
域对象属性的变化: ServletRequestAttributeListener
session中的绑定的对象相关的监听器(对象感知监听器)
即将要被绑定到session中的对象有几种状态
绑定状态:就一个对象被放到session域中
解绑状态:就是这个对象从session域中移除了
钝化状态:是将session内存中的对象持久化(序列化)到磁盘
活化状态:就是将磁盘上的对象再次恢复到session内存中
绑定与解绑的监听器HttpSessionBindingListener
钝化与活化的监听器HttpSessionActivationListener
注意:对象感知监听器不需要在web.xml中进行配置
2.监听三大域对象的创建与销毁的监听器
举例:监听ServletContext域的创建与销毁的监听器ServletContextListener
Servlet域的生命周期
何时创建:服务器启动创建
何时销毁:服务器关闭销毁
作用范围:整个web应用
HttpSession对象的生命周期
何时创建:第一次调用request.getSession时创建
何时销毁:服务器关闭销毁 session过期 手动销毁
作用范围:默认一次会话中
ServletRequest的生命周期
创建:每一次请求都会创建request
销毁:请求结束
域对象的通用的方法:
setAttribute(name,value)
--- 触发添加属性的监听器的方法
--- 触发修改属性的监听器的方法
getAttribute(name)
--- 无触发
removeAttribute(name)
--- 触发删除属性的监听器的方法
2)监听器的编写步骤:
a、编写一个监听器类去实现监听器接口
b、覆盖监听器的方法
c、需要在web.xml中进行配置
1.ServletContextListener, HttpSession, ServletRequest
public class ListenerContent implements ServletContextListener{
public void contextInitialized(ServletContextEvent sce) {
System.out.println("init");
}
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("destory");
}
}
web.xnl配置文件
<listener>
<listener-class>cn.servlet.ListenerContent</listener-class>
</listener>
2.钝化与活化的监听器HttpSessionActivationListener
可以通过配置文件 指定对象钝化时间 --- 对象多长时间不用被钝化在META-INF下创建一个context.xml
<Context>
<!-- maxIdleSwap:session中的对象多长时间不使用就钝化 -->
<!-- directory:钝化后的对象的文件写到磁盘的哪个目录下 配置钝化的对象文件在work/catalina/localhost/钝化文件 -->
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="itcast205" />
</Manager>
</Context>
7.Filter
filter是对客户端访问资源的过滤,符合条件放行,不符合条件不放行
步骤:
1)编写一个过滤器的类实现Filter接口
2)实现接口中尚未实现的方法(着重实现doFilter方法)
3)在web.xml中进行配置(主要是配置要对哪些资源进行过滤)
filter生命周期及其与生命周期相关的方法
Filter接口有三个方法,并且这个三个都是与Filter的生命相关的方法
1.init(Filterconfig):代表filter对象初始化方法 filter对象创建时执行
2.doFilter(ServletRequest,ServletResponse,FilterCha):代表filter执行过滤的核心方法,如果某资源在已经被配置到这个filter进行过滤的话,那么每次访问这个资源都会执行doFilter方法。FilterChain:过滤器链对象,通过该对象的doFilter方法可以放行该请求
3.destory():代表是filter销毁方法 当filter对象销毁时执行该方法
Filter对象的生命周期:
Filter何时创建:服务器启动时就创建该filter对象
Filter何时销毁:服务器关闭时filter销毁
public class FilterDemo implements Filter{
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain)
throws IOException, ServletException {
filterChain.doFilter(req, resp);
}
}
<filter>
<filter-name>filterDemo</filter-name>
<filter-class>cn.servlet.FilterDemo</filter-class>
</filter>
<filter-mapping>
<filter-name>filterDemo</filter-name>
<url-pattern>/servlet</url-pattern>
</filter-mapping>
url-pattern配置时
1)完全匹配 /sertvle1
2)目录匹配 /aaa/bbb/* ----最多的
/user/*:访问前台的资源进入此过滤器
/admin/*:访问后台的资源时执行此过滤器
3)扩展名匹配 *.abc *.jsp
注意:url-pattern可以使用servlet-name替代,也可以混用
dispatcher:访问的方式(了解)
REQUEST:默认值,代表直接访问某个资源时执行filter
FORWARD:转发时才执行filter
INCLUDE: 包含资源时执行filter
ERROR:发生错误时 进行跳转是执行filter