JavaWeb2025.02.28

发布于:2025-03-05 ⋅ 阅读:(18) ⋅ 点赞:(0)

JavaWeb

2025.03.03 javaWeb学习日记

今天主要是完成了黑马给的文档里面day13的作业,熟悉了AOP的使用方法。同时也进入到了前端关于Vue的方面,主要是认识一个简单的vue项目开发流程,学习选项式API和组合式API,知道了两者如何进行转化,在什么场景下用更好。

前端页面今天学习的部分较为简单,只是一个简单的转化,就不记录了。

记录下黑马day14里面的作业4

题目:基于springAOP技术完成如下需求。

**需求:**记录当前 tlias 智能学习辅助系统中所有员工的登录操作 (切入点:execution(…); 通知类型:@Around) ,无论登录成功还是失败,都需要记录日志。

日志信息包含如下信息:

  • 用户名 (登录时,输入的用户名) ----- 【提示:用户名在原始方法执行时的参数中 – 获取到参数可以强转】
  • 密码 (登录时,输入的密码) -------- 【提示:密码在原始方法执行时的参数中 – 获取到参数可以强转 】
  • 操作时间 (什么时间,员工登录的)
  • 登录是否成功 ------ 【提示:在原始方法执行后的返回值中,可以通过Result来获取code从而判断成功还是失败 – 可以强转】
  • 登录成功后,下发的jwt令牌 ------ 【提示:jwt在原始方法执行后的返回值中 – 可以强转】
  • 登录操作耗时

创建表结构和实体类有对应的代码,这里就不展示了

解题思路:

其实只要理解了AOP的作用,这道题也是比较简单的。

一开始,自己对AOP的作用没有理解正确,以为是在代码里面调用了目标对象的方法后,才能获取对应的值。但其实在参数传入到对应的方法的时候,该方法就被@Around通知拦截了。拦截器就会立即获取到确定的参数。所以整个过程其实是三个顺序。

  1. 前置处理:首先获取传入的参数,在用户登陆的时候,就会传入对应的emp参数,这个时候获取到用户输入的对应的username和password的值
  2. 调用目标方法:通过joinPoint.proceed()执行实际的登录逻辑.调用目标方,获得对应的返回值。
  3. 根据返回值来判断登录是否成功,登陆成功了,就再获取token的值,登陆失败了,就设置success为失败。同时需要捕获异常,如果发生了异常,那么也是登录失败了。但要先在数据库中记录对应的值,再抛出异常。

代码示例:

package com.itheima.aop;

import com.itheima.mapper.EmpLoginLogMapper;
import com.itheima.pojo.Emp;
import com.itheima.pojo.EmpLoginLog;
import com.itheima.pojo.LoginInfo;
import com.itheima.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Slf4j
@Component
@Aspect
public class OperationLoginLogAspect {
    @Autowired
    private EmpLoginLogMapper empLoginLogMapper;

    @Around("@annotation(com.itheima.anno.LoginOperation)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        //获取传入的参数
        Object[] args = joinPoint.getArgs();
        Emp emp = null;
        if(args!=null&&args.length >0 && args[0] instanceof Emp){
            emp=(Emp)args[0];
        }
        EmpLoginLog loginLog = new EmpLoginLog();
        if (emp!=null){
            loginLog.setUsername(emp.getUsername());
            loginLog.setPassword(emp.getPassword());
        }
        loginLog.setLoginTime(LocalDateTime.now());

        Object result = null;
        try {
            result=joinPoint.proceed();
            if(result instanceof Result){
                Result res=(Result) result;
                if(res.getCode()==1){
                    loginLog.setIsSuccess((short)1);
                    if(res.getData() instanceof LoginInfo){
                        LoginInfo info=(LoginInfo) res.getData();
                        loginLog.setJwt(info.getToken());
                    }
                }else {
                    loginLog.setIsSuccess((short)0);
                }
            }else {loginLog.setIsSuccess((short)0);}
        }catch (Exception e){
            log.info("登录异常",e);
            loginLog.setIsSuccess((short)0);
            long endTime=System.currentTimeMillis();
            loginLog.setCostTime(endTime-startTime);
            empLoginLogMapper.insert(loginLog);
            //插入日志操作后,再处理异常
            throw e;
        }
        long endTime=System.currentTimeMillis();
        loginLog.setCostTime(endTime-startTime);
        empLoginLogMapper.insert(loginLog);
        return result;
    }
}

整个流程没有很困难,但要注意对应的细节。记得加上@Aspect 注解

这个是自定义的接口的示例,将接口添加在需要通知的方法和类上,添加到登录逻辑的控制层即可。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginOperation {
}

总的来说没有很难,就是对传入的参数进行前置处理,对调用完目标方法后的结果进行后置处理!

今天算法花费的事件较长,学习项目的时间较短,但也是有对应的收获的,希望后续也有时间写写总结,巩固当天所学习的知识。


网站公告

今日签到

点亮在社区的每一天
去签到