Servlet过滤监听

1. 过滤器

过滤器常作用于servlet,可以在servlet执行service()前后,进行一次过滤,过滤之后的操作内容自己定义,主要目的就是进行统一处理。
过滤基础搭建
新建MyFilter.java,并且实现Filter接口,实现里面的所有抽象方法

    public class MyFiler implements Filter{
        public void doFilter(ServletRequest req, ServletResponse resp, 
            FilterChain chain) throws IOException, ServletException {
            
            System.out.println("前置过滤:service()方法执行之前...");
    		chain.doFilter(request, response);// 放行,去执行目标service()方法
    		System.out.println("后置过滤:service()方法执行之后...");
        }
        public void init(FilterConfig arg0) throws ServletException {
            System.out.println("MyFilter被创建...");
        }
        public void destroy() {
            System.out.println("MyFilter被销毁...");
        }
    }

在web.xml中部署这个过滤器,部署过程和servlet部署过程很相似。

<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>com.xhh.filter.MyFiler</filter-class>
</filter>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/servlet/*</url-pattern>//<url-pattern>中规定了什么样的路径,会被过滤器拦截。
</filter-mapping> 

过滤案例:统一转码

public class MyFilter implements Filter{
    public void doFilter(ServletRequest req, ServletResponse resp, 
        FilterChain chain) throws IOException, ServletException {
    
        // 通过强转得到请求HttpServletRequest和HttpServletResponse对象;
        HttpServletRequest request=(HttpServletRequest)req;
        HttpServletResponse response=(HttpServletResponse)resp;
        
        // 拦截响应,统一转码;
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=utf-8");
        
        chain.doFilter(request,response);// 放行
    }
    public void init(FilterConfig arg0) throws ServletException {
        System.out.println("MyFilter被创建...");
    }
    public void destroy() {
        System.out.println("MyFilter被销毁...");
    }
}

过滤案例:非法登录

如果用户直接地址栏键入"servlet/*"这样的路径,不可以让其直接进入程序,这属于非法入侵,那么此时就需要对请求进行过滤,非法的不允许登录,当然,登录的servlet必须只能放行。

public void doFilter(ServletRequest req, ServletResponse resp,
    FilterChain chain) throws IOException, ServletException {
    
    HttpServletRequest request = (HttpServletRequest)req;
    HttpServletResponse response = (HttpServletResponse)resp;
    request.setCharacterEncoding("utf-8");
    response.setContentType("text/html;charset=utf-8");
    
    String uri = request.getRequestURI();// 得到请求中的url
    if(uri.indexOf("/servlet/LoginServlet") > 0){// 路径中存在/servlet/LoginServlet
        chain.doFilter(request, response);// 直接通过,否则登录模块会崩溃
    }else{// 判断用户当前是否已经是登录状态
        Object userMap = request.getSession().getAttribute("userMap");
        if(userMap != null){// 用户当前已经是登录状态
            chain.doFilter(request, response);//放行
        }else{// 没有登录,转到失败页
            request.getRequestDispatcher("/jsp/login/login.jsp").forward(request, response);
        }
    }
}

**

2. 监听器

**

2.1 监听基础搭建

新建MyListener.java,并且实现ServletContextListener接口,实现里面的所有抽象方法

public class MyListener implements ServletContextListener{
    public void contextDestroyed(ServletContextEvent event) {
        System.out.println("MyListener销毁:服务器关闭时做的操作...");
    }
    public void contextInitialized(ServletContextEvent event) {
        System.out.println("MyListener启动:服务器开启时做的操作...");
    }
}

在web.xml中部署这个监听器

<listener>
    <listener-class>com.xhh.listener.MyListener</listener-class>
</listener>

tips:servlet3可以使用@WebListener注解进行搭建监听器。

2.2 监听案例:防止统一ID同时在线

MyListener.java
public class MyListener implements ServletContextListener{
    public void contextDestroyed(ServletContextEvent event) {
        event.getServletContext().removeAttribute("online_users");
    }
    public void contextInitialized(ServletContextEvent event) {
        // 把一个空list存放到application中,起名为online_users
        // 只要服务器不关闭,就一直存在
        event.getServletContext().setAttribute("online_users", new ArrayList<String>());
    }
}

LoginServlet.java
protected void service(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    
    String loginname = request.getParameter("loginname");
    ServletContext application = request.getSession().getServletContext();
    List<String> online_users = (List<String>)application.getAttribute("online_users");
    boolean flag = false;// false代表不存在(允许登录)、true代表已存在(禁止登录)
    if(online_users.isEmpty()){// online_users为空,允许登录
        online_users.add(loginname);// 帐号添加到online_users中
        application.setAttribute("online_users", online_users);// 更新online_users
        request.getSession().setAttribute("loginname",loginname);
        request.getRequestDispatcher("/main.jsp").forward(request, response);
    }else{// online_users不为空,继续判断
        for(String e : online_users){
            if(e.equals(loginname)){// 在online_users中搜寻loginid
                flag = true;// 如果已存在,禁止登录
                break;
            }
        }
        if(flag){// 已存在,禁止登录
            request.setAttribute("msg","当前用户已经存在,不要重复登录!");
            request.getRequestDispatcher("/middle.jsp").forward(request, response);
        }else{// 未存在,允许登录
            online_users.add(loginname);// 帐号添加到online_users中
            application.setAttribute("online_users", online_users);// 更新online_users
            request.getSession().setAttribute("loginname",loginname);
            request.getRequestDispatcher("/main.jsp").forward(request, response);
        }
    }
}

2.3 监听案例:退出服务器登录

login.jsp

<a href="<%=path%>/servlet/ExitServlet">退出登录</a>


ExitServlet.java
public class ExitServlet extends HttpServlet{
    protected void service(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    
        // 获取到当前登录的loginname
        String loginname = (String)request.getSession().getAttribute("loginname");
        
        // 获取当前在线的list
        ServletContext application = request.getSession().getServletContext();
        List<String> online_users = (List<String>)application.getAttribute("online_users");
    
        // 将Logind从list中移除		
        online_users.remove(loginname);
        request.getRequestDispatcher("/index.jsp").forward(request, response);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值