过滤器:执行目标资源之前做预处理工作。
应用场景:
例如设置编码,这种试通常都会放行,只是在目标资源执行之前做一些准备工作
通过条件判断是否放行,例如校验当前用户是否已经登录,或者用户IP是否已经被禁用;
在目标资源执行后,做一些后续的特殊处理工作,例如把目标资源输出的数据进行处理;
本文实例包含:
1.分IP统计网站的访问次数
2.粗粒度权限控制(拦截是否登录,拦截用户名admin权限)
3.解决全站字符乱码问题(POST和GET中文编码问题)
- 分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>
- 粗粒度权限控制(拦截是否登录,拦截用户名admin权限)
游客、会员、管理员三个粒度
A. 创建一个Fileter,过滤会员下的资源访问,这是保安1号 ,doFilter里检查session中权限标记,第一道检查工序,不是管理员=> 放行,第二道检查工序,不是会员=> 打回到登录/注册页面,如果是会员就放行!
B. 创建一个Fileter,过滤管理员下的资源访问,这是保安2号 ,doFilter里检查session中权限标记,查看是不是管理员,不是管理员=>打回到登录/注册页面,如果是管理员就放行!
- 解决全站字符乱码问题(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”)
参考资料: