天天看點

【過濾器(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接口】