網站首頁 編程語言 正文
? ? ? ? 前后端分離的開發中,用戶http請求應用服務的接口時, 如果要求檢測該用戶是否已登錄。可以實現的方法有多種, 本示例是通過aop 的方式實現,簡單有效。
? ? ? ? 約定:前端http的post?請求
export async function request(url,data) {
const config = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
}
//每個請求的參數要求附加sessionid, 該sessionid 是登錄時生成的
const paramsData = Object.assign(data,{sessionid:globalData.sessionID || ''})
config.body = JSON.stringify(paramsData)
try {
const res = await window.fetch(url, config)
if(res.status!==200){
return {
status: res.status,
data:{},
headers: res.headers,
url: res.url,
statusText:res.statusText
}
}
return {
status: res.status,
data:await res.json(),
headers: res.headers,
url: res.url,
}
} catch (err) {
return {
status: 404,
data:{},
headers: res.headers,
url: res.url,
statusText:'fetch error:'+err.toString()
}
}
}
1、在pom.xml 引用
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2、創建插入標記
@Target({ElementType.METHOD}) // 只在對象方法上標記
@Retention(RetentionPolicy.RUNTIME) //運行時反射
public @interface Interceptor {
String additionalMessage() default "";
}
3、實現切入類
@Aspect
@Component
@Slf4j
public class LoggingAspect {
@Autowired
public StringRedisTemplate redisTemplatelocate;
private <T> T getSessionID(Object postData,Class<T> clazz){
return (T)postData;
}
@Around("@annotation(Interceptor)") //有標記的地方將實現以下和切入
public Object logExecutionTime(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
//獲取切入方法的參數,就是前部請求的json數據
Object[] args = proceedingJoinPoint.getArgs();
//獲取其中的sessionid
// requestBase 實體類只有一個參sessionid , 做為其它實體類的父類,用于接收接口上傳的參數。
RequestBase requestBase=getSessionID(args[0],RequestBase.class);
log.info("sessionid:{}",requestBase.getSessionid());
//檢測該sessionid 是否存在(redis)
if (requestBase.getSessionid()==null || !redisTemplatelocate.hasKey(requestBase.getSessionid())) {
//用戶未登陸
throw new Exception("用戶未登陸");
}
//獲取 request 和 response
ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
log.info("request:{}",servletRequestAttributes.getRequest());
log.info("response:{}",servletRequestAttributes.getResponse());
MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
String className = methodSignature.getDeclaringType().getSimpleName();
String methodName = methodSignature.getMethod().getName();
Instant startTime = Instant.now();
//實行被切入的方法
Object result = proceedingJoinPoint.proceed();
String additionalMessage = methodSignature.getMethod().getAnnotation(Interceptor.class).additionalMessage();
long elapsedTime = Duration.between(startTime, Instant.now()).toMillis();
log.info("Class Name: {}, Method Name: {}, Additional Message: {}, Elapsed Time: {}ms",
className, methodName, additionalMessage, elapsedTime);
log.info("Result: {}", result);
return result;
}
}
4 建立api接口,在需要檢測的方法上加入@Interceptor 就完成切入的檢測。
@RestController
@Slf4j
public class ExampleController {
@PostMapping("/t1")
@Interceptor(additionalMessage = "要求檢測登錄")
@ResponseBody
public ResponseEntity<RequestBase> getData(@RequestBody DataRequest req) {
try {
return new ResponseEntity<>(req, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
}
}
}
5 實體類
@Data
public class DataRequest extends RequestBase {
private String name;
}
@Data
public class RequestBase{
private String sessionid;
}
? ?該方法只適用于少部分需要檢測,而大部份不需要檢測的情況下,如果整個包都需要檢測的,利用execution方?法實現
@Pointcut("execution(public * com.example.myapp..*.*(..))")
@Aspect
@Component
@Slf4j
public class LoginExecution {
@Autowired
public StringRedisTemplate redisTemplatelocate;
private <T> T getSessionID(Object postData,Class<T> clazz){
return (T)postData;
}
//切入點: com.aop.ttt 下的所有public 方法
@Pointcut("execution(public * com.aop.ttt..*.*(..))")
public void publicMethods() {}
@Around("publicMethods()")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
//獲取切入方法的參數,就是前部請求的json數據
Object[] args = joinPoint.getArgs();
//獲取其中的sessionid
// requestBase 實體類只有一個參sessionid , 做為其它實體類的父類,用于接收接口上傳的參數。
RequestBase requestBase=getSessionID(args[0],RequestBase.class);
log.info("sessionid:{}",requestBase.getSessionid());
//檢測該sessionid 是否存在(redis)
if (requestBase.getSessionid()==null || !redisTemplatelocate.hasKey(requestBase.getSessionid())) {
//用戶未登陸
throw new Exception("用戶未登陸");
}
//獲取 request 和 response
ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
log.info("request:{}",servletRequestAttributes.getRequest());
log.info("response:{}",servletRequestAttributes.getResponse());
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
String className = methodSignature.getDeclaringType().getSimpleName();
String methodName = methodSignature.getMethod().getName();
Instant startTime = Instant.now();
//實行被切入的方法
Object result = joinPoint.proceed();
long elapsedTime = Duration.between(startTime, Instant.now()).toMillis();
log.info("Class Name: {}, Method Name: {}, Elapsed Time: {}ms",
className, methodName, elapsedTime);
log.info("Result: {}", result);
return result;
}
}
原文鏈接:https://blog.csdn.net/ganyuanmen/article/details/136129364
- 上一篇:沒有了
- 下一篇:沒有了
相關推薦
- 2022-08-28 虛擬機ubuntu通過fdisk命令擴充硬盤容量,分區簡單說明
- 2022-04-27 Python學習筆記之字典,元組,布爾類型和讀寫文件_python
- 2021-12-09 Typora自動編號的具體操作_其它綜合
- 2022-01-17 自動化實戰之Cypress(一):環境搭建
- 2022-03-26 c語言實現可自定義的游戲地圖_C 語言
- 2022-11-26 React常見跨窗口通信方式實例詳解_React
- 2022-04-08 iOS實現計算器小功能_IOS
- 2022-06-08 Spring Cloud Alibaba Nacos Config 加載配置
- 欄目分類
-
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支