过滤器Filter的应用场景案例

过滤器:执行目标资源之前做预处理工作
应用场景:
例如设置编码,这种试通常都会放行,只是在目标资源执行之前做一些准备工作
通过条件判断是否放行,例如校验当前用户是否已经登录,或者用户IP是否已经被禁用;
在目标资源执行后,做一些后续的特殊处理工作,例如把目标资源输出的数据进行处理;
本文实例包含:
1.分IP统计网站的访问次数
2.粗粒度权限控制(拦截是否登录,拦截用户名admin权限)
3.解决全站字符乱码问题(POST和GET中文编码问题)

  1. 分IP统计网站的访问次数
    统计网站访问次数,首先不需要做拦截。
    只需要考虑使用什么样的“容器”来放置这个计数结果(Map<String,Integer>),以及什么时候在哪里创建这个“容器”(使用ServletContextListener,在服务器启动时完成创建,并只在到ServletContext中)

Listener

package com.example.listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.util.HashMap;
import java.util.LinkedHashMap;

@WebListener()
public class CListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //1.创建ServletContext
        ServletContext application = sce.getServletContext();
        //2.Map
        HashMap<String, Integer> ipMap = new LinkedHashMap<>();
        //3.把Map保存到ServletContext中
        application.setAttribute("ipMap",ipMap);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {

    }
}

Filter

package com.example.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
import java.util.LinkedHashMap;

@WebFilter("/*")
public class CFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //1.得到ServletContext中的IPMap
        ServletContext application = req.getServletContext();
        //2.获取客户端IP
        String IP = req.getRemoteAddr();
        //3.获得并操作Map
        LinkedHashMap<String, Integer> ipMap = (LinkedHashMap<String, Integer>) application.getAttribute("ipMap");
        if (ipMap.containsKey(IP)) {
            int ipValue = ipMap.get(IP);
            ipMap.put(IP, ++ipValue);
            System.out.println("添加了map IP = " + IP + "次数 = " + ipValue);
        } else {
            ipMap.put(IP, 1);
            System.out.println("添加了map IP = " + IP + "次数 = " + 1);
        }
        application.setAttribute("ipMap", ipMap);
        //4.放行
        chain.doFilter(req, resp);
    }

    @Override
    public void destroy() {

    }
}

jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="y" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="zh-CN">
<html>
<body>
<h1>显示IP</h1>
<h1>${applicationScope.ipMap }</h1>

<table border="1" align="center" width="60%">

    <tr>
        <th>IP地址</th>
        <th>次数</th>
    </tr>
    <c:forEach items="${applicationScope.ipMap }" var="entry">
    <tr>
        <td>${entry.key}</td><%--这里不知道为啥没显示出来--%>
        <td>${entry.value}</td><%--这里不知道为啥没显示出来--%>
    </tr>
    </c:forEach>
</table>
</body>
</html>
  1. 粗粒度权限控制(拦截是否登录,拦截用户名admin权限)

游客、会员、管理员三个粒度
A. 创建一个Fileter,过滤会员下的资源访问,这是保安1号 ,doFilter里检查session中权限标记,第一道检查工序,不是管理员=> 放行,第二道检查工序,不是会员=> 打回到登录/注册页面,如果是会员就放行!
B. 创建一个Fileter,过滤管理员下的资源访问,这是保安2号 ,doFilter里检查session中权限标记,查看是不是管理员,不是管理员=>打回到登录/注册页面,如果是管理员就放行!

  1. 解决全站字符乱码问题(POST和GET中文编码问题)

servlet:
POST:request.setCharacterEncoding(“utf-8”)
GET
String username = request.getParameter(“username”)
username = new String(username.getBytes(“IOS-8859-1”),“UTF-8”);
响应的乱码问题:
response.setContextType(“text/html;charset=utf-8”)

参考资料:

  1. JavaWeb之 Filter(过滤器)
  2. 过滤器的几个实例
上一篇:第八节——使用ContextListener监听器简化开发


下一篇:ServletContext作用功能详解