过滤器(filter)简介
- 过滤器是Javaweb的组件之一,用来过滤请求和处理响应
过滤器实际上就是对web资源进行拦截,做一些处理后再交给下一个过滤器或servlet处理
通常都是用来拦截request进行处理的,也可以对返回的response进行拦截处理
使用场景:
1.设置请求/响应字符编码
2.校验登录权限
3.敏感词汇的过滤
大致流程图如下:
filter的使用(xml配置)
1,声明一个过滤器类要实现Filter接口(CusFilter类)
public class CusFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("filter 初始化了");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
/*过滤方法 主要是对request和response进行一些处理,然后交给下一个过滤器或Servlet处理*/
System.out.println("过滤请求了!!!");
//给请求放行 请求真正的资源/或者到下一个过滤器
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println("filter 销毁了");
}
}
2、配置 web.xml 文件
<filter>
<filter-name>filter</filter-name>
<filter-class>com.codeyancy.filter.CusFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
过滤器(Filter)的生命周期
构造 —> 初始化 —> 过滤 —> 销毁
- 构造和初始化是在应用部署好后就执行的而不是第一次访问,而且是只执行一次
- 过滤方法是每次指定的请求发送过来的时候执行
- 销毁方法是应用卸载或者TOMCAT关闭的时候执行
过滤器(Filter)的拦截路径写法
<filter-mapping>
<filter-name>filter</filter-name>
<!-- /* 表示过滤所有请求 -->
<url-pattern>/*</url-pattern>
<!--精确路径过滤-->
<url-pattern>/ajaSearch.html</url-pattern>
<!--后缀名匹配过滤-->
<url-pattern>*.html</url-pattern>
<!--目录匹配过滤-->
<url-pattern>/html/*</url-pattern>
</filter-mapping>
filter的使用(注解形式)
使用注解形式,就不需要再配置web.xml了
只需要在实现Filter接口的类上添加注解@WebFilter("/*")
即可
@WebFilter("/*")
public class CusFilter implements Filter {
多个过滤器(Filter)的执行顺序
在请求到达Servle之间是可以经过多个过滤器(Filter)的,一般情况下,建议过滤器(Filter)之间不要有关联,各自处理各自的逻辑即可。这样,我们也不需要关心执行顺序问题。
如果一定要确保执行顺序,就要对配置进行修改了,多个过滤器(Filter)的执行顺序如下
- 使用web.xml 配置,filter执行顺序跟的顺序有关,先声明的就会先执行
- 使用注解配置,filter的执行顺序跟filter名称的字母顺序有关,例如AFilter会比BFilter先执行
- 如果既有在web.xml中声明的Filter,也有通过注解配置的Filter,那么会优先执行web.xml中配置的Filter
FilterConfig配置类
每个filter都有一个配置类
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//获取filter的初始化参数
String jdbcUrl = filterConfig.getInitParameter("jdbcUrl");
System.out.println(jdbcUrl);
// 获取上下文对象
ServletContext servletContext = filterConfig.getServletContext();
System.out.println("filter 初始化了");
}
web.xml文件配置初始化参数
<filter>
<filter-name>filter</filter-name>
<filter-class>com.codeyancy.filter.CusFilter</filter-class>
<init-param>
<param-name>jdbcUrl</param-name>
<param-value>dbc:mysql://192.168.0.1:3306/</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
使用过滤器处理请求响应乱码案例
主要代码演示:
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//处理乱码
request.setCharacterEncoding("UTF-8");
response.setContentType("text/json;charset=UTF-8");
String requestURI = request.getRequestURI();
//System.out.println("filter1 拦截了请求..." + requestURI);
filterChain.doFilter(servletRequest, servletResponse);
//System.out.println("filter1 响应了请求...");
}
使用过滤器进行校验登陆权限案例
1.前端login.html
<body>
<form action="/auth">
user <input type="text" name="username"> <br>
pass <input type="password" name="password"> <br>
<input type="submit" value="登录">
</form>
</body>
2.后端权限校验servlet(AuthController 类)
@WebServlet("/auth")
public class AuthController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
if("tom".equals(username)&&"666".equals(password)){
//验证成功后往session域中存放登录信息
HttpSession session = req.getSession();
session.setAttribute("user",new User(username,password));
resp.sendRedirect("/index.html");
}else {
resp.sendRedirect("/login.html");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3.后端过滤器(CusFilter2类)
@WebFilter("/*")
public class CusFilter2 implements Filter {
public CusFilter2() {
System.out.println("filter2 过滤器构造了");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("filter2 初始化");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String requestURI = request.getRequestURI();
//不拦截 .css .js login.html index.html .img .jpg /auth
//使用正则表达式
Pattern compile = Pattern.compile(".*(css|js|login.html|index.html|img|jpg|auth)$");
Matcher matcher = compile.matcher(requestURI);
if(matcher.matches()){
//放行
filterChain.doFilter(servletRequest,servletResponse);
}else {
HttpSession session = request.getSession();
Object user = session.getAttribute("user");
if(user==null){
response.sendRedirect("/login.html");
}else {
//放行,请求真正的资源/到下一个过滤器
filterChain.doFilter(servletRequest, servletResponse);
}
}
}
@Override
public void destroy() {
}
}