天天看点

【过滤器(Filter)编码过滤、登录权限拦截】+【监听器(xxxListener)HttpSessionListener接口】

声明:本文实例学习自:B站UP主–遇见狂神说。写此文仅作为学习记录,加深印象,方便回顾。

文章目录

  • ​​过滤器(Filter)​​
  • ​​1.类结构​​
  • ​​2.初始化​​
  • ​​3.执行过滤​​
  • ​​3.销毁​​
  • ​​4.测试​​
  • ​​实例测试一(编码过滤)​​
  • ​​1)主要代码​​
  • ​​2)效果图​​
  • ​​实例测试二(登录权限拦截)​​
  • ​​1)主要代码​​
  • ​​2)效果图​​
  • ​​监听器(xxxListener)​​
  • ​​测试​​
  • ​​实例测试(HttpSessionListener接口)​​
  • ​​1)主要代码​​
  • ​​2)效果图​​

过滤器(Filter)

1.类结构

有三个方法需要重写:初始化,执行过滤和销毁

【过滤器(Filter)编码过滤、登录权限拦截】+【监听器(xxxListener)HttpSessionListener接口】

2.初始化

web服务器启动后,Filter就已经初始化,随时等待需过滤目标的出现

【过滤器(Filter)编码过滤、登录权限拦截】+【监听器(xxxListener)HttpSessionListener接口】

3.执行过滤

通过重写Filter接口的doFilter方法

3.销毁

web服务器终止后,Filter就执行销毁操作

【过滤器(Filter)编码过滤、登录权限拦截】+【监听器(xxxListener)HttpSessionListener接口】

4.测试

实例测试一(编码过滤)

1)主要代码

过滤器(Filter)

public class CharacterEncodingFilter implements Filter {
    //初始化:web服务器启动后,就已经初始化,随时等待过滤对象的出现
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter初始化");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        System.out.println("Filter执行前");
        chain.doFilter(request, response); //请求继续转接出去,如果不写,程序到此会被拦截
        System.out.println("Filter执行后");
    }

    //销毁
    @Override
    public void destroy() {
        System.out.println("Filter销毁");
    }
}      

Servlet测试类

public class ShowServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //让Filter去执行此注释中的操作
        //resp.setContentType("text/html");
        //resp.setCharacterEncoding("UTF-8");
        resp.getWriter().write("你好,世界!");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}      

web.xml

<servlet>
    <servlet-name>show</servlet-name>
    <servlet-class>com.zlc.servlet.ShowServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>show</servlet-name>
    <url-pattern>/servlet/show</url-pattern>
</servlet-mapping>
<!--一个servlet可映射多个请求-->
<servlet-mapping>
    <servlet-name>show</servlet-name>
    <url-pattern>/show</url-pattern>
</servlet-mapping>

<filter>
    <filter-name>cfilter</filter-name>
    <filter-class>com.zlc.filter.CharacterEncodingFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>cfilter</filter-name>
    <!--只要/servlet的任何请求,都会被过滤器先拦截-->
    <url-pattern>/servlet/*</url-pattern>
</filter-mapping>      
2)效果图

说明:ShowServlet这个用于输出页面信息的类,设置了两个请求地址,即/show和/servlet/show,其中/servlet/show才被过滤器拦截。

首先请求/show,因未被拦截,因此也为修改其编码为UTF-8,因此显示???

【过滤器(Filter)编码过滤、登录权限拦截】+【监听器(xxxListener)HttpSessionListener接口】

请求被拦截的/servlet/show,修改编码成功

【过滤器(Filter)编码过滤、登录权限拦截】+【监听器(xxxListener)HttpSessionListener接口】

实例测试二(登录权限拦截)

1)主要代码

常用常量类

public class Constant {
    public static String USER_SESSION = "USER_SESSION";
}      

登录成功后,添加Session,从而标识此用户的登录状态

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(Constant.USER_SESSION, req.getSession().getId());
            resp.sendRedirect("/sys/success.jsp");
        } else {
            //登录失败
            resp.sendRedirect("/error.jsp");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}      

注销 / 退出登录,清除Session内容

public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object user_session = req.getSession().getAttribute(Constant.USER_SESSION);

        if (user_session != null) {
            req.getSession().removeAttribute(Constant.USER_SESSION);
            resp.sendRedirect("/login.jsp");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}      

登录身份拦截器,之后配置web.xml,使其拦截/sys/*下的请求,确保管理员登录成功(即保存了Session)后,才可以访问sys/success.jsp

public class SysFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        if (request.getSession().getAttribute(Constant.USER_SESSION) == null) {
            response.sendRedirect("/error.jsp");
        }

        chain.doFilter(req, resp);
    }
}      

web.xml

<servlet>
    <servlet-name>login</servlet-name>
    <servlet-class>com.zlc.servlet.LoginServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>login</servlet-name>
    <url-pattern>/servlet/login</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>logout</servlet-name>
    <servlet-class>com.zlc.servlet.LogoutServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>logout</servlet-name>
    <url-pattern>/servlet/logout</url-pattern>
</servlet-mapping>

<filter>
    <filter-name>sysfilter</filter-name>
    <filter-class>com.zlc.filter.SysFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>sysfilter</filter-name>
    <url-pattern>/sys/*</url-pattern>
</filter-mapping>      

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="/servlet/login">
        用户名:<input type="text" name="username">
        密码:<input type="password" name="password">
        <input type="submit">
    </form>
</body>
</html>      

error.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
 <h1>登录失败</h1>
 <h1>没有权限!</h1>
 <a href="/login.jsp">返回登录页面</a>
</body>
</html>      

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<%--<%--%>
<%--    JSP也可实现登录权限拦截(不推荐)--%>
<%--    Object user_session = request.getSession().getAttribute("USER_SESSION");--%>

<%--    if (user_session == null) {--%>
<%--        response.sendRedirect("/login.jsp");--%>
<%--    }--%>
<%--%>--%>

    <h1>主页</h1>

    <a href="/servlet/logout">注销</a>
</body>
</html>      
2)效果图

测试非admin用户登录

【过滤器(Filter)编码过滤、登录权限拦截】+【监听器(xxxListener)HttpSessionListener接口】

被拦截

【过滤器(Filter)编码过滤、登录权限拦截】+【监听器(xxxListener)HttpSessionListener接口】

管理员用户登录

【过滤器(Filter)编码过滤、登录权限拦截】+【监听器(xxxListener)HttpSessionListener接口】

成功

【过滤器(Filter)编码过滤、登录权限拦截】+【监听器(xxxListener)HttpSessionListener接口】

未登录的情况下,直接通过url访问成功页,则被拦截,无法访问

【过滤器(Filter)编码过滤、登录权限拦截】+【监听器(xxxListener)HttpSessionListener接口】

监听器(xxxListener)

监听器的种类非常多,但基本机制类似。

测试

以HttpSessionListener接口做测试。

实例测试(HttpSessionListener接口)

1)主要代码

监听器(Listener)

//统计网站在线人数:统计Session,利用Session的监听器
public class OnlineCountListener implements HttpSessionListener {

    //创建Session监听
    //一旦创建一个Session,就会触发一次这个事件
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();
        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监听
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {

    }
}      

web.xml

<listener>
     <listener-class>com.zlc.listener.OnlineCountListener</listener-class>
 </listener>      

2)效果图

启动项目后,先重新部署,否则页面会显示有3个Session,但其实是一个,重启后就正常了

【过滤器(Filter)编码过滤、登录权限拦截】+【监听器(xxxListener)HttpSessionListener接口】