资料来源黑马javaweb2019
Filter过滤器,可以理解成中间件。可以对request和response做一些处理,并放行一部分数据。
可以理解成一个土匪,拦路打劫。
此外,这种打劫是双向的(即从客户端到服务器打劫一次,从服务器到客户端也可以打劫)。
主要格式:
此外还有以下可选细节:
拦截路径配置:
- 具体资源路径: /index.jsp 只有访问index.jsp资源时,过滤器才会被执行
- 拦截目录: /user/* 访问/user下的所有资源时,过滤器都会被执行
- 后缀名拦截: *.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行
- 拦截所有资源:/* 访问所有资源时,过滤器都会被执行
- 拦截方式配置:资源被访问的方式
注解配置: - 设置dispatcherTypes属性
- REQUEST:默认值。浏览器直接请求资源
- FORWARD:转发访问资源
- INCLUDE:包含访问资源
- ERROR:错误跳转资源
- ASYNC:异步访问资源
web.xml配置
- 设置标签即可
- 过滤器链(配置多个过滤器)
执行顺序:如果有两个过滤器:过滤器1和过滤器2 - 过滤器1
- 过滤器2
- 资源执行
- 过滤器2
- 过滤器1
Filter应用:登入验证
验证登入(如果用户没有登入,就不让他访问某些资源,并跳转到登入页面,提示其登入)
//登入验证的过滤器
@WebFilter(value = "/*")
public class LoginFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//1.强制转换 把ServletRequest转成子类HttpServletRequest
HttpServletRequest request = (HttpServletRequest)req;
//2.判断是否是登入相关的资源,直接放行
String uri = request.getRequestURI();
//要注意还要排除掉css/js/图片/验证码等资源
if(uri.contains("/login.jsp") || uri.contains("/loginServlet") || uri.contains("/css/")
|| uri.contains("/js/") || uri.contains("/fonts/") || uri.contains("/checkCode"))
{
//包含,说明用户就是想登入,放行
chain.doFilter(req, resp);
}
else
{
Object user = request.getSession().getAttribute("user");
if(user != null)
chain.doFilter(req,resp); //session中有user,用户已经登入,放行
else
{
//没有登入,跳转到登入页面
request.setAttribute("login_msg","你还没有登入,请登入");
request.getRequestDispatcher("/login.jsp").forward(request,resp);
}
}
//chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
敏感词验证
应用了动态代理的设计模式。详见:动态代理
此外,需要在init中加载txt配置文件,还是用BufferedReader来读取。
@WebFilter("/*")
public class SensitiveWordsFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//1.创建代理对象,增强getParameter方法
ServletRequest proxy_req = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//增强getParameter方法
//判断是否是getParameter方法
if(method.getName().equals("getParameter")){
//增强返回值
//获取返回值
String value = (String) method.invoke(req,args);
if(value != null){
for (String str : list) {
if(value.contains(str)){
value = value.replaceAll(str,"***");
}
}
}
return value;
}
//判断方法名是否是 getParameterMap
//判断方法名是否是 getParameterValue
return method.invoke(req,args);
}
});
//2.放行
chain.doFilter(proxy_req, resp);
}
private List<String> list = new ArrayList<String>();//敏感词汇集合
public void init(FilterConfig config) throws ServletException {
try{
//1.获取文件真实路径
ServletContext servletContext = config.getServletContext();
String realPath = servletContext.getRealPath("/WEB-INF/classes/敏感词汇.txt");
//2.读取文件
BufferedReader br = new BufferedReader(new FileReader(realPath));
//3.将文件的每一行数据添加到list中
String line = null;
while((line = br.readLine())!=null){
list.add(line);
}
br.close();
System.out.println(list);
}catch (Exception e){
e.printStackTrace();
}
}
public void destroy() {
}
}