详解 Javaweb 中过滤器(Filter)、监听器(Listener)

写在前面:

代码实现(可直接运行):filter01

一. 过滤器(Filter)[重要 !]

1.1 Filter 的作用

Filter:过滤器 ,用来过滤网站的数据;

  • 处理中文乱码
  • 登录验证….

1.2 Filter 开发步骤(解决中文乱码)

  • 导包
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.3</version>
    </dependency>

    <dependency>
      <groupId>javax.servlet.jsp.jstl</groupId>
      <artifactId>jstl-api</artifactId>
      <version>1.2</version>
    </dependency>

    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>

    <!-- 连接数据库 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.47</version>
    </dependency>
  </dependencies>
  • 编写过滤器
public class CharacterEncodingFilter implements Filter {
    
    

    //初始化:web服务器启动,就以及初始化了,随时等待过滤对象出现!
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
    
        System.out.println("CharacterEncodingFilter初始化");
    }

    //Chain : 链
    /*
    1. 过滤中的所有代码,在过滤特定请求的时候都会执行
    2. 必须要让过滤器继续同行
        chain.doFilter(request,response);
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html;charset=UTF-8");

        System.out.println("CharacterEncodingFilter执行前....");
        filterChain.doFilter(servletRequest,servletResponse); //让我们的请求继续走,如果不写,程序到这里就被拦截停止!
        System.out.println("CharacterEncodingFilter执行后....");
    }

    // 销毁:web服务器关闭的时候,过滤会销毁
    @Override
    public void destroy() {
    
    
        System.out.println("CharacterEncodingFilter销毁");
    }
}
  • 在 web.xml 中配置 Filter
  <!-- 注册filter -->
  <filter>
    <filter-name>filter</filter-name>
    <filter-class>com.filter.CharacterEncodingFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>filter</filter-name>
    <!-- 只要 /servlet/                                                                                                                                                                                                                   * 的任何请求,都会经过过滤器 -->
    <url-pattern>/*</url-pattern>
  </filter-mapping>

二. 监听器(Listener)

实现一个监听器的接口;(有N种)

实现一个功能:统计网站在线人数(统计 session)

  • index.jsp
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello World!</h2>

<h1>当前有<span style="color: blue"><%=this.getServletConfig().getServletContext().getAttribute("OnlineCount")%></span>人在线。</h1>
</body>
</html>

  • OnlineCountListener
public class OnlineCountListener implements HttpSessionListener {
    
    

    // 创建 Session 监听
    //一旦创建 Session 就会触发一次这个事件!
    @Override
    public void sessionCreated(HttpSessionEvent se) {
    
    
        ServletContext ctx = se.getSession().getServletContext();

        System.out.println(se.getSession().getId());

        Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount"); // 取对象

        if (onlineCount==null){
    
    
            onlineCount = new Integer(1);
        }else {
    
    
            int count = onlineCount.intValue();
            onlineCount = new Integer(count+1);
        }

        ctx.setAttribute("OnlineCount",onlineCount);
    }

    // 销毁 Session 监听
    //一旦销毁 Session 就会触发一次这个事件!
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
    
    
        ServletContext ctx = se.getSession().getServletContext();

        Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");

        if (onlineCount==null){
    
    
            onlineCount = new Integer(0);
        }else {
    
    
            int count = onlineCount.intValue();
            onlineCount = new Integer(count-1);
        }

        ctx.setAttribute("OnlineCount",onlineCount);
    }
}
  • 在 web.xml 中注册监听器
<!--注册监听器-->
<listener>
    <listener-class>com.kuang.listener.OnlineCountListener</listener-class>
</listener>

三. 过滤器、监听器的常见应用

3.1 监听器:GUI 编程中经常使用

public class TestPanel {
    
    
    public static void main(String[] args) {
    
    
        Frame frame = new Frame("中秋节快乐");  //新建一个窗体
        Panel panel = new Panel(null); //面板
        frame.setLayout(null); //设置窗体的布局

        frame.setBounds(300,300,500,500);
        frame.setBackground(new Color(0,0,255)); //设置背景颜色

        panel.setBounds(50,50,300,300);
        panel.setBackground(new Color(0,255,0)); //设置背景颜色

        frame.add(panel);

        frame.setVisible(true);

        //监听事件,监听关闭事件
        frame.addWindowListener(new WindowAdapter() {
    
    
            @Override
            public void windowOpened(WindowEvent e) {
    
    
                System.out.println("打开");
            }

            @Override
            public void windowClosed(WindowEvent e) {
    
    
                System.out.println("关闭ed");
            }

            @Override
            public void windowClosing(WindowEvent e) {
    
    
                System.out.println("关闭ing");
                System.exit(0);
            }
        });


    }
}

3.2 登录页面

功能:

  • 用户登录之后才能进入主页;
  • 用户注销后就不能进入主页了;

主要代码如下:

  • LoginServlet
public class LoginServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        // 获取前端请求的参数
        String username = req.getParameter("username");

        if(username.equals("admin")){
    
      // 登录成功
            req.getSession().setAttribute("USER_SESSION",req.getSession().getId());
            resp.sendRedirect("/sys/success.jsp"); // 重定向
        }else{
    
     // 登录失败
            resp.sendRedirect("/sys/error.jsp"); // 重定向
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        doGet(req, resp);
    }
}
  • LogoutServlet
public class LogoutServlet extends HttpServlet {
    
    

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        Object user_session = req.getSession().getAttribute("USER_SESSION");
        if (user_session != null){
    
    
            req.getSession().removeAttribute("USER_SESSION");
            resp.sendRedirect("/Login.jsp");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        doGet(req, resp);
    }
}
  • 添加监听器 SysFilter:
public class SysFilter implements Filter {
    
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
    

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        if (request.getSession().getAttribute(Constant.USER_SESSION)==null){
    
    
            response.sendRedirect("/sys/error.jsp");
        }

        filterChain.doFilter(request,response);
    }

    @Override
    public void destroy() {
    
    

    }
}

猜你喜欢

转载自blog.csdn.net/Kc635908933/article/details/114668176