文档章节

利用spring AOP实现每个请求的日志输出

凯文加内特
 凯文加内特
发布于 2016/02/01 16:36
字数 636
阅读 271
收藏 15

前提条件:

除了spring相关jar包外,还需要引入aspectj包。

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.7.2</version>
  </dependency>

要实现此功能,必须完成以下几步:

1.在springmvc-servlet.xml中实现对AOP的支持

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:aop="http://www.springframework.org/schema/aop" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:mvc="http://www.springframework.org/schema/mvc"
  xsi:schemaLocation="   
  http://www.springframework.org/schema/beans   
  http://www.springframework.org/schema/beans/spring-beans-4.0.xsd   
  http://www.springframework.org/schema/context   
  http://www.springframework.org/schema/context/spring-context-4.0.xsd  
  http://www.springframework.org/schema/mvc   
  http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
  http://www.springframework.org/schema/aop 
         http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
         
  <aop:aspectj-autoproxy proxy-target-class="true"/>
  <bean class="com.yusj.interceptor.LogAspect" />
.
.
.
.
</beans>

2.注解的方法实现Aspect

package com.yusj.core.interceptor;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.google.gson.Gson;

/**
 * 
* @ClassName: LogAspect 
* @Description: 日志记录AOP实现 
* @author shaojian.yu
* @date 2014年11月3日 下午1:51:59 
*
 */
@Aspect
public class LogAspect {
  private final Logger logger = LoggerFactory.getLogger(this.getClass());

  private String requestPath = null ; // 请求地址
  private String userName = null ; // 用户名
  private Map<?,?> inputParamMap = null ; // 传入参数
  private Map<String, Object> outputParamMap = null; // 存放输出结果
  private long startTimeMillis = 0; // 开始时间
  private long endTimeMillis = 0; // 结束时间

  /**
   * 
   * @Title:doBeforeInServiceLayer
   * @Description: 方法调用前触发 
   *  记录开始时间 
   * @author shaojian.yu 
   * @date 2014年11月2日 下午4:45:53
   * @param joinPoint
   */
  @Before("execution(* com.yusj.controller..*.*(..))")
  public void doBeforeInServiceLayer(JoinPoint joinPoint) {
    startTimeMillis = System.currentTimeMillis(); // 记录方法开始执行的时间
  }

  /**
   * 
   * @Title:doAfterInServiceLayer
   * @Description: 方法调用后触发 
   *  记录结束时间
   * @author shaojian.yu 
   * @date 2014年11月2日 下午4:46:21
   * @param joinPoint
   */
  @After("execution(* com.yusj.controller..*.*(..))")
  public void doAfterInServiceLayer(JoinPoint joinPoint) {
    endTimeMillis = System.currentTimeMillis(); // 记录方法执行完成的时间
    this.printOptLog();
  }

  /**
   * 
   * @Title:doAround
   * @Description: 环绕触发 
   * @author shaojian.yu 
   * @date 2014年11月3日 下午1:58:45
   * @param pjp
   * @return
   * @throws Throwable
   */
  @Around("execution(* com.yusj.controller..*.*(..))")
  public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
    /**
     * 1.获取request信息
     * 2.根据request获取session
     * 3.从session中取出登录用户信息
     */
    RequestAttributes ra = RequestContextHolder.getRequestAttributes();
    ServletRequestAttributes sra = (ServletRequestAttributes)ra;
    HttpServletRequest request = sra.getRequest();
    // 从session中获取用户信息
    String loginInfo = (String) session.getAttribute("username");
    if(loginInfo != null && !"".equals(loginInfo)){
      userName = operLoginModel.getLogin_Name();
    }else{
      userName = "用户未登录" ;
    }
    // 获取输入参数
    inputParamMap = request.getParameterMap();
    // 获取请求地址
    requestPath = request.getRequestURI();
    
    // 执行完方法的返回值:调用proceed()方法,就会触发切入点方法执行
    outputParamMap = new HashMap<String, Object>();
    Object result = pjp.proceed();// result的值就是被拦截方法的返回值
    outputParamMap.put("result", result);
    
