过滤器Filter
过滤器
在多个页面需要统一执行的代码,可以通过过滤器的web组件来完成;
- 定义过滤器
//识别过滤器
@WebFilter(urlPattern="要过滤哪些路径")
class 过滤器类 implements Filter{
//初始化操作
public void init(){}
//销毁操作
public void destroy(){}
//过滤方法
//FilterChain过滤器链
public void doFilter(ServletRequest req,ServletResponse resp,FilterChain chain){
//要统一执行的代码
//是否让请求继续前进
chain.doFilter(req,resp);
}
}
- 过滤的路径格式
- 精准匹配 /servlet1:只会进入servlet1之前进入过滤器;
- 后缀匹配 *.jsp:访问任意一个以.jsp结尾的路径都会经过过滤器;
- 前缀匹配 /user/*:当请求的路径是以user开头的就会经过过滤器;
如果有多个过滤器都和目标路径匹配,那么会依次经过多个过滤器,经过先后顺序跟过滤器的名字有关;
- request和response的类型转换
Filter中的request和response声明的是父类型,有些方法没有,需要转换为子类型对象;
- 过滤器的应用
- post请求的中文乱码,可以采用字符编码过滤器来解决
req.setCharacterEncoding("解码字符集");
req.getParameter()
- 登录检查过滤器
@WebFilter(urlPatterns = "/*")
public class Filter1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
//检查路径是否为登录界面路径,如果是则直接放行,否则判断用户是否已经登录
String uri = req.getRequestURI();
if (uri.equals("/users.jsp") || uri.equals("/servlet01")){
filterChain.doFilter(req,resp);
return;
}
//检查会话中是否存在username用户,如果存在这说明已经登录,否则跳转到登录页面让用户继续登录
HttpSession session = req.getSession();
Object user = session.getAttribute("username");
if(user ==null){
session.setAttribute("error","您尚未登录");
resp.sendRedirect("/users.jsp");
}else {
filterChain.doFilter(req,resp);
}
}
@Override
public void destroy() {
}
}
如果跳转页面有多层目录,在跳转时在路径前加上"/",以相对主机名和端口号进行跳转;
否则会以从后往前第一个"/"之前的路径为相对路径进行跳转。
- 自动登录过滤器
- 浏览器第一次登陆,发送登录请求,登陆成功后,服务器将包含用户名、密码的登录标志信息放入session中;
- 服务器返回给浏览器一个cookie响应,包含用户名和密码,并且浏览器设置maxAge等属性;
- 浏览器关闭,session中的信息失效,但是浏览器中存在cookie的信息,在发送请求的时候,
同时将cookie中的信息发送给服务器; - 过滤器先检查session内容,如果有旧直接放行,否则检查cookie中的信息,看cookie是否存在并且用户名和密码是否正确,
如果正确直接放行,否则需要重新登录;
在servlet中判断是否要自动登录
//如果自动登录栏被勾选则执行
if (req.getParameter("autoLogin").equals("true")){
req.setAttribute("success","登陆成功");
//创建cookie对象,将用户信息存入
Cookie cookie = new Cookie("up",user.getUsername()+":"+user.getPassword());
//设置cookie的存活时间
cookie.setMaxAge(24*3600);
//将cookie添加到响应,返回给浏览器
resp.addCookie(cookie);
}
在过滤器中,先判断session中是否存在用户信息,如果存在则自动登录;如果不存在则判断浏览器发过来的
cookie中是否存在用户信息,如果存在则自动登录,并且把cookie中的信息放入session中方便以后使用,否则跳转到登录页面;
//检查会话中是否存在username用户
HttpSession session = req.getSession();
Object user = session.getAttribute("username");
if(user !=null){
filterChain.doFilter(req,resp);
}else {
//如果session中没有用户信息,则检查cookie中是否存在
//获取浏览器请求时发过来的cookie
Cookie[] cookies = req.getCookies();
Cookie up=null;
for (Cookie cookie : cookies) {
if(cookie.getName().equals("up")){
up=cookie;
break;
}
}
if(up!=null){
//获取用户名和密码
String[] split = up.getValue().split(":");
//验证用户名和密码
UserDao ud = new UserDao();
String username = split[0];
String password=split[1];
User user1 = ud.authUser(username);
if (user1!=null && user1.getPassword().equals(password)){
//将用户名放入session
session.setAttribute("username",username);
filterChain.doFilter(req,resp);
return;
}
}
}
监听器
Listener没有路径,特定事件发生时,会执行监听器代码;
- ServletRequestListener:在请求对象初始化和销毁时,会被调用;
- HttpSessionListener:在session初始化和销毁的时候会被调用;
应用场景:
-
ServletContextListener:在application对象创建和销毁的时候被调用;
-
ServletRequestAttributeListener:在往request作用域中变量发生变化时被调用
-
HTTPSessionAttributeListener:在往session作用域中变量发生变化时被调用
-
ServletContextAttributeListener:在往application作用域中变量发生变化时被调用
-
HttpSessionActivationListener:在session钝化(从内存到磁盘)和活化(从磁盘到内存)session中存储对象,
对象要实现序列化和反序列化; -
HTTPSessionBindingListener:
下一篇: 基于Vue实现可以拖拽的树形表格实例详解