记录日志写入数据库实现查询
环境: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);
}
}
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();
}
}
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;
}
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.测试