目录
一:Filter介绍
Filter是JavaWeb三大组件之一,中文称为过滤器,是一个接口,可以访问静态资源和动态资源,既可以过滤请求也可以过滤响应。
在JavaEE的官方文档中,我们也可以查阅到Filter是一个接口
Filter的应用场景:
1.解决Post请求中午乱码问题(全战)
2.敏感字符过滤(将不利团结的话过滤为*****)
3.登录权限进行校验
二:Filter快速开发步骤
1.定义过滤器类实现Filter接口
2.再自定义类中实现过滤器接口中的所有的抽象方法
3.在foFilter方法体中书写拦截资源代码
4.配置过滤器
5.访问被拦截资源
用代码实现快速开发Filter步骤
第一到三步:
package it.lcyy;
import javax.servlet.*;
import java.io.IOException;
public class Filter01 implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("哈哈哈哈哈 我是过滤网");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Filter.super.init(filterConfig);
}
@Override
public void destroy() {
// Filter.super.destroy();
}
}
注意:在自定义类中init方法的 Filter.super.init(filterConfig) 和 Filter.super.destroy()不能调用否则会报错
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Filter.super.init(filterConfig);
}
@Override
public void destroy() {
// Filter.super.destroy();
}
第四步:配置过滤器
在配置过滤器中有两种方法,第一种就是配置web.xml文件,如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<filter>
<filter-name>Filter01</filter-name>
<filter-class>it.lcyy.Filter01</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter01</filter-name>
<url-pattern>/demo01.html</url-pattern>
</filter-mapping>
</web-app>
注意: <url-pattern>/demo01.html</url-pattern> 这里配置的是当前过滤器要过滤的资源路径,在这里我使用的是在webapp下的demo01.html文件,如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>haahh1</title>
</head>
<body>
<h1>我是被过滤掉的资源</h1>
</body>
</html>
第二种方法是用注解方式配置过滤器(注解方式是为了简化代码的开发,但是不利于理解原理)
package it.lcyy;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/demo01.html")
public class Filter02 implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("哈哈哈哈哈 我是过滤网");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Filter.super.init(filterConfig);
}
@Override
public void destroy() {
// Filter.super.destroy();
}
}
三:Filter生命周期
1.启动Tomcat时,Toncat调用过滤器类的无参构造方法创建过滤类对象
2.使用过滤器对象调用 init 方法初始化
3.每次访问资源时都要执行 doFilter 方法
4.关闭Tomcat服务器前都调用 destory 方法
四:拦截路径
在开发中,可以通过指定的拦截路径来定义拦截目标资源的范围
1.精准匹配:
用户访问指定资源(/demo01.html)时,过滤器进行拦截
2.目录匹配:
用户访问指定目录(/user/)所有资源时,过滤器进行拦截
3.后缀匹配:
用户访问指定后缀名(*.html)的资源时,让过滤器进行拦截,注意:不能加 /
4.匹配所有:
用户访问网站所有资源(/*)时,然过滤器进行拦截
五:Filter案例:
1.请求中文乱码问题(全站)
1.首先,我们在包下建立一个Servlet类和一个Filter类,如下:
然后再Filter_01类中书写请求和响应的代码
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/*")//表示拦截所有资源
public class Filter_01 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Filter.super.init(filterConfig);
}
@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 destroy() {
// Filter.super.destroy();
}
}
再在Servlet类中书写业务代码
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/demo01.html")//
public class Servlet_01 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理请求参数
String username = req.getParameter("username");
System.out.println("username"+username);
//响应给浏览器
resp.getWriter().print("是真的吗?");
}
}
再在webapp下书写html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="demo01.html" method="post">
<input type="text" name="username"><br>
<input type="submit">
</form>
</body>
</html>
于是启动tomcat服务器
我们可以看到已经解决了post请求中文乱码问题了
2.登录权限校验
1.登录之后,能够访问hack.html,然后下载购物车资源
2.未登录,跳转到登陆页面
3.Filter对hack.html页面进行过滤
1.首先先建立框架,在src下的filter_test包建立Filter_02 Filter类和Servler_02 Servlet类和实体类User,并在webapp下建立hack.html页面和login.html页面,如下图:
2.之后在书写各方面的业务代码
<1> 书写hack.html页面内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>
购物车。。。。。。
</h1>
<a href="javascript:;">购买购车资源</a>
</body>
</html>
<2>书写login.html页面内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="login.html" method="post">
用户名<input type="text" name="username"><br>
密码<input type="password" password="password"><br>
<input type="submit" value="登录">
</form>
</body>
</html>
<3>书写User实体类内容
public class User {
private String name;//用户名
private String passeord;//密码
public User(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPasseord() {
return passeord;
}
public void setPasseord(String passeord) {
this.passeord = passeord;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", passeord='" + passeord + '\'' +
'}';
}
}
<4>书写Servlet_02内容
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("/login.html")
public class Servlet_02 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取请求参数
String name = req.getParameter("name");
String password = req.getParameter("password");
//2.创建User对象
User user = new User();
//3.封装数据
user.setName("name");
user.setPasseord("password");
//TODO:实际开发中,将user对象传递到业务层交给数据库查询
//4.假设这里用户名和密码都是正确的,将user对象放在Session中
req.getSession().setAttribute("u",user);
//跳转到hack.html页面
resp.sendRedirect("/hack.html");
}
}
<5>书写过滤类Filter_02内容
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter("/hack.html")//过滤hack.html资源
public class Filter_02 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//1.从Session中获取对象
User u = (User) request.getSession().getAttribute("u");
//2.判断u
if(u == null){
//3.说明没有登陆,跳转到登陆页面
response.sendRedirect("/login.html");
}else{
//4.u不为空,说明登陆成功,放行资源
filterChain.doFilter(request, response);
}
}
@Override
public void destroy() {
// Filter.super.destroy();
}
}
注意:在filter_02中无需再对post请求乱码问题进行书写,因为在同一包下的Filter_01中,我们已经对中文乱码问题进行了解决。
六:总结
简单来说过滤器是一个可以传送请求或修改响应的对象。
过滤器并不是servlet,他们并不实际创建一个请求。他们是请求到达一个servlet前的预处理程序或响应离开servlet后的后处理程序。
因此过滤器能够:
1·在一个servlet被调用前截获该调用
2·在一个servlet被调用前检查请求
3·修改在实际请求中提供了可定制请求对象的请求头和请求数据
4·修改在实际响应中提供了可定制响应对象的响应头和响应数据
5.在一个servlet被调用之后截获该调用