Java利用過濾器實現完善登錄功能
1、問題引入
我們已經完成了后臺系統(tǒng)的登錄功能開發(fā),但是目前還存在一個問題,就是用戶如果不登錄,直接訪問系統(tǒng)首頁面,照樣可以正常訪問。
很明顯,上面這種情況并不合理,我們希望看到的效果應該是,只有登錄成功后才可以訪問系統(tǒng)中的頁面,如果沒有登錄, 訪問系統(tǒng)中的任何界面都直接跳轉到登錄頁面。
2、解決思路
使用 過濾器或者攔截器來實現,在過濾器、攔截器中攔截前端發(fā)起的請求,判斷用戶是否已經完成登錄,如果沒有登錄則返回提示信息,跳轉到登錄頁面,那我這篇博客選擇的是過濾器來實現這個效果。

過濾器具體的處理邏輯如下:
A. 獲取本次請求的URI
B. 判斷本次請求, 是否需要登錄, 才可以訪問
C. 如果不需要,則直接放行
D. 判斷登錄狀態(tài),如果已登錄,則直接放行
E. 如果未登錄, 則返回未登錄結果
如果未登錄,我們需要給前端返回什么樣的結果呢? 這個時候, 可以去看看前端代碼是如何處理的,大家可以先看看我這里的前端是如何處理的。(每個前端處理方式都不一樣,隨機應變)

這個是我們前端的攔截器,這個攔截器就是用來攔截我們服務端給頁面上的響應的,一旦我們后端給前端響應之后,它就會執(zhí)行下面的代碼進行判斷。
大家也可以看到它里面的if判斷 ,如果我們后端給前端返回的數據是
res.data.code = 0 && res.data.msg='NOTLOGIN'
那它就會自動跳到登錄界面。
3、代碼實現
3.1 定義登錄校驗過濾器
首先我們創(chuàng)建一個過濾器 LoginCheckFilter 并實現 Filter 接口, 在doFilter方法中完成校驗的邏輯。
/**
* @description: 檢查用戶是否已經完成登錄
* @author: Jie
* @date: 2022/8/10 9:48
**/
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
}
}注:
@WebFilter :用于將一個類聲明為過濾器,filterName 指定過濾器的名稱,urlPatterns :需要攔截的請求路徑
首先我們要獲取到 request 和 response 和請求路徑,這三位后面都會用到。

現在我們獲取到了請求路徑,就可以去判斷哪些請求路徑是需要進行處理的,因為在項目實際開發(fā)中,我們的項目中有些地方是不需要登錄也能進行訪問的,比如淘寶和京東的首頁,大家不登陸也能訪問吧,所以我們要將這些路徑定義出來,如果用戶訪問的是這些路徑,那么我們就直接放行,就不處理了。

上面就是我定義不需要攔截的請求路徑,相信大家看到了最后兩個路徑有些不一樣,這里呢我們用的是通配符的方式。
通配符規(guī)則:
| 符號 | 含義 |
|---|---|
| ? | 匹配一個字符 |
| * | 匹配0個或多個字符 |
| ** | 匹配0個或多個目錄/字符 |
但是現在有一個問題,比如我現在請求的是/backend/index.html ,這對不上呀!那該如何去匹配呢?
這個時候我們就要認識一個新的對象 AntPathMatcher 。

現在我們通過這個路徑匹配器,匹配一下這個請求過來的路徑是否能匹配上我們定義不需要攔截的請求路徑里的任意一項。
這里我們封裝一個方法用來判斷本次請求是否需要處理。

這樣我們在上面調用,然后判斷一下是否需要處理,如果不需要處理,那就直接放行即可。

反之就是需要判斷是否需要登錄,那我們如何判斷用戶是否登錄呢?因為我是登錄的時候將用戶的信息存到session 里的 ,那這里我就是 從session 里 獲取登錄用戶,如果能獲取出來,就代表用戶已經登錄。

如果用戶沒有登錄我們就需要通過輸出流方式向客戶端頁面響應數據。

完整代碼 :
package com.jie.reggjie.filter;
import cn.hutool.core.text.AntPathMatcher;
import com.alibaba.fastjson.JSON;
import com.jie.reggjie.common.R;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @description: 檢查用戶是否已經完成登錄
* @author: Jie
* @date: 2022/8/10 9:48
**/
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
/**
* 路徑匹配器,支持通配符
*/
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String requestURI = request.getRequestURI();
log.info("攔截到請求,{}", requestURI);
//2、判斷本次請求是否需要處理
//定義不需要處理的請求路徑
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**"
};
boolean check = check(urls, requestURI);
//3、如果不需要處理,則直接放行
if (check) {
log.info("本次請求{}不需要處理", requestURI);
filterChain.doFilter(request, response);
return;
}
//4、判斷登錄狀態(tài),如果已登錄,則直接放行
if (request.getSession().getAttribute("employee") != null) {
log.info("用戶已登錄,用戶id為:{}", request.getSession().getAttribute("employee"));
filterChain.doFilter(request, response);
return;
}
log.info("用戶未登錄");
//5、如果未登錄則返回未登錄結果,通過輸出流方式向客戶端頁面響應數據
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
return;
}
public boolean check(String[] urls, String requestURI) {
for (String url : urls) {
boolean match = PATH_MATCHER.match(url, requestURI);
if (match) {
return true;
}
}
return false;
}
}3.2 開啟組件掃描
需要在啟動類上, 加上Servlet組件掃描的注解, 來掃描過濾器配置的@WebFilter注解, 掃描上之后, 過濾器在運行時就生效了。

到此這篇關于Java利用過濾器實現完善登錄功能的文章就介紹到這了,更多相關Java過濾器 登錄內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring?IOC容器基于XML外部屬性文件的Bean管理
這篇文章主要為大家介紹了Spring?IOC容器Bean管理XML外部屬性文件,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05
springBoot的事件機制GenericApplicationListener用法解析
這篇文章主要介紹了springBoot的事件機制GenericApplicationListener用法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值的相關資料2019-09-09

