Servlet过滤器Fileter是一个小型的web组件,它们通过拦截请求和响应,以便查看、提取或以某种方式操作客户端和服务器之间交换的数据,实现“过滤”的功能。Filter通常封装了一些功能的web组件,过滤器提供了一种面向对象的模块化机制,将任务封装到一个可插入的组件中, Filter组件通过配置文件来声明,并动态的代理。
Filter的工作原理如下:
总而言之就是拦截器可以实现拦截servlet和jsp的请求和相应,通过拦截我们可以提前做一些预处理事件。
下面我结合防跳墙来介绍拦截器,请细看代码注释!!!
逻辑如下:
1.现在我设置防跳墙的目的是:当用户在没有正常进入登录界面完成登录时,无法访问其他页面。
2.开启Session会话:想要实现该目的,在登录的业务逻辑实现代码中,完成登录后开启Session会话并设置会话属性键值对。
GetMapper getMapper = new GetMapper();
List<Admin> admin = getMapper.selectAdmin(user, pw);
if (!admin.isEmpty()) {
//如果数据库存在该账号密码开启会话,并设置会话属性键值对
HttpSession session = req.getSession();
session.setAttribute("login", "pass");
resp.sendRedirect("paging.jsp");
} else {
PrintWriter writer = resp.getWriter();
writer.write("<script>" +
"alert('账号或密码错误!');" +
"window.location.href='login.jsp'" +
"</script>");
}
3.拦截放行:在拦截器中对登录需要的请求和响应放行,其他请求和响应都要做逻辑判断,如果存在Session会话属性login的键值对就允许访问,否则拦截。
4.销毁会话:在网页中设计的注销登录按钮跳转请求销毁所有session,即可实现退出效果
@WebServlet("/LogOut")
public class LogOut extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取会话
HttpSession session = req.getSession();
session.invalidate();//销毁会话
PrintWriter writer = resp.getWriter();
writer.write("<script>" +
"alert('退出成功!');" +
"window.location.href='login.jsp'" +
"</script>");
}
}
下面的是拦截器中写的逻辑判断
package Filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
@WebFilter("/*")//*代表拦截所有
public class filter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//初始化
System.out.println("初始化了!!!");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("进来先拦截");
//在页面放行前先设编码(在这里做设编码,就不用在每个servlet中写了)
servletRequest.setCharacterEncoding("UTF-8");
servletResponse.setContentType("text/html;charset=utf-8");
//获取session
HttpSession session = ((HttpServletRequest) servletRequest).getSession(false);
String requestURI = ((HttpServletRequest) servletRequest).getRequestURI();
if (requestURI.endsWith("/login.jsp") || requestURI.endsWith("/KaptchaCode") ||
requestURI.endsWith("/Login") || requestURI.endsWith("/LoginFailed")) {
filterChain.doFilter(servletRequest, servletResponse);//这里对登录需要的请求放行
} else if (session == null || session.getAttribute("login") == null) {
//如果session会话的login属性为空就是没有登录,拦截请求,并弹窗提示登录
PrintWriter writer = servletResponse.getWriter();
writer.write("<script>" +
"alert('请登录!!!');" +
"window.location.href='login.jsp'" +
"</script>");
}else {
//完成登录后所有请求放行
filterChain.doFilter(servletRequest, servletResponse);
}
}
@Override
public void destroy() {
System.out.println("\" 拦截结束了\" = " + " 拦截结束了");
}
}