Servlet学习详解--基本涵盖所有Servlet知识点
目录
- 一、Servlet
- 二、 Servlet入门
- 2.1. 执行原理
- 2.2. 实现Servlet接口重写其五个方法及其生命周期
- 三、Request请求对象
- 3.1. 获取请求消息数据
- 3.2. 获取请求头数据
- 3.3. 获取请求体数据
- 3.4. 设置编码
- 3.5. 其他通用功能
- 3.6. 请求转发(Forward)
- 3.7. 转发共享数据
- 四、Response对象
- 4.1. response常用方法
- 4.2. 重定向
- 五、ServletContext对象
- 5.1 ServletContext对象获取方式
- 5.2 获取MIME类型
- 5.2 共享数据
- 六、Cookie对象
- 6.1 Cookie介绍
- 6.2 Cookie实现原理
- 6.3 实现方式
- 6.4 Cookie的细节
- 七、Session对象
- 7.1 Session介绍
- 7.2 实现原理
- 7.3 Session实现
- 7.4 Session的细节
- 7.5 Session的特点
- 八、过滤器
- 8.1 基本介绍
- 8.2 过滤器实现原理
- 8.3 实现步骤
- 8.4 过滤器的生命周期
- 8.5 过滤器配置
- 8.6 过滤链(多个过滤器)
一、Servlet
- Servlet(Server Applet),全称Java Servlet。是用Java编写的服务器端程序,其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。
- Servlet运行于支持Java的应用服务器中。从实现上讲,Servlet可以响应任何类型的请求,但绝大多数情况下,Servlet只用来扩展基于HTTP协议的Web服务器
- Servlet工作模式:
① 客户端发送请求至服务器
②服务器启动并调用Servlet,Servlet根据客户端请求生成响应内容并将其传给服务器
③ 服务器将响应返回客户端
二、 Servlet入门
编写Servlet类
//@WebServlet("/demo03")
//使用继承Servlet接口的方式
public class ServletDemo01 implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("这里是初始化方法");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("service执行了......");
}
@Override
public String getServletInfo() {
return "()";
}
@Override
public void destroy() {
System.out.println("这里是销毁方法");
}
}
//@WebServlet("/demo02")
//使用继承GenericServlet类的方式
public class ServletDemo02 extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("service方法执行了");
}
}
//@WebServlet("/demo03")
//使用继承HttpServlet的方式
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("执行了doget");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml配置文件
<servlet>
<!--Servlet的自定义名称-->
<servlet-name>demo01</servlet-name>
<!--Servlet资源的全限定路径-->
<servlet-class>com.aoyezongguanjun.servlet.ServletDemo01</servlet-class>
</servlet>
<servlet-mapping>
<!--资源对应的Servlet-->
<servlet-name>demo01</servlet-name>
<!--资源路径-->
<url-pattern>/demo01</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>demo02</servlet-name>
<servlet-class>com.tencent.servlet.ServletDemo02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo02</servlet-name>
<url-pattern>/demo02</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>demo03</servlet-name>
<servlet-class>com.tencent.servlet.ServletDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo03</servlet-name>
<url-pattern>/demo03</url-pattern>
</servlet-mapping>
2.1. 执行原理
- 当服务器收到客户端发送的请求后,会解析对应的URL路径,获取访问的
Servlet的资源路径名称
。 - tomcat会查询web.xml配置文件,
<url-pattern>
内配置对应Servlet资源路径名称,并且根据<servlet-name>
的配置拿到Servlet类的全限定类名
。 - tomcat根据Servlet的全限定类名通过
反射获取Servlet对象
,然后调用其方法。
2.2. 实现Servlet接口重写其五个方法及其生命周期
init( )
:初始化方法
,当访问该servlet时会调用一次。注:该方法只会被调用一次
,通常用于加载资源。我们在<servlet>
标签下配置<load-on-startup>
标签可以改变init()执行的时机,当配置的是0或正整数时,第一次被访问时才执行,当配置负数时,服务器启动时,就会执行该方法。由init()方法只被执行一次说明Servlet是单例的,可能存在线程安全问题。service()
:处理或响应客户端请求时执行
,每访问都会调用该方法。destroy()
:销毁方法
,服务器正常关闭时,会调用该方法,通常用于释放资源,该方法只会被调用一次
。getServletInfo()
:该方法用于获取 servlet 容器的名称和当前版本的信息。getServletConfig( )
:获取servlet配置对象。@WebServlet
注解
在Servlet3.0后支持注解配置Servlet,不再需要web.xml文件了,可以使用该注解将进行配置,配置方式@WebServlet("资源路径")
。- HttpServlet的doGet和doPost的执行原理。
HttpServlet继承了GenericServlet
类,实质还是重写了Service方法,只是会根据不同的请求方式调用不同的方法。
三、Request请求对象
Request对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。简单来说,要得到浏览器信息,就找
HttpServletRequest
对象。
3.1. 获取请求消息数据
- 获取请求方式:
String getMethod()
- 获取请求虚拟路径:
String getContextPath()
- 获取servlet路径:
String getServletPath()
- 获取get请求方式参数:
String getQueryString()
- 获取请求URI:
String getRequestURI()
- 获取请求URL:
StringBuffer getRequestURL()
- 获取协议及版本:
String getProtocol()
- 获取客户机的IP地址:
String getRemoteAddr()
3.2. 获取请求头数据
- 获取请求头:
String getHeader(String name)
- 获取所有请求头的名称:
Enumeration<String> getHeaderNames()
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //请求地址:http://localhost:8080/contextPath/demo03?username=zhangsan String method = req.getMethod(); System.out.println(method);//GET String contextPath = req.getContextPath(); System.out.println(contextPath);// /contextPath String servletPath = req.getServletPath(); System.out.println(servletPath);// /demo03 String queryString = req.getQueryString(); System.out.println(queryString);// username=zhangsan String requestURI = req.getRequestURI(); System.out.println(requestURI);// /contextPath/demo03 StringBuffer requestURL = req.getRequestURL(); System.out.println(requestURL.toString());// http://localhost:8080/contextPath/demo03 String protocol = req.getProtocol(); System.out.println(protocol);// HTTP/1.1 String remoteAddr = req.getRemoteAddr(); System.out.println(remoteAddr);// 0:0:0:0:0:0:0:1,由于这里是本地调用,如果是其他客户端调用会返回对应的IP地址 String header = req.getHeader("user-Agent"); System.out.println(header);// PostmanRuntime/7.26.8 Enumeration<String> headerNames = req.getHeaderNames(); List<String> headerNameList = new ArrayList<>(); while (headerNames.hasMoreElements()){ headerNameList.add(headerNames.nextElement()); } System.out.println(String.join(";",headerNameList));//user-agent;accept;postman-token;host;accept-encoding;connection }
3.3. 获取请求体数据
BufferedReader getReader()
:获取字符输入流,只能操作字符数据ServletInputStream getInputStream()
:获取字节输入流,可以操作所有类型数据
3.4. 设置编码
setCharacterEncoding("utf-8")
3.5. 其他通用功能
获取请求头参数通用方式,不论get还是post请求方式都可以使用下列方法来获取请求参数
- 根据参数名称获取对应的参数值:
String getParameter(String name)
- 根据参数名称获取参数值的数组:
String[] getParameterValues(String name)
- 获取所有请求的参数名称:
Enumeration<String> getParameterNames()
- 获取所有参数的map集合:
Map<String,String[]> getParameterMap()
3.6. 请求转发(Forward)
- 工作原理:转发是在服务器内部进行的,用户发送的请求由一个Servlet接收后,可以将请求内部转发给另一个Servlet或JSP处理,最终将处理结果返回给用户。对于用户而言,他们
只发出了一次请求,也只收到了一次响应
。 - URL保持不变:因为转发是在服务器内部进行的,所以用户浏览器的地址栏
URL不会发生变化
。 - 性能较高:转发不涉及到客户端的重新请求,因此通常比重定向快。
- 共享请求数据:在转发过程中,原始请求和响应对象保持不变,
可以共享请求中的数据
。 - 实现步骤:
- 通过request对象获取请求转发器对象:
RequestDispatcher
,getRequestDispatcher(String path)
- 使用
RequestDispatcher
对象来进行转发:forward(ServletRequest request,ServletResponse response)
- 请求转发的特点:浏览器地址栏路径不发生变化;只能转发到当前服务器内部资源中;转发是一次请求。
req.getRequestDispatcher("/demo01").forward(req,resp);
- 通过request对象获取请求转发器对象:
3.7. 转发共享数据
-
域对象:一个有作用范围的对象,可以在范围内共享数据
当浏览器访问浏览器时,如果服务器需要进行请求转发,服务器会转发到指定资源,注意这次是服务器转发的,用户端浏览器没有任何感知,如果需要在转发时共享数据,可以先将数据存储在Servlet转发域中,将来转发请求指定资源时,可以去转发域中获取共享的数据。转发资源响应后,再响应到浏览器中,该转发共享域也随之销毁。 -
Request域:一般用于请求转发的多个资源中共享数据,Request域的作用范围是一次请求。
-
方法:
void setAttribute(String name,Object obj)
:存储数据Object getAttitude(String name)
:通过键获取值void removeAttribute(String name)
:通过键移除键值对
四、Response对象
Response是Web应用程序用来封装向客户端响应信息的,是Servlet接口的service()方法的一个参数,类型为javax.servlet.http.HttpServletResponse。客户端每次发送请求时,服务器都会创建一个Response对象,并传递给Servlet接口的service()方法,来完成向客户端的响应工作。
4.1. response常用方法
- 设置响应状态码:
setStatus(int httpStatusCode)
- 设置响应头
setHeader(String name,String value)
//以附件形式打开响应体,可以进行文件下载,并且指定文件名称 resp.setHeader("content-disposition","attachment;filename=xxxxxx");
setContentType(String MIME)
//设置content-type响应头,告诉浏览器,以json的格式进行解析,且编码方式是utf-8 resp.setContentType("text/json;charset=utf-8");
- 设置响应体
- 获取字符输出流
PrintWriter getWriter()
,获取的流的默认编码方式是ISO-8859-1
/** * 输出字符到浏览器 */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //表示将response的流编码方式为utf-8,且告诉浏览器以json格式解析数据,并且浏览器也是以utf-8编码方式解析数据 resp.setContentType("text/json;charset=utf-8"); User user = new User(); user.setUsername("张三"); String json = JSONArray.toJSONString(user); resp.getWriter().println(json); }
- 获取字节输出流
ServletOutputStream getOutputStream()
/** * 实现文件下载 */ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { ServletContext servletContext = req.getServletContext(); String imagePath = servletContext.getRealPath("/img/JR史密斯.jpg"); String mimeType = servletContext.getMimeType(imagePath); resp.setHeader("content-type",mimeType); //读取文件,获取文件输出流 InputStream inputStream = new FileInputStream(imagePath); //获取response字节流 ServletOutputStream respOutputStream = resp.getOutputStream(); //建立缓冲区 byte[] buffer = new byte[1024 * 8]; int len = 0; //读写文件 while ((len = inputStream.read(buffer)) != -1){ respOutputStream.write(buffer,0,len); } inputStream.close(); String fileName = URLEncoder.encode("JR史密斯" + System.currentTimeMillis(), "UTF-8").replaceAll("\\+", "%20"); //设置响应体 resp.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".jpg"); }
- 获取字符输出流
4.2. 重定向
在Java Web开发中,重定向(Redirect)是一种常见的技术,用于将用户从一个URL地址自动重定向到另一个URL地址。这在很多情况下都非常有用,例如在用户登录后将其重定向到其个人资料页面,或者在进行某些操作后将其重定向到一个感谢页面。它通常用于以下情况:
- 将用户从一个页面引导到另一个页面。
- 更改或更新URL以反映新的资源位置。
- 处理用户登录后的跳转。
重定向可以是临时的或永久的。临时重定向(HTTP状态码为302)通常用于暂时将用户导向另一个地址,而永久重定向(HTTP状态码为301)则表示资源已永久移动到新的URL地址。
浏览器请求服务器指定资源,如果该资源需要进行重定向,会将这次请求的响应码设置为302
,且响应头location设置为重定向路径地址。当浏览器收到响应后,会解析location设置的重定向路径地址,然后重新发起一次新的请求
去请求指定资源。
重定向实现:
@WebServlet("/AServletDemo ")
public class AServletDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// resp.setStatus(302);
// resp.setHeader("location",req.getContextPath()+"/BServletDemo");
//或者使用sendRedirect方法
//跳转路径规则:判断定义的路径是给谁用的?判断请求将来从哪儿发出
//给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
//给服务器使用:不需要加虚拟目录
resp.sendRedirect(req.getContextPath()+"/BServletDemo");
}
}
重定向的特点:
- 重定向是
两次请求
,两次响应。 - 重定向前后,浏览器的
地址栏会发生变化
。 - 重定向前后的request对象不是同一个,所以不能使用request对象来共享域。
- 重定向前后的两个资源可以是来自不同的web应用,甚至可以是不同的服务器。
五、ServletContext对象
ServletContext是Servlet规范中的一个对象,它代表了当前Web应用程序的上下文(Context)。这个上下文包括了整个Web应用程序的信息,可以被Web应用中的所有Servlet共享。可以将ServletContext看作是一个全局存储区,用于存储和访问Web应用中的全局数据和资源。可以读取全局配置参数,搜索当前工程目录下面的资源文件等。
5.1 ServletContext对象获取方式
- 通过Request对象获取
ServletContext servletContext = req.getServletContext();
- 通过HttpServlet获取
@WebServlet("/demo04")
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
ServletContext servletContext = this.getServletContext();
}
5.2 获取MIME类型
MIME类型
:在互联网通信过程中定义的一种文件数据类型,浏览器通常使用MIME类型(而不是文件扩展名)来确定如何处理URL,因此Web服务器在响应头中添加正确的MIME类型非常重要。如果配置不正确,浏览器可能会曲解文件内容,网站将无法正常工作,并且下载的文件也会被错误处理。比如给浏览器返回Json格式数据,MIME类型就是application/json
,给浏览器返回excel的xlsx格式表格,MIME类型就是application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
。
- 实现方法:
String getMimeType(String fileName)
String mimeType = this.getServletContext().getMimeType("列表.xlsx");
5.2 共享数据
ServletContext
域:在整个Web应用程序中共享数据,所有Servlet都可以访问。- 一旦获得了
ServletContext
对象,您可以使用其域对象来存取数据。这可以通过以下方法之一来完成-
setAttribute(String name,Object value)
:其中name是存储数据的名称,value是数据的值。servletContext .getServletContext().setAttribute("name","zhangsan");
-
getAttribute(String name)
:获取数据。String name = (String)servletContext.getServletContext().getAttribute("name");
-
removeAttribute(String name)
:删除数据servletContext.getServletContext().removeAttribute("name");
-
使用init-param元素在web.xml文件中配置全局参数,以供整个Web应用程序使用。
-
- ServletContext共享域生命周期
ServletContext域的生命周期与Web应用程序的生命周期相同。它在Web应用程序启动时创建,而在Web应用程序关闭时销毁。这意味着在Web应用程序启动期间存储的数据将在整个应用程序的生命周期内保持不变。由于ServletContext域的数据在整个Web应用程序中可见,因此要小心确保不要意外覆盖或混淆数据。
- 获取文件(服务器文件)的真实路径
String getRealPath(String path)
//web目录下资源访问 String b = servletContext.getRealPath("/b.txt"); //WEB-INF目录下的资源访问 String c = servletContext.getRealPath("/WEB-INF/c.txt"); //src目录下的资源访问 String a = servletContext.getRealPath("/WEB-INF/classes/a.txt");
六、Cookie对象
6.1 Cookie介绍
Cookie 是一种在网站和应用程序中用于存储用户信息的小型文本文件。在一次会话的范围内的多次请求间,共享数据。当用户访问一个网站或应用程序时,该网站或应用程序会将一个包含用户信息的 Cookie 发送到用户的浏览器。浏览器会将该 Cookie 存储在用户的计算机上,并在以后的访问中将该 Cookie 发送回网站或应用程序。
虽然 Cookie 对于提供个性化体验和方便用户来说非常有用,但它们也引发了一些隐私和安全问题。例如,第三方 Cookie 可以用于跟踪用户在多个网站上的活动,可能会侵犯用户的隐私。出于隐私和安全的考虑,现代浏览器通常允许用户控制哪些 Cookie 被接受和存储,并提供了清除 Cookie 的选项。
会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止,一次会话中包含多次请求和响应。
6.2 Cookie实现原理
浏览器第一次请求服务器,服务器如果需要设置Cookie,会在响应头添加set-cookie的响应头,值为键值对形式。如set-cookie:key=name。当浏览器收到服务器响应,会去查询是否有set-cookie的响应头,如果有会将响应头的值存储在浏览器中。当浏览器再次访问该服务器时,会自定将cookie以请求头的格式发送给服务器,具体格式为cookie:key=value。服务器收到请求后,如果需要获取cookie,可以解析请求头进行获取。
6.3 实现方式
添加cookie
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建cookie对象
Cookie cookie1 = new Cookie("username","zhangsan");
Cookie cookie2 = new Cookie("username2","zhangsan");
//添加到响应头
resp.addCookie(cookie1);
resp.addCookie(cookie2);
}
获取cookie
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取cookie
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
System.out.println(cookie.getName()+"="+cookie.getValue());
}
}
6.4 Cookie的细节
- Cookie一次可以创建多个,创建多个cookie后请求头携带Cookie的格式为
Cookie:username=zhangsan; username2=zhangsan
- Cookie的存活时长默认是浏览器关闭后,Cookie数据被销毁,我们也可以使用
cookie.setMaxAge(int seconds)
执行cookie的存活时间,当浏览器关闭后,会自动持久化到浏览器中,其中seconds参数正数表示存活时长(s)。负数(默认值)表示浏览器关闭后自动销毁。零表示立即删除cookie消息。 - 在tomcat8之前,Cookie中不能直接存储中文数据,一般需要使用URL编码,在tomcat8之后,cookie支持中文数据,但是特殊字符还是不支持,建议使用URL编码存储,使用URL编码解析。
- 默认情况下一个服务器下多个web项目Cookie是不能共享的,如果需要共享可以使用
cookie.setPath(String path)
设置Cookie的获取范围,默认情况是设置当前的虚拟目录,如果需要共享可以将path设置为"/"
。如果多个tomcat服务器之间需要共享Cookie,可以使用cookie.setDomain(String path)
实现,如果设置一级域名相同,那么可以实现共享Cookie。如 setDomain(“.baidu.com”),那么tieba.baidu.com和news.baidu.com中cookie可以共享。 - 浏览器对于单个Cookie
大小限制4kb
,对于同一个域名下cookie总数限制20个
。 - 由于Cookie是存储在用户浏览器中,所以数据安全性并不高。一般用于存储用户少量不太敏感的数据,比如用户的登录信息和电商平台在不登陆的情况下加入购物车等功能。
七、Session对象
7.1 Session介绍
session在网络应用中称为“会话控制”,是服务器为了保存用户状态而创建的一个特殊的对象。简而言之,session就是一个对象,用于存储信息。 Session类似于一个Map,里面可以存放多个键值对,是以key-value进行存放的。key必须是一个字符串,value是一个对象
7.2 实现原理
当浏览器第一次发送请求时,服务器会自动创建一个Session对象放到内存中,并且指定唯一sessionId,响应时服务器会将这个唯一的sessionId以响应cookie的方式响应给浏览器并且储存在浏览器。当浏览器第二次访问服务器时,服务器会解析请求头是否携带这个cookie,如果携带会根据cookie的sessionId去寻找执行sessionId的Session对象。
7.3 Session实现
向Session中存储数据。
HttpSession session = req.getSession();
List<User> users = new ArrayList<User>();
User user = new User();
user.setUsername("use1");
users.add(user);
session.setAttribute("users",users);
向Session中获取数据
HttpSession session = req.getSession();
List<User> userList = (List<User>) session.getAttribute("users");
7.4 Session的细节
-
当客户端关闭后,两次获取的Session并不是同一个对象,如果需要获取的是同一个对象,可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。
Cookie c = new Cookie("JSESSIONID",session.getId()); c.setMaxAge(60*60); response.addCookie(c);
-
当浏览器关闭时,为防止session丢失,tomcat在关闭之前,会将Session钝化,即将Session对象存储到硬盘上,在tomcat启动后,可以将其活化,即读取硬盘重新加载到内存中。
-
Session在
30分钟后默认失效
,或者使用session的invalidate()
方法对session里的内容进行清空。我们也可以修改session的默认失效时间<session-config> <session-timeout>30</session-timeout> </session-config>
7.5 Session的特点
- session用于存储一次会话的多次请求,是存储在服务器中的。
- session相对cookie来说相对安全
- session的数量个数和数据的大小没有限制。
八、过滤器
8.1 基本介绍
过滤器,顾名思义就是对事物进行过滤的,在Web中的过滤器,当然就是对请求进行过滤,我们使用过滤器,就可以对请求进行拦截,然后做相应的处理,实现许多特殊功能。如登录控制,权限管理,过滤敏感词汇等。
8.2 过滤器实现原理
当服务器接受到浏览器发送请求,会根据请求资源路径和过滤器@WebFilter
配置的拦截进行匹配,当匹配不通过会绕过拦截器直接访问目标资源。当匹配通过时进入过滤器执行doFilter方法,这里可以进行一些前置逻辑判断,当符合某些放行规则后,可以使用filterChain.doFilter(request,response)
方法进行放行,访问完目标资源后,再次进入过滤器执行放行后的代码,最后响应浏览器。细节:过滤器Filter是在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后。
8.3 实现步骤
- 基于注解配置过滤器
@WebFilter("/user/*")
public class ServletFilter1 implements Filter {
//初始化方法
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
//拦截方法
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
System.out.println("ServletFilter1拦截器进行拦截了......");
//放行
filterChain.doFilter(request,response);
System.out.println("执行之后......");
}
//销毁方法
@Override
public void destroy() {
Filter.super.destroy();
}
}
- 基于web.xml配置过滤器
<filter>
<filter-name>demo1</filter-name>
<filter-class>com.aoyezongguanjun.filter.ServletFilter1</filter-class>
</filter>
<filter-mapping>
<filter-name>demo1</filter-name>
<!-- 拦截路径 -->
<url-pattern>/user/*</url-pattern>
</filter-mapping>
@WebFilter("/user/*")
public class ServletFilter1 implements Filter {
//初始化方法
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
//拦截方法
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
System.out.println("ServletFilter1拦截器进行拦截了......");
//放行
filterChain.doFilter(request,response);
System.out.println("执行之后......");
}
//销毁方法
@Override
public void destroy() {
Filter.super.destroy();
}
}
8.4 过滤器的生命周期
init
:在服务器启动后,会自动创建Filiter对象,然后调用init方法,该方法只执行一次
,一般用于加载资源。doFIlter
:每次请求拦截时候,都会执行该方法。destroy
:在服务器正常关闭后,Filter对象会被销毁,销毁前调用destroy方法,该方法只会执行一次
,通常用于释放资源。
8.5 过滤器配置
- 具体路径资源:/user/servletDemo1 只有访问/user/servletDemo1时,过滤器才会执行。
- 拦截目录:/user/* 访问/user下的所有资源时,过滤器才会执行。
- 后缀名拦截:*.jsp 访问所有后缀名为jsp资源时,过滤器才会执行。
- 拦截所有资源:/* 访问所有资源过滤器都会执行。
- 拦截方式配置:可以设置dispatcherTypes属性
REQUEST
:默认值。浏览器直接请求资源FORWARD
:转发访问资源
*INCLUDE
:包含访问资源ERROR
:错误跳转资源ASYNC
:异步访问资源
- 可以使用web.xml的
<dispatcher>
标签配置过滤方式配置。
8.6 过滤链(多个过滤器)
- 当配置了多个过滤器匹配访问资源时候,如过滤器1和过滤器2匹配过滤,执行顺序为过滤器1->过滤器2->执行资源->过滤器2->过滤器1
- 当配置多个过滤器后,默认会按照类名的字符串比较,值小的优先执行。如果使用的是web.xml的方式执行,优先配置的先执行。