记录日志写入数据库实现查询

环境:dubbo 下的ssm框架

1.AOP切面代码(web层)

@Aspect
@Component
public class LogAopController {

    @Autowired
    private HttpServletRequest request; //需要在web.xml配置

    @Reference //注意不同的项目下不能使用@Autowired  要是用@Reference
    private ISysLogService service;

    private Date visitTime;//5开始时间
    private Class clazz;//6访问的类
    private Method method;//7访问的方法
/*
1如何获取操作者?
     * 2如何获取访问的ip
     * 3如何获取访问的url
     * 4如何获取执行的时长
*/



    //前置通知,主要获取开始时间,执行的类是哪一个,执行了哪个方法
    @Before("execution(* com.qingcheng.controller.goods.SpuController.*(..))")//.*是包下的所有类 .*是类下的所有方法
    public void doBefore(JoinPoint jp) throws NoSuchMethodException {
        visitTime=new Date();//当前时间就是开始的时间
        clazz=jp.getTarget().getClass();//获取类
        String methodName=jp.getSignature().getName();//只能获取方法的名字
        Object[] args = jp.getArgs();//获取访问的方法参数
        //获取具体的方法对象
        if (args == null||args.length == 0){
            //无参数
            method=clazz.getMethod(methodName); //根据方法的名字,只能获取无参数的方法
        }else {
            //有参数
            Class[] classArgs=new Class[args.length];
            for (int i=0;i<args.length;i++){
                classArgs[i]=args[i].getClass();//把方法的每个参数都存入到数组中
            }
            method=clazz.getMethod(methodName,classArgs);
        }

    }
    //后置通知
    @After("execution(* com.qingcheng.controller.goods.SpuController.*(..))")
    public void doAfter(JoinPoint jp){
        //4如何获取执行的时长?
        String time= String.valueOf(new Date().getTime()-visitTime.getTime());
        //3如何获取访问的url
        String url="";
        if(clazz!=null&&method!=null&&clazz!= LogAopController.class){
            //获取url @RequestMapping("/findAll.do")
            //子类 对象名= (子类) 父类; 强制转换 将父类对象赋予子类对象需要强制转换为子类对象(小知识点!!!!)
            RequestMapping classAnnotation = (RequestMapping) clazz.getAnnotation(RequestMapping.class);
            if(classAnnotation!=null){
                //1.获取类上的路径
                String[] classValue=classAnnotation.value();
                //2.获取方法上的路径
                RequestMapping methodAnnotation = method.getAnnotation(RequestMapping.class);
                if (methodAnnotation!=null){
                    String[] methodValue = methodAnnotation.value();//获取了方法上的路径
                    //类路径+方法路径
                    url=classValue[0]+methodValue[0];
                }
            }
        }
        //如何获取2如何获取访问的ip
        //1.配置web.xml 获取HttpServletRequest 2.注入依赖获取request对象
        String ip = request.getRemoteAddr(); ///获取ip

        //封装信息
        Syslog syslog=new Syslog();
        UUID uuid = UUID.randomUUID();
        syslog.setId(uuid.toString());//1
        syslog.setExecutionTime(time);//2
        syslog.setIp(ip);//3
        syslog.setMethod("[类]"+clazz.getName()+"[方法]"+method.getName());//4
        syslog.setUrl(url);//5
        syslog.setUsername("TEST");//6
        syslog.setVisitTime(visitTime);//7
        System.out.println(syslog);
        service.saveLog(syslog);

    }

}
View Code

2.配置mvc的xml文件

<context:component-scan base-package="扫描包路径"/>

<aop:aspectj-autoproxy proxy-target-class="true"/> <!-- 支持AOP的注解支持,AOP底层使用代理技术-->

3.web层的查询日志代码

@RestController
@RequestMapping("/spuLog")
public class LogSpuController {
    @Reference
    private ISysLogService spuService;
    @GetMapping("findAll")
    public List<Syslog> findAll(){
        return spuService.findAll();
    }
}
View Code

4.pojo

@Table(name = "tb_syslog")
public class Syslog implements Serializable {
    @Id
    private String id;
    private Date visitTime;
    private String visitTimestr; //注意 visitTimestr 设计数据库字段为visit_timestr Mapper才会识别
    private String username;
    private String ip;
    private String url;
    private String executionTime;
    private String method;
}
View Code

5.service接口

public interface ISysLogService {
    public void saveLog(Syslog syslog); //保存日志
    List<Syslog> findAll();//查询所有日志
}

6.service层下的dao (使用的通用mapper)

public interface ISysLogMapper extends Mapper<Syslog> {

}

7.service层下的接口实现

@Service
public class ISysLogServiceImpl implements ISysLogService {

    @Autowired
    private ISysLogMapper iSysLogMapper;

    public void saveLog(Syslog syslog) {//保存日志
        iSysLogMapper.insert(syslog);//当mysql数据库设置默认值时,如果使用insert插入会把字段为空的值也插入到数据库,所以数据库设置的默认值也没用
    }
    public List<Syslog> findAll() {
     return  iSysLogMapper.selectAll();
    }

}

切面配置好后会显示m->

 

 8.测试

posted @ 2019-12-28 15:55  三只坚果  阅读(2006)  评论(0编辑  收藏  举报