一、概述
1、概念
过滤器是一个服务器端的组件,它可以截取客户端的请求和服务端的响应信息,并对这些信息进行过滤。
2、原理:先过滤,后放行
3、应用场景
(1)统一处理中文编码问题
(2)统一处理登陆控制功能
二、如何创建过滤器
方式一:使用web.xml注册过滤器
1.创建一个普通类实现Filter接口
2. 重写Filter接口中的三个方法
3. 在web.xml文件中注册过滤器
package com.ujiuye.filter;
import javax.servlet.*;
import java.io.IOException;
/**
* 1、实现Filter接口
* 2、重写三个方法
* 3、在web.xml注册filter
*/
public class Demo01Filter 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("Demo01Filter的doFilter方法执行了");
//放行
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("Demo01Filter的doFilter方法又执行了");
}
@Override
public void destroy() {
//销毁方法
}
}
<filter>
<filter-name>demo01</filter-name>
<filter-class>com.ujiuye.filter.Demo01Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>demo01</filter-name>
<!--拦截demo01-->
<url-pattern>/demo01</url-pattern>
</filter-mapping>
package com.ujiuye.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/demo01")
public class Demo01Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("demo01servlet执行了");
}
}
方式二:使用注解方式注册过滤器
1.创建一个普通类继承Filter接口
2.重写Filter接口中的三个方法
3.使用注解注册过滤器
这里我们可以直接通过@WebFilter(“/*”)注解的方式进行过滤器的注册。
说明:过滤器常用的路径配置格式有以下三种:
- /*过滤所有的服务器端资源
- *.do表示过滤所有以.do结尾的服务器端资源
- /hello 只能过滤hello这个路径的服务器端资源
跟servlet的拦截路径是一样的
三、 过滤器的生命周期
1.调用 init() 方法初始化实例,在服务器启动时只调用一次;
2.每次访问请求,如果被访问的请求符合过滤条件都会调用 doFilter() 方法进行真正的过滤处理;
3.停止服务器调用 destroy() 方法,销毁实例,释放资源,只执行一次。
package com.ujiuye.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/demo02")
public class Demo02Filter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init方法执行了");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse
servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("demo02Filter");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
System.out.println("销毁的方法执行了");
}
}
四、过滤器的特点
1.一个过滤器可以过滤多个servlet或者请求路径
<filter>
<filter-name>demo03</filter-name>-->
<filter-class>com.ujiuye.filter.Demo03Filter</filter-class>-->
</filter>-->
<filter-mapping>-->
<filter-name>demo03</filter-name>-->
<url-pattern>/demo03</url-pattern>-->
</filter-mapping>-->
<filter-mapping>-->
<filter-name>demo03</filter-name>-->
<url-pattern>/demo03Servlet</url-pattern>-->
</filter-mapping>-->
注解:@WebFilter(urlPatterns = {“/hello”,“/demo.do”})
过滤器默认情况下只过滤重定向的路径,不过滤转发路径
设置过滤转发路径:
- web.xml方式配置:
<filter-mapping>
<!--过滤器名称-->
<filter-name>ThirdFilter</filter-name>
<!--过滤器过滤的路径,如果是/*表示所有资源都要被过滤-->
<url-pattern>/second</url-pattern>
<!--设置过滤转发路径-->
<dispatcher>FORWARD</dispatcher>
<!--设置过滤重定向路径-->
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
- 注解方式配置:
@WebFilter(urlPatterns = {“/one”,“/second”},dispatcherTypes = DispatcherType.FORWARD)
五、使用过滤器实现统一编码
package com.ujiuye.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebListener;
import java.io.IOException;
//@WebFilter("/*")
public class EncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse
servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;charset=utf-8");
//放行
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
六、练习:登录控制
1、创建一个register.jsp login.jsp main.jsp trolley.jsp
RegisterServlet(“/register”) LoginServlet(“/login”)
2、如果是访问登录页面、注册页面、登录请求、注册请求 要放行
如果不是这些请求 判断用户是否登录(user放到session里面) 登录了才放行 没有登录跳转到登录页面
String uri = req.getRequestURI();
package com.ujiuye.filter;
import com.ujiuye.bean.User;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* 登陆拦截思路:
* 访问register.jsp、login.jsp registerServlet loginServlet 直接放行
* 不是上面四个路径,判断是否登陆了没有
* 登陆了 ----- 直接放行
* 没有登陆 ----- 跳转到登陆页面
*/
//@WebFilter("/*")
public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse
servletResponse, FilterChain filterChain) throws IOException, ServletException {
//向下转型
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
//要获取用户请求的路径
String uri = req.getRequestURI();
//System.out.println(uri);///day17/register.jsp
//说明是登陆和注册的操作
if (uri.endsWith("register.jsp") ||uri.endsWith("login.jsp") ||
uri.endsWith("registerServlet") || uri.endsWith("loginServlet"))
{
//直接放行
filterChain.doFilter(req, resp);
} else {
//判断
//获取用户信息
HttpSession session = req.getSession();
User user = (User) session.getAttribute("user");
//说明没有登陆
if(user == null) {
resp.sendRedirect("login.jsp");
}else {
//直接放行
filterChain.doFilter(req, resp);
}
}
}
}
login.jsp:
<%--
Created by IntelliJ IDEA.
User: why
Date: 2022/4/15
Time: 10:15
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="loginServlet">
账号: <input type="text" name="username" value=""> <br>
密码: <input type="text" name="password" value=""> <br>
<input type="submit" value="登陆">
</form>
</body>
</html>
register.jsp:
<%--
Created by IntelliJ IDEA.
User: why
Date: 2022/4/15
Time: 10:15
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="registerServlet">
账号; <input type="text"> <br>
<input type="submit" value="注册">
</form>
</body>
</html>
shoppingcar.jsp:
<%--
Created by IntelliJ IDEA.
User: why
Date: 2022/4/15
Time: 10:15
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
我是购物车
</body>
</html>
main.jsp:
<%--
Created by IntelliJ IDEA.
User: why
Date: 2022/4/15
Time: 10:15
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
我是主页
</body>
</html>
registerServlet:
package com.ujiuye.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/registerServlet")
public class RegisterServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("注册成功");
//只要点击注册就算注册成功
req.getRequestDispatcher("login.jsp").forward(req,resp);
}
}
loginServlet:
package com.ujiuye.servlet;
import com.ujiuye.bean.User;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//接收账号和密码
String username = req.getParameter("username");
String password = req.getParameter("password");
//admin 123
if ("admin".equals(username) && "123".equals(password)) {
User user = new User(username,password);
//登陆成功
req.getSession().setAttribute("user",user);
//跳转到主页
resp.sendRedirect("main.jsp");
}else {
//登陆失败
resp.sendRedirect("login.jsp");
}
}
}
七、总结
1、Filter
配置过滤器 前台----过滤器----servlet/jsp/html-----过滤器----前台
2、创建过滤器
(1)创建一个类 implements javax.servlet.Filter 实现 三个方法 init doFilter destroy
在web.xml 注册 filter filter-mapping
注解 webFilter()
一定要放行 不放行到达不了servlet doFilter方法里面放行
3、生命周期
init 只执行一次 随着tomcat启动就初始化
doFilter 执行多次
destroy 销毁方法 执行一次 tomcat关闭或者重启
4、特点:
(1) 一个过滤器拦截多个请求
web.xml filter 配置多个filter-mapping
注解 webfilter(url-patterns={多个路径})
(2) 过滤器默认只拦截重定向
1、可以配置
web.xml filter-mapping里面配置
dispatcher>REQUEST 拦截重定向
dispatcher>FORWARD 拦截转发
注解
dispatcherTypes ={DispatcherType.FORWARD,DispatcherType.REQUEST})