• spring集成mongodb通过aop记录业务日志


    1. 编辑 pom.xml 添加 maven 依赖

    <!-- mongodb -->
            <dependency>
              <groupId>org.mongodb</groupId>
              <artifactId>mongo-java-driver</artifactId>
              <version>2.14.2</version>
            </dependency>
            <dependency>
              <groupId>org.springframework.data</groupId>
              <artifactId>spring-data-mongodb</artifactId>
              <!-- 都是坑,用最新版的报错,下面全部用回1.7.1版 -->
              <version>1.7.1.RELEASE</version>
            </dependency>
            <dependency>
              <groupId>org.springframework.data</groupId>
              <artifactId>spring-data-mongodb-cross-store</artifactId>
              <version>1.7.1.RELEASE</version>
            </dependency>
            <dependency>
              <groupId>org.springframework.data</groupId>
              <artifactId>spring-data-mongodb-log4j</artifactId>
              <version>1.7.1.RELEASE</version>
            </dependency>
            <!-- mongodb -->

    2.添加 spring-mongodb.xml 配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mongo="http://www.springframework.org/schema/data/mongo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd">
    
        <!--连接池配置-->
        <mongo:mongo id="mongo" host="host" port="port">
            <mongo:options connections-per-host="8"
                           threads-allowed-to-block-for-connection-multiplier="4"
                           connect-timeout="1000"
                           max-wait-time="1500"
                           auto-connect-retry="true"
                           socket-keep-alive="true"
                           socket-timeout="1500"
                           slave-ok="true"
                           write-number="1"
                           write-timeout="0"
                           write-fsync="true"/>
        </mongo:mongo>
    
        <!--连接池工厂配置-->
        <mongo:db-factory dbname="dbname" username="username" password="pwd" mongo-ref="mongo"/>
    
        <!-- MongoDBTemplate -->
        <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
            <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
        </bean>
    </beans>

    3.在 applicationContext.xml 文件中引用 spring-mongodb.xml

    <import resource="spring-mongodb.xml" />

    4.若 aop 在controller 层不生效,则需要在 springmvc 配置文件添加如下配置

    <aop:aspectj-autoproxy proxy-target-class="true"/>

    5.集成 MongoTemplate

      Model

    import org.springframework.data.mongodb.core.mapping.Document;
    
    @Document(collection = "business_log")
    public class BusinessLogInfo {
        /**
         * 日志级别:INFO,WARN,ERROR,DEBUG
         */
        private String level;
        /**
         * 客户端ip
         */
        private String clientIp;
        /**
         * 服务端ip,用于区分是哪台服务器
         */
        private String serverIp;
        /**
         * 请求url
         */
        private String requestUrl;
        /**
         * 目标类
         */
        private String targetClass;
        /**
         * 目标方法
         */
        private String targetMethod;
        /**
         * 请求参数
         */
        private String requestParam;
        /**
         * 日志内容
         */
        private String content;
        /**
         * 异常
         */
        private String exception;
        /**
         * 日志记录时间
         */
        private String createDate;
        
        public String getLevel() {
            return level;
        }
        public void setLevel(String level) {
            this.level = level;
        }
        public String getClientIp() {
            return clientIp;
        }
        public void setClientIp(String clientIp) {
            this.clientIp = clientIp;
        }
        public String getServerIp() {
            return serverIp;
        }
        public void setServerIp(String serverIp) {
            this.serverIp = serverIp;
        }
        public String getRequestUrl() {
            return requestUrl;
        }
        public void setRequestUrl(String requestUrl) {
            this.requestUrl = requestUrl;
        }
        public String getTargetClass() {
            return targetClass;
        }
        public void setTargetClass(String targetClass) {
            this.targetClass = targetClass;
        }
        public String getTargetMethod() {
            return targetMethod;
        }
        public void setTargetMethod(String targetMethod) {
            this.targetMethod = targetMethod;
        }
        public String getRequestParam() {
            return requestParam;
        }
        public void setRequestParam(String requestParam) {
            this.requestParam = requestParam;
        }
        public String getContent() {
            return content;
        }
        public void setContent(String content) {
            this.content = content;
        }
        public String getException() {
            return exception;
        }
        public void setException(String exception) {
            this.exception = exception;
        }
        public String getCreateDate() {
            return createDate;
        }
        public void setCreateDate(String createDate) {
            this.createDate = createDate;
        }
        
        @Override
        public String toString() {
            return "BusinessLogInfo [level=" + level + ", clientIp=" + clientIp + ", serverIp=" + serverIp + ", requestUrl="
                    + requestUrl + ", targetClass=" + targetClass + ", targetMethod=" + targetMethod + ", requestParam="
                    + requestParam + ", content=" + content + ", exception=" + exception + ", createDate=" + createDate
                    + "]";
        }    
    }

      Dao

    import org.springframework.data.mongodb.core.MongoTemplate;
    
    public interface MongoDao {
        // insert
        void insert(MongoTemplate mongoTemplate, Object obj);
        
         find
        @SuppressWarnings("hiding")
        <T> List<T> find(MongoTemplate mongoTemplate, Query query, Class<T> clazz);
        
        // findOne
        @SuppressWarnings("hiding")
        <T> T findOne(MongoTemplate mongoTemplate, Query query, Class<T> clazz);
        
        // modify
        
        // del
    }

      DaoImpl

    import org.springframework.data.mongodb.core.MongoTemplate;
    import org.springframework.stereotype.Service;

    @Service
    public class MongoDaoImpl implements MongoDao{
    // insert
        @Override
        public void insert(MongoTemplate mongoTemplate, Object obj) {
            mongoTemplate.insert(obj);        
        }
    
        // find
        @SuppressWarnings("hiding")
        @Override
        public <T> List<T> find(MongoTemplate mongoTemplate, Query query, Class<T> clazz) {
            return mongoTemplate.find(query, clazz);
        }
    
        // findOne
        @SuppressWarnings("hiding")
        @Override
        public <T> T findOne(MongoTemplate mongoTemplate, Query query, Class<T> clazz) {
            return mongoTemplate.findOne(query, clazz);
        }
    }

      Service

    public interface MongoService {
        // insert
        void insert(Object obj);
        
        // find
        <T> List<T> find(Query query, Class<T> clazz);
        
        // findOne
        <T> T findOne(Query query, Class<T> clazz);
    }

      ServiceImpl

    import javax.annotation.Resource;
    import org.springframework.data.mongodb.core.MongoTemplate;
    import org.springframework.stereotype.Service;
    
    @Service("mongoService")
    public class MongoServiceImpl implements MongoService {
        @Resource
        MongoDao mongoDao;
        
        @Resource(name = "mongoTemplate")
        private MongoTemplate mongoTemplate;
        
        // insert
        @Override
        public void insert(Object obj) {
            mongoTemplate.insert(obj);
        }
        
        // find
        public <T> List<T> find(Query query, Class<T> clazz) {
            return mongoDao.find(mongoTemplate, query, clazz);
        }
    
        // findOne
        @Override
        public <T> T findOne(Query query, Class<T> clazz) {
            return mongoDao.findOne(mongoTemplate, query, clazz);
        }
    }

      Facade

    import java.net.InetAddress;
    import java.net.UnknownHostException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import javax.annotation.Resource;
    import org.apache.commons.lang3.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.data.mongodb.core.MongoTemplate;
    import org.springframework.stereotype.Service;
    
    @Service("mongoLoggerFacade")
    public class MongoLoggerFacade {
        private static final Logger LOGGER = LoggerFactory.getLogger(MongoLoggerFacade.class);
    
        @Resource
        MongoService mongoService;
    
        @Resource(name = "mongoTemplate")
        private MongoTemplate mongoTemplate;
    
        // private static final String COLLECTION = "business_log";
    
        /**
         * 本机ip
         */
        private static String LOCAL_IP = "";
    
        /**
         * 客户端ip
         */
        private String clientIp;
    
        /**
         * 请求url
         */
        private String requestUrl;
    
        /**
         * 目标对象
         */
        private String targetClass;
    
        /**
         * 目标方法
         */
        private String targetMethod;
    
        /**
         * 请求参数
         */
        private String requestParam;
    
        /**
         * 捕获异常
         */
        private String exception;
    
        public String getClientIp() {
            return clientIp;
        }
    
        public void setClientIp(String clientIp) {
            this.clientIp = clientIp;
        }
    
        public String getRequestUrl() {
            return requestUrl;
        }
    
        public void setRequestUrl(String requestUrl) {
            this.requestUrl = requestUrl;
        }
    
        public String getTargetClass() {
            return targetClass;
        }
    
        public void setTargetClass(String targetClass) {
            this.targetClass = targetClass;
        }
    
        public String getTargetMethod() {
            return targetMethod;
        }
    
        public void setTargetMethod(String targetMethod) {
            this.targetMethod = targetMethod;
        }
    
        public String getRequestParam() {
            return requestParam;
        }
    
        public void setRequestParam(String requestParam) {
            this.requestParam = requestParam;
        }
    
        public String getException() {
            return exception;
        }
    
        public void setException(String exception) {
            this.exception = exception;
        }
    
        /**
         * 记录INFO级别日志
         * 
         * @param content
         */
        public void INFO(String content) {
            BusinessLogInfo businessLog = getBusinessLog("INFO", content);
            // 插入mongodb
            mongoService.insert(businessLog);
        }
    
        /**
         * 记录INFO级别日志
         * 
         * @param content
         */
        public void INFO(String content, String exception) {
            BusinessLogInfo businessLog = getBusinessLog("INFO", content, exception);
            // 插入mongodb
            mongoService.insert(businessLog);
        }
    
        /**
         * 记录ERROR级别日志
         * 
         * @param content
         */
        public void ERROR(String content) {
            BusinessLogInfo businessLog = getBusinessLog("ERROR", content);
            // 插入mongodb
            mongoService.insert(businessLog);
        }
    
        /**
         * 记录ERROR级别日志
         * 
         * @param content
         */
        public void ERROR(String content, String exception) {
            BusinessLogInfo businessLog = getBusinessLog("ERROR", content, exception);
            // 插入mongodb
            mongoService.insert(businessLog);
        }
    
        /**
         * 记录WARN级别日志
         * 
         * @param content
         */
        public void WARN(String content) {
            BusinessLogInfo businessLog = getBusinessLog("WARN", content);
            // 插入mongodb
            mongoService.insert(businessLog);
        }
    
        /**
         * 记录WARN级别日志
         * 
         * @param content
         */
        public void WARN(String content, String exception) {
            BusinessLogInfo businessLog = getBusinessLog("WARN", content, exception);
            // 插入mongodb
            mongoService.insert(businessLog);
        }
    
        /**
         * 记录DEBUG级别日志
         * 
         * @param content
         */
        public void DEBUG(String content) {
            BusinessLogInfo businessLog = getBusinessLog("DEBUG", content);
            // 插入mongodb
            mongoService.insert(businessLog);
        }
    
        /**
         * 记录DEBUG级别日志
         * 
         * @param content
         */
        public void DEBUG(String content, String exception) {
            BusinessLogInfo businessLog = getBusinessLog("DEBUG", content, exception);
            // 插入mongodb
            mongoService.insert(businessLog);
        }
    
        // 获取封装BusinessLogInfo对象
        private BusinessLogInfo getBusinessLog(String level, String content) {
            BusinessLogInfo businessLog = new BusinessLogInfo();
            setField(businessLog, level, content);
            // 设置异常
            String thisException = getException();
            if(StringUtils.isBlank(thisException)) {
                businessLog.setException("");
            } else {
                businessLog.setException(getException());
            }
            return businessLog;
        }
    
        // 获取封装BusinessLogInfo对象
        private BusinessLogInfo getBusinessLog(String level, String content, String customException) {
            BusinessLogInfo businessLog = new BusinessLogInfo();
            setField(businessLog, level, content);
            // 设置异常
            businessLog.setException(customException);
            return businessLog;
        }
    
        // 设置属性值
        private void setField(BusinessLogInfo businessLog, String level, String content) {
            // 设置日志级别
            businessLog.setLevel(level);
            // 设置内容
            businessLog.setContent(content);
            // 获取客户端ip
            businessLog.setClientIp(getClientIp());
            // 设置本机ip
            businessLog.setServerIp(getLocalIp());
            // 设置请求url
            businessLog.setRequestUrl(getRequestUrl());
            // 设置目标类
            businessLog.setTargetClass(getTargetClass());
            // 设置目标方法
            businessLog.setTargetMethod(getTargetMethod());
            // 获取请求参数
            businessLog.setRequestParam(getRequestParam());
            // 设置记录时间
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
            businessLog.setCreateDate(sdf.format(new Date()));
        }
    
        // 获取服务端ip
        private String getLocalIp() {
            if (StringUtils.isBlank(LOCAL_IP)) {
                InetAddress inetAddress = null;
                try {
                    inetAddress = InetAddress.getLocalHost();
                    LOCAL_IP = inetAddress.getHostAddress();
                } catch (UnknownHostException e) {
                    LOGGER.error("===== get local host error =====");
                }
            }
            return LOCAL_IP;
        }
    
        /**
         * 查询BusinessLogInfo
         * 
         * @param conditions
         * @return
         */
        public BusinessLogInfo findBusinessLog(Map<String, String> conditions) {
            Query query = new Query();
            Set<String> keys = conditions.keySet();
            for (String key : keys) {
                String val = conditions.get(key);
                if (StringUtils.isNotBlank(val)) {
                    query.addCriteria(Criteria.where(key).is(val));
                }
            }
            return mongoService.findOne(query, BusinessLogInfo.class);
        }
    
        /**
         * 查询BusinessLogInfo列表
         * 
         * @param conditions
         * @return
         */
        public List<BusinessLogInfo> findBusinessLogList(Map<String, String> conditions) {
            Query query = new Query();
            Set<String> keys = conditions.keySet();
            for (String key : keys) {
                String val = conditions.get(key);
                if (StringUtils.isNotBlank(val)) {
                    query.addCriteria(Criteria.where(key).is(val));
                }
            }
            return mongoService.find(query, BusinessLogInfo.class);
        }
    }

      Interceptor

    import java.io.PrintWriter;
    import java.io.StringWriter;
    import javax.annotation.Resource;
    import javax.servlet.http.HttpServletRequest;
    import org.apache.commons.lang3.StringUtils;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    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;
    
    @Aspect
    @Component
    public class MongoLoggerInterceptor {
        @Resource
        private MongoLoggerFacade mongoLoggerFacade;
    
        // 连接点是@RequestMapping注解的方法
        @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
        private void webPointcut() {
        }
    
        /**
         * 记录日志前获取目标对象和目标方法
         * 
         * @param joinPoint
         * @throws Throwable
         */
        @Before(value = "execution(* com.kmei.*.*.*.*(..)) and !execution(* com.kmei.mongo.facade.*.*(..))")
        public void befordMedthod(JoinPoint joinPoint) {
            preOperation(joinPoint);
        }
    
        /**
         * 捕获controller类抛出的异常
         * 
         * @param joinPoint
         * @param e
         */
        @AfterThrowing(pointcut = "webPointcut()", throwing = "e")
        public void handleThrowing(JoinPoint joinPoint, Exception e) {
            preOperation(joinPoint);
            mongoLoggerFacade.setException(getExceptionText(e));
            mongoLoggerFacade.ERROR("aop cache exception");
        }
    
        // 预处理操作
        private void preOperation(JoinPoint joinPoint) {
            // 获取目标对象和方法
            String targetClass = joinPoint.getTarget().getClass().getName();
            String targetMethod = joinPoint.getSignature().getName();
            mongoLoggerFacade.setTargetClass(targetClass);
            mongoLoggerFacade.setTargetMethod(targetMethod);
            // 获取请求参数
            Object[] args = joinPoint.getArgs();
            if (args != null && args.length > 0) {
                String requestParam = "requestParam:[{";
                for (int i = 0; i < args.length; i++) {
                    int j = i + 1;
                    if (args[i] != null && StringUtils.isNotBlank(args[i].toString())) {
                        requestParam += "param" + j + ":" + args[i].toString() + ", ";
                    } else {
                        requestParam += "param" + j + ":null, ";
                    }
                }
                requestParam = requestParam.substring(0, requestParam.length() - 2) + "}]";
                mongoLoggerFacade.setRequestParam(requestParam);
                // Map<String, String> paramMap = getFieldsName(targetClass,
                // targetMethod, args);
                // mongoLoggerFacade.setRequestParam(paramMap.toString());
            }
            // 获取客户端真实ip
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            ServletRequestAttributes sra = (ServletRequestAttributes) requestAttributes;
            if (sra != null) {
                HttpServletRequest request = sra.getRequest();
                mongoLoggerFacade.setClientIp(getRealIp(request));
                mongoLoggerFacade.setRequestUrl(request.getRequestURI());
            }
        }
    
        // 下列代码用于获取参数名,存在问题:当参数包含HttpServletRequest和HttpServletResponse时会抛出异常,暂时注释不启用
        // private Map<String, String> getFieldsName(String targetClass, String
        // targetMethod, Object[] args) throws ClassNotFoundException,
        // NoSuchMethodException {
        // // 获取参数值
        // Class<?>[] classes = new Class[args.length];
        // for (int i = 0; i < args.length; i++) {
        // if (!args[i].getClass().isPrimitive()) {
        // // 获取的是封装类型而不是基础类型
        // String result = args[i].getClass().getName();
        // if("javax.servlet.http.HttpServletRequest".equals(result) ||
        // "javax.servlet.http.HttpServletResponse".equals(result)) {
        // continue;
        // }
        // Class<?> s = classMap.get(result);
        // classes[i] = s == null ? args[i].getClass() : s;
        // }
        // }
        // ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer();
        // // 获取指定的方法,第二个参数可以不传,但是为了防止有重载的现象,还是需要传入参数的类型
        // Method method = Class.forName(targetClass).getMethod(targetMethod);
        // // 参数名
        // String[] parameterNames = pnd.getParameterNames(method);
        // if(parameterNames == null) {
        // System.out.println("===== parameterNames is null =====");
        // return null;
        // }
        // System.out.println("===== parameterNames: " + parameterNames.toString());
        // // 通过map封装参数和参数值
        // Map<String, String> paramMap = new HashMap<String, String>();
        // for (int i = 0; i < parameterNames.length; i++) {
        // paramMap.put(parameterNames[i], args[i].toString());
        // }
        // return paramMap;
        // }
    
        // @SuppressWarnings("rawtypes")
        // private static HashMap<String, Class> classMap = new HashMap<String,
        // Class>() {
        // private static final long serialVersionUID = 8205702023950800531L;
        //
        // {
        // put("java.lang.Integer", int.class);
        // put("java.lang.Double", double.class);
        // put("java.lang.Float", float.class);
        // put("java.lang.Long", long.class);
        // put("java.lang.Short", short.class);
        // put("java.lang.Boolean", boolean.class);
        // put("java.lang.Char", char.class);
        // }
        // };
    
        // 打印异常堆栈信息
        private String getExceptionText(Exception e) {
            String text = "";
            if (e == null) {
                return text;
            }
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            text = sw.toString();
            text = e.getMessage() + "
    " + text;
            return text;
        }
    
        // 获取客户端真实ip
        private String getRealIp(HttpServletRequest request) {
            String ip = request.getHeader("X-Forwarded-For");
            if (StringUtils.isNotBlank(ip) && !"unKnown".equalsIgnoreCase(ip)) {
                // 多次反向代理后会有多个ip值,第一个ip才是真实ip
                int index = ip.indexOf(",");
                if (index != -1) {
                    return ip.substring(0, index);
                } else {
                    return ip;
                }
            }
            ip = request.getHeader("X-Real-IP");
            if (StringUtils.isNotBlank(ip) && !"unKnown".equalsIgnoreCase(ip)) {
                return ip;
            }
            return request.getRemoteAddr();
        }
    }

      Controller

    import javax.annotation.Resource;
    import org.springframework.stereotype.Component;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Component
    @Controller
    @RequestMapping("/testmongo")
    public class TestMongoController {
        @Resource
        MongoLoggerFacade mongoLoggerFacade;
        
        @RequestMapping(value = "/testcontent", method = RequestMethod.GET)
        @ResponseBody
        public void testContent(@RequestParam("content") String content, @RequestParam("test") String test, BusinessLogInfo businessLogInfo) throws Exception {
            System.out.println("===== test content =====");
            mongoLoggerFacade.INFO(content);
        }
    
        @RequestMapping(value = "/testinfo", method = RequestMethod.GET)
        @ResponseBody
        public void testInfo() throws Exception {
            System.out.println("===== test info =====");
            mongoLoggerFacade.INFO("test log info");
        }
        
        @RequestMapping(value = "/testerror", method = RequestMethod.GET)
        @ResponseBody
        public void testError() throws Exception {
            System.out.println("===== test error =====");
            mongoLoggerFacade.ERROR("test log error");
        }
        
        @RequestMapping(value = "/testwarn", method = RequestMethod.GET)
        @ResponseBody
        public void testWarn() throws Exception {
            System.out.println("===== test warn =====");
            mongoLoggerFacade.WARN("test log warn");
        }
    
        @RequestMapping(value = "/testfindone", method = RequestMethod.GET)
        @ResponseBody
        public void test2() throws Exception {
            System.out.println("===== test findOne =====");
            Map<String, String> conditions = new HashMap<>();
            conditions.put("level", "INFO");
            BusinessLogInfo result = mongoLoggerFacade.findBusinessLog(conditions);
            System.out.println(result);
        }
        
        @RequestMapping(value = "/testfind", method = RequestMethod.GET)
        @ResponseBody
        public void test3() throws Exception {
            System.out.println("===== test find =====");
            Map<String, String> conditions = new HashMap<>();
            conditions.put("level", "INFO");
            List<BusinessLogInfo> result = mongoLoggerFacade.findBusinessLogList(conditions);
            System.out.println(result);
        }
    }
  • 相关阅读:
    QQ空间爬虫--获取好友信息
    分层最短路-2018南京网赛L
    安装SSH,配置SSH无密码登陆
    树形DP--求树上任意两点间距离和
    JTS基本概念和使用
    odps编写UDF的实现
    oozie安装总结
    同步工具的选择
    转:hive面试题
    转:hive-列转行和行转列
  • 原文地址:https://www.cnblogs.com/tarencez/p/10905863.html
Copyright © 2020-2023  润新知