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

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

這個(gè)是我們前端的攔截器,這個(gè)攔截器就是用來(lái)攔截我們服務(wù)端給頁(yè)面上的響應(yīng)的,一旦我們后端給前端響應(yīng)之后,它就會(huì)執(zhí)行下面的代碼進(jìn)行判斷。
大家也可以看到它里面的if判斷 ,如果我們后端給前端返回的數(shù)據(jù)是
res.data.code = 0 && res.data.msg='NOTLOGIN'
那它就會(huì)自動(dòng)跳到登錄界面。
3、代碼實(shí)現(xiàn)
3.1 定義登錄校驗(yàn)過(guò)濾器
首先我們創(chuàng)建一個(gè)過(guò)濾器 LoginCheckFilter 并實(shí)現(xiàn) Filter 接口, 在doFilter方法中完成校驗(yàn)的邏輯。
/**
* @description: 檢查用戶(hù)是否已經(jīng)完成登錄
* @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 :用于將一個(gè)類(lèi)聲明為過(guò)濾器,filterName 指定過(guò)濾器的名稱(chēng),urlPatterns :需要攔截的請(qǐng)求路徑
首先我們要獲取到 request 和 response 和請(qǐng)求路徑,這三位后面都會(huì)用到。

現(xiàn)在我們獲取到了請(qǐng)求路徑,就可以去判斷哪些請(qǐng)求路徑是需要進(jìn)行處理的,因?yàn)樵陧?xiàng)目實(shí)際開(kāi)發(fā)中,我們的項(xiàng)目中有些地方是不需要登錄也能進(jìn)行訪(fǎng)問(wèn)的,比如淘寶和京東的首頁(yè),大家不登陸也能訪(fǎng)問(wèn)吧,所以我們要將這些路徑定義出來(lái),如果用戶(hù)訪(fǎng)問(wèn)的是這些路徑,那么我們就直接放行,就不處理了。

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

現(xiàn)在我們通過(guò)這個(gè)路徑匹配器,匹配一下這個(gè)請(qǐng)求過(guò)來(lái)的路徑是否能匹配上我們定義不需要攔截的請(qǐng)求路徑里的任意一項(xiàng)。
這里我們封裝一個(gè)方法用來(lái)判斷本次請(qǐng)求是否需要處理。

這樣我們?cè)谏厦嬲{(diào)用,然后判斷一下是否需要處理,如果不需要處理,那就直接放行即可。

反之就是需要判斷是否需要登錄,那我們?nèi)绾闻袛嘤脩?hù)是否登錄呢?因?yàn)槲沂堑卿浀臅r(shí)候?qū)⒂脩?hù)的信息存到session 里的 ,那這里我就是 從session 里 獲取登錄用戶(hù),如果能獲取出來(lái),就代表用戶(hù)已經(jīng)登錄。

如果用戶(hù)沒(méi)有登錄我們就需要通過(guò)輸出流方式向客戶(hù)端頁(yè)面響應(yīng)數(shù)據(jù)。

完整代碼 :
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: 檢查用戶(hù)是否已經(jīng)完成登錄
* @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("攔截到請(qǐng)求,{}", requestURI);
//2、判斷本次請(qǐng)求是否需要處理
//定義不需要處理的請(qǐng)求路徑
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**"
};
boolean check = check(urls, requestURI);
//3、如果不需要處理,則直接放行
if (check) {
log.info("本次請(qǐng)求{}不需要處理", requestURI);
filterChain.doFilter(request, response);
return;
}
//4、判斷登錄狀態(tài),如果已登錄,則直接放行
if (request.getSession().getAttribute("employee") != null) {
log.info("用戶(hù)已登錄,用戶(hù)id為:{}", request.getSession().getAttribute("employee"));
filterChain.doFilter(request, response);
return;
}
log.info("用戶(hù)未登錄");
//5、如果未登錄則返回未登錄結(jié)果,通過(guò)輸出流方式向客戶(hù)端頁(yè)面響應(yīng)數(shù)據(jù)
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 開(kāi)啟組件掃描
需要在啟動(dòng)類(lèi)上, 加上Servlet組件掃描的注解, 來(lái)掃描過(guò)濾器配置的@WebFilter注解, 掃描上之后, 過(guò)濾器在運(yùn)行時(shí)就生效了。

到此這篇關(guān)于Java利用過(guò)濾器實(shí)現(xiàn)完善登錄功能的文章就介紹到這了,更多相關(guān)Java過(guò)濾器 登錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
前端和后端時(shí)間不一致問(wèn)題解決的實(shí)踐指南
這篇文章主要給大家介紹了關(guān)于前端和后端時(shí)間不一致問(wèn)題解決的實(shí)踐指南,在SpringBoot項(xiàng)目中,可以通過(guò)設(shè)置application.yml文件中的屬性來(lái)統(tǒng)一時(shí)間格式和時(shí)區(qū),從而確保序列化和反序列化過(guò)程中的時(shí)間和時(shí)區(qū)一致性,需要的朋友可以參考下2025-01-01
Mybatis-Plus自動(dòng)填充更新操作相關(guān)字段的實(shí)現(xiàn)
數(shù)據(jù)庫(kù)表中應(yīng)該都要有create_time、update_time字段;那么在開(kāi)發(fā)中,對(duì)于這些共有字段的處理應(yīng)該要進(jìn)行統(tǒng)一,這樣就可以簡(jiǎn)化我們的開(kāi)發(fā)過(guò)程。那么本文就對(duì)Mybatis-Plus中的字段自動(dòng)填充進(jìn)行記錄2021-11-11
淺析java中String類(lèi)型中“==”與“equal”的區(qū)別
這篇文章主要介紹了淺析java中String類(lèi)型中“==”與“equal”的區(qū)別,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
JavaWeb 簡(jiǎn)單分頁(yè)實(shí)現(xiàn)代碼
這篇文章主要介紹了JavaWeb 簡(jiǎn)單分頁(yè)實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2016-11-11
springboot整合sentinel接口熔斷的實(shí)現(xiàn)示例
為了防止慢接口導(dǎo)致的服務(wù)阻塞,可以通過(guò)添加熔斷處理來(lái)避免應(yīng)用的大量工作線(xiàn)程陷入阻塞,保證其他接口的正常運(yùn)行,本文介紹了如何使用Spring Boot與Sentinel進(jìn)行接口熔斷的配置與實(shí)現(xiàn),感興趣的可以了解一下2024-09-09
SpringBoot實(shí)現(xiàn)反向代理的示例代碼
本文主要介紹了SpringBoot實(shí)現(xiàn)反向代理的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06
Spring中使用JSR303請(qǐng)求約束判空的實(shí)現(xiàn)
這篇文章主要介紹了Spring中使用JSR303請(qǐng)求約束判空的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12

