aop切面打印日志

最近在做一块将所有接口的返回值body值接口地址ip地址等都打印字日志中。这样查找错误比较方便,

解决当前问题用aop切面来工作。下面是代码:

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
public class WebLogAspect {

//配置文件配置logging.printFlag (1打印日志0不打印日志)

    @Value("${logging.printFlag}")
    private int printFlag;
    private static Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
     
    // 定义切点Pointcut所有@RequestMappping注解的方法
    @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
    public void excudeService() {
    }
 
 
 
 
    @Around("excudeService()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String url = request.getRequestURL().toString();
        String method = request.getMethod();
        String uri = request.getRequestURI();
        String queryString = request.getQueryString();
        Object[] args = pjp.getArgs();
        String params = "";
        //获取请求参数集合并进行遍历拼接
        if(args.length>0){
            if("POST".equals(method)){
                Object object = args[0];
                Map map = getKeyAndValue(object);
                params = JSON.toJSONString(map);
            }else if("GET".equals(method)){
                params = queryString;
            }
        }
        if(printFlag == 1){
            Map<String, String> Headermap = new HashMap<String, String>();
            Enumeration headerNames = request.getHeaderNames();
            //获取Header
            while (headerNames.hasMoreElements()) {
                String key = (String) headerNames.nextElement();
                String value = request.getHeader(key);
                Headermap.put(key, value);
            }
            Set<String> keys = Headermap.keySet();   //此行可省略,直接将map.keySet()写在for-each循环的条件中
            logger.warn("\n"+"Header获取时间:"+df.format(new Date()));
            for(String key:keys){
                logger.warn("Header键: "+key+"\t"+"Header值:"+Headermap.get(key));
            }
            logger.info("\n"+"客户端操作IP:"+"\t"+request.getRemoteAddr());//远程IP,即客户端IP
            logger.warn("\n"+"客户端操作端口:"+"\t"+String.valueOf(request.getRemotePort()));//远程端口,即客户端端口
            logger.warn("\n"+"操作地址时间:"+"\t"+df.format(new Date()));
            logger.info("\n"+"请求地址:"+"\t"+url);
            logger.info("\n"+"请求类型:"+"\t"+method);
            logger.info("\n"+"请求参数:"+"\t"+params);

            //转发request,解决io流读取一次的问题,RequestWrapper类会在另一篇博文写到
            RequestWrapper requestWrapper = new RequestWrapper(request);
            String body = requestWrapper.getBody();
            logger.warn("\n"+"Body值时间:"+"\t"+df.format(new Date()));
            logger.info("\n"+"Body值:"+"\t"+body);
        }
         
        // result的值就是被拦截方法的返回值
        Object result = pjp.proceed();
        if(printFlag == 1){
            Object json = JSONObject.toJSON(result);
            if(result != null){
                JSONObject parseObject = JSONObject.parseObject(json.toString());
                logger.info("\n"+"请求返回时间:"+"\t"+df.format(new Date()));
                logger.info("\n"+"请求返回值:" + JSONObject.toJSONString(parseObject,SerializerFeature.PrettyFormat));
            }
        }
        return result;
    }
 
    public static Map<String, Object> getKeyAndValue(Object obj) {
        Map<String, Object> map = new HashMap<>();
        // 得到类对象
        Class userCla = (Class) obj.getClass();
        /* 得到类中的所有属性集合 */
        Field[] fs = userCla.getDeclaredFields();
        for (int i = 0; i < fs.length; i++) {
            Field f = fs[i];
            f.setAccessible(true); // 设置些属性是可以访问的
            Object val = new Object();
            try {
                val = f.get(obj);
                // 得到此属性的值
                map.put(f.getName(), val);// 设置键值
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
 
            }
        return map;
    }
    
}
pom.xml配置

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值