目录
1、Servlet
关于 Servlet ,之前讲过一小部分关于生命周期和继承关系的内容,具体内容可以看我之前整理的笔记,(尚硅谷)JavaWeb新版教程03-Tomcat-Servlet。
1.1 Sercvlet 初始化方法
- Servlet 生命周期:实例化、初始化、服务、销毁
- Servlet 接口中的定义的初始化方法有一个,它的实现类 GenericServlet 中定义了两个 init() 方法
- 上面是带参数的构造方法,下面是无参的构造方法。
- 如果我们想要在Servlet初始化时做一些准备工作,那么我们可以重写 init 方法
- 我们可以通过如下步骤去获取初始化设置的数据
- 获取 config 对象:
ServletConfig config = getServletConfig();
- 获取初始化参数值:
config.getInitParameter(key);
- 获取 config 对象:
1.2 设置初始化参数的两种方法
1.2.1 在 web.xml 文件中配置 Servlet
在 <servlet> 标签中通过一对 <init-param> 标签可以对初始化参数进行配置,初始化参数包括一对键值对(key-value),代码如下:
<servlet>
<servlet-name>Demo01Servlet</servlet-name>
<servlet-class>com.atguigu.servlet.Demo01Servlet</servlet-class>
<init-param>
<param-name>hello</param-name>
<param-value>world</param-value>
</init-param>
<init-param>
<param-name>uname</param-name>
<param-value>jim</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Demo01Servlet</servlet-name>
<url-pattern>/demo01</url-pattern>
</servlet-mapping>
1.2.2 通过注解的方式配置 Servlet
在 WebServlet 注解中使用 WebInitParam 注解来配置初始化参数:
@WebServlet(urlPatterns = {"/demo01"} ,
initParams = {
@WebInitParam(name="hello",value="world"),
@WebInitParam(name="uname",value="jim")
})
1.3 Servlet 中的 ServletContext 上下文
1.3.1 获取 ServletContext 的方法
- 在重写的初始化方法中:
ServletContext servletContext = getServletContext();
- 在服务方法中也可以通过 request 对象获取,也可以通过 session 获取:
request.getServletContext();
request.getSession().getServletContext();
1.3.2 获取初始化值
通过获取到的 servletContext 来获取上下文定义的初始化参数, servletContext.getInitParameter("你定义的param-name");
1.4 代码示例
public class Demo01Servlet extends HttpServlet {
@Override
public void init() throws ServletException {
ServletConfig config = getServletConfig();//获取配置
String initValue = config.getInitParameter("hello");//获取配置参数
System.out.println("initValue = " + initValue);
ServletContext servletContext = getServletContext();
String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");
System.out.println("contextConfigLocation = " + contextConfigLocation);
}
}
web.xml 配置文件中的信息:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>Demo01Servlet</servlet-name>
<servlet-class>com.atguigu0.servlet.Demo01Servlet</servlet-class>
<init-param>
<param-name>hello</param-name>
<param-value>world</param-value>
</init-param>
<init-param>
<param-name>uname</param-name>
<param-value>jim</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Demo01Servlet</servlet-name>
<url-pattern>/demo01</url-pattern>
</servlet-mapping>
控制台输出:
2、Filter 过滤器
Filter 也属于 Servlet 规范
2.1 过滤器三要素
1.对某些请求进行拦截
过滤器之所以能够对请求进行预处理,关键是对请求进行拦截,把请求拦截下来才能够做后续的操作。而且对于一个具体的过滤器,它必须明确它要拦截的请求,而不是所有请求都拦截。
-
过滤
根据业务功能实际的需求,看看在把请求拦截到之后,需要做什么检查或什么操作,写对应的代码即可。 -
放行
过滤器完成自己的任务或者是检测到当前请求符合过滤规则,那么可以将请求放行。所谓放行,就是让请求继续去访问它原本要访问的资源。
2.2 过滤器生命周期
和 Servlet 生命周期类比,Filter生命周期的关键区别是:在 Web 应用启动时创建对象
过滤器生命周期:
Servlet 生命周期:
2.3 Filter 开发步骤
-
新建类实现 Filter 接口,然后实现其中的三个方法:init、doFilter(放行方法)、destroy
-
配置 Filter,可以用注解
@WebFilter
,也可以使用xml
文件中的<filter> <filter-mapping>
注解方式:
@WebFilter("*.do")
web.xml 配置文件方式:
<filter>
<filter-name>Demo01Filter</filter-name>
<filter-class>com.atguigu1.filters.Demo01Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>Demo01Filter</filter-name>
<url-pattern>/demo01.do</url-pattern>
</filter-mapping>
- Filter 在配置时,和 servlet 一样,也可以配置通配符,例如 @WebFilter(“*.do”) 表示拦截所有以 .do 结尾的请求。
2.4 过滤器链
- 如果采取的是
注解
的方式进行配置,那么过滤器链的拦截顺序是按照全类名的先后顺序排序的(按照文件排序先后顺序) - 如果采取的是
xml
的方式进行配置,那么按照配置的先后顺序进行排序
代码示例:
Filter01 代码:
@WebFilter("*.do")
public class Filter01 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("A");
//放行
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("A2");
}
@Override
public void destroy() {}
}
Filter02 代码,其中的 doFilter 重写方法不一样:
@WebFilter("*.do")
public class Filter02 implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("B");
//放行
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("B2");
}
}
Filter03 代码:
@WebFilter("*.do")
public class Filter03 implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("C");
//放行
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("C2");
}
}
Demo01Servlet 代码:
@WebServlet("/demo01.do")
public class Demo01Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo01 service.....");
//内部转发
request.getRequestDispatcher("succ.html").forward(request,response);
}
}
控制台输出:
3、Listener 监听器
3.1 常见的监听器
-
ServletContextListener - 监听 ServletContext 对象的创建和销毁的过程
-
HttpSessionListener - 监听 HttpSession 对象的创建和销毁的过程
-
ServletRequestListener - 监听 ServletRequest 对象的创建和销毁的过程
-
ServletContextAttributeListener - 监听 ServletContext 的保存作用域的改动(add,remove,replace)
-
HttpSessionAttributeListener - 监听 HttpSession 的保存作用域的改动(add,remove,replace)
-
ServletRequestAttributeListener - 监听 ServletRequest 的保存作用域的改动(add,remove,replace)
-
HttpSessionBindingListener - 监听某个对象在 Session 域中的创建与移除
-
HttpSessionActivationListener - 监听某个对象在 Session 域中的序列化和反序列化
3.2 监听器开发步骤
-
以 ServletContextListener 为例,新建类实现 ServletContextListener 接口,然后重写其中的两个方法:contextInitialized 和 contextDestroyed 方法,一个是在上下文初始化时候,一个是在上下文销毁的时候。
-
配置 Listener,可以用注解
@WebListener
,也可以使用xml
文件中的<listener>
标签
注解方式:
@WebListener
web.xml 配置文件方式:
<listener>
<listener-class>com.atguigu1.listener.MyServletContextListener</listener-class>
</listener>
3.3 监听器代码示例
@WebListener
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("Servlet上下文对象初始化动作被我监听到了....");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("Servlet上下文对象销毁动作被我监听到了.....");
}
}
控制台输出:
3.4 监听器的一个常见应用
监听上下文启动,在上下文启动的时候去创建 IOC 容器,然后将其保存到 application 作用域,后面中央控制器再从 application 作用域中去获取 IOC 容器。(后序用 MVC 优化 fruit 后台管理系统的时候会提到)