    return result;
  }

  /**
   * 
   * @Title:printOptLog
   * @Description: 输出日志 
   * @author shaojian.yu 
   * @date 2014年11月2日 下午4:47:09
   */
  private void printOptLog() {
    Gson gson = new Gson(); // 需要用到google的gson解析包
    String optTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(startTimeMillis);
    logger.info("\n user:"+userName
        +"  url:"+requestPath+"; op_time:" + optTime + " pro_time:" + (endTimeMillis - startTimeMillis) + "ms ;"
        +" param:"+gson.toJson(inputParamMap)+";"+"\n result:"+gson.toJson(outputParamMap));
  }
}


本文转载自:http://www.tuicool.com/articles/NnmM3ef

共有 人打赏支持
凯文加内特
粉丝 334
博文 670
码字总数 94314
作品 0
青岛
后端工程师
SpringCloud拦截器使用(Interceptors拦截器使用)

SpringCloud后端要对前端请求进行拦截,也就是日志记录,使用SpringAOP方式即面向切面方式进行拦截。 首先,拦截请求地址(ip),使用HandlerInterceptorAdapter,它拦截的是请求地址,所以针...

Bug-Killer
05/10
0
0
基于SpringAop 的统一验证

背景 在我们的项目实际开发中,由于使用dubbo框架,项目的所有的接口都是按照一定的规范来开发的,项目接口层的接口如下: 系统按照功能分包,所有的功能下面,都会有domain(VO数据),request...

顾志雄
2016/06/30
135
0
java技术栈

参考了众多资料,这里就不再详细列举了,可以自行去搜索 1 java基础: 1.1 算法 - 1.1 排序算法:直接插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序、基数排序-...

乒乓狂魔
2016/07/29
5K
9
Spring、Spring Boot 和 TestNG 测试指南 ( 7 )

原文出处:chanjarster Spring提供了一套AOP工具,但是当你把各种Aspect写完之后,如何确定这些Aspect都正确的应用到目标Bean上了呢?本章将举例说明如何对Spring AOP做测试。 首先先来看我们...

chanjarster
2017/12/15
0
0
Spring AOP+反射实现自定义动态配置校验规则,让校验规则飞起来

原文作者:弥诺R 原文地址:http://www.minuor.com/1524369999/article 转载声明:转载请注明原文地址,注意版权维护,谢谢! 场景小计 之前项目都是使用hibernate-validator来校验参数,但是...

兴趣e族
04/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Django支持中文

django是支持中文界面, 先找到Django语言包安装目录,我的在: /usr/local/python3/lib/python3.6/site-packages/django/conf/locale 有zh-Hans和zh-Hant两个文件, 其中zh-Hans是简体中文,...

MichaelShu
18分钟前
1
0
迷宫问题:顺序栈解法

采用顺序栈以及回溯法,一个比较简单的问题,但是从来没有写过,也算是弥补一下自己欠数据结构的债吧,居然也花了一个半小时,无地自容了。。 定义好数据结构求解算法就显得容易一些了。 st...

LoSingSang
24分钟前
0
0
Zookeeper 概述及应用场景

一、概述 分布式协调技术,主要用来解决分布式环境当中多个进程之间的同步控制,让他们有序的去访问某种临界资源,防止造成"脏数据"的后果。 ZooKeeper是一个分布式的,开放源码的分布式应用...

PeakFang-BOK
32分钟前
0
0
(译)OpenGL ES2.0 – Iphone开发指引

教程截图: OpenGL ES 是可以在iphone上实现2D和3D图形编程的低级API。 如果你之前接触过 cocos2d,sparrow,corona,unity 这些框架,你会发现其实它们都是基于OpenGL上创建的。 多数程序员...

robslove
42分钟前
0
0
金九银十跳槽季,程序员面试点解析之Java专场

前言 近年来Java工程师这个岗位炙手可热,市场需求大,学习Java的人也越来越多,所以IT企业与求职者的选择都比较多,那么IT企业在面试时都会提哪些问题呢。下面为大家分享 Java高级工程师面试...

老道士
44分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部