ssm框架操作日志实现步骤

1.创建日志表

CREATE TABLE `log_message`  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '操作日志id',
  `operationUser` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作人',
  `path` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求路径',
  `time` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作时间',
  `parameter` varchar(10000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '参数',
  `title` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求模块',
  `action` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求内容',
  `ip` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作人IP地址',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 38 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

 

 

2.逆向工程生成pojo,mapper接口,mapper.xml

pojo

package com.df.pojo.po;

import java.io.Serializable;

public class LogMessage implements Serializable {
    private Integer id;

    private String operationuser;    //操作人
    
    private String path;    //请求方法

    private String time;    //请求时间

    private String parameter;    //请求参数

    private String title;    //title

    private String action;    //操作内容

    private String ip;    //操作人员ip
    
    private String start_time;    //用于输入框时间查询
    private String end_time;  //用于输入框时间查询
    

    public String getStart_time() {
        return start_time;
    }

    public void setStart_time(String start_time) {
        this.start_time = start_time;
    }

    public String getEnd_time() {
        return end_time;
    }

    public void setEnd_time(String end_time) {
        this.end_time = end_time;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getOperationuser() {
        return operationuser;
    }

    public void setOperationuser(String operationuser) {
        this.operationuser = operationuser == null ? null : operationuser.trim();
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path == null ? null : path.trim();
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time == null ? null : time.trim();
    }

    public String getParameter() {
        return parameter;
    }

    public void setParameter(String parameter) {
        this.parameter = parameter == null ? null : parameter.trim();
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title == null ? null : title.trim();
    }

    public String getAction() {
        return action;
    }

    public void setAction(String action) {
        this.action = action == null ? null : action.trim();
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip == null ? null : ip.trim();
    }

    public LogMessage(String operationuser, String path, String time, String parameter, String title, String action,
            String ip) {
        super();
        this.operationuser = operationuser;
        this.path = path;
        this.time = time;
        this.parameter = parameter;
        this.title = title;
        this.action = action;
        this.ip = ip;
    }

    public LogMessage() {
        super();
    }

    @Override
    public String toString() {
        return "LogMessage [id=" + id + ", operationuser=" + operationuser + ", path=" + path + ", time=" + time
                + ", parameter=" + parameter + ", title=" + title + ", action=" + action + ", ip=" + ip
                + ", start_time=" + start_time + ", end_time=" + end_time + "]";
    }  
    
}

 

mapper.java接口

package com.df.base.dao.mapper;

import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.df.pojo.po.LogMessage;
import com.df.pojo.po.LogMessageExample;
import com.df.pojo.vo.LogMessageQueryVo;

public interface LogMessageMapper {
    int countByExample(LogMessageExample example);

    int deleteByExample(LogMessageExample example);

    int deleteByPrimaryKey(Integer id);

    int insert(LogMessage record);

    int insertSelective(LogMessage record);

    List<LogMessage> selectByExample(LogMessageExample example);

    LogMessage selectByPrimaryKey(Integer id);

    int updateByExampleSelective(@Param("record") LogMessage record, @Param("example") LogMessageExample example);

    int updateByExample(@Param("record") LogMessage record, @Param("example") LogMessageExample example);

    int updateByPrimaryKeySelective(LogMessage record);

    int updateByPrimaryKey(LogMessage record);
    
    List<LogMessage> findLogMessageList(LogMessageQueryVo logMessageQueryVo);
    int findLogMessageListCount(LogMessageQueryVo logMessageQueryVo);
}

 

mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.df.dao.mapper.LogMessageMapper" >
  <resultMap id="BaseResultMap" type="yycg.base.pojo.po.LogMessage" >
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="operationUser" property="operationuser" jdbcType="VARCHAR" />
    <result column="path" property="path" jdbcType="VARCHAR" />
    <result column="time" property="time" jdbcType="VARCHAR" />
    <result column="parameter" property="parameter" jdbcType="VARCHAR" />
    <result column="title" property="title" jdbcType="VARCHAR" />
    <result column="action" property="action" jdbcType="VARCHAR" />
    <result column="ip" property="ip" jdbcType="VARCHAR" />
  </resultMap>
  <sql id="Example_Where_Clause" >
    <where >
      <foreach collection="oredCriteria" item="criteria" separator="or" >
        <if test="criteria.valid" >
          <trim prefix="(" suffix=")" prefixOverrides="and" >
            <foreach collection="criteria.criteria" item="criterion" >
              <choose >
                <when test="criterion.noValue" >
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue" >
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue" >
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue" >
                  and ${criterion.condition}
                  <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
  <sql id="Update_By_Example_Where_Clause" >
    <where >
      <foreach collection="example.oredCriteria" item="criteria" separator="or" >
        <if test="criteria.valid" >
          <trim prefix="(" suffix=")" prefixOverrides="and" >
            <foreach collection="criteria.criteria" item="criterion" >
              <choose >
                <when test="criterion.noValue" >
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue" >
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue" >
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue" >
                  and ${criterion.condition}
                  <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
  <sql id="Base_Column_List" >
    id, operationUser, path, time, parameter, title, action, ip
  </sql>
  <select id="selectByExample" resultMap="BaseResultMap" parameterType="yycg.base.pojo.po.LogMessageExample" >
    select
    <if test="distinct" >
      distinct
    </if>
    <include refid="Base_Column_List" />
    from log_message
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null" >
      order by ${orderByClause}
    </if>
  </select>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    select 
    <include refid="Base_Column_List" />
    from log_message
    where id = #{id,jdbcType=INTEGER}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
    delete from log_message
    where id = #{id,jdbcType=INTEGER}
  </delete>
  <delete id="deleteByExample" parameterType="yycg.base.pojo.po.LogMessageExample" >
    delete from log_message
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
  </delete>
  <insert id="insert" parameterType="yycg.base.pojo.po.LogMessage" >
    insert into log_message (id, operationUser, path, 
      time, parameter, title, 
      action, ip)
    values (#{id,jdbcType=INTEGER}, #{operationuser,jdbcType=VARCHAR}, #{path,jdbcType=VARCHAR}, 
      #{time,jdbcType=VARCHAR}, #{parameter,jdbcType=VARCHAR}, #{title,jdbcType=VARCHAR}, 
      #{action,jdbcType=VARCHAR}, #{ip,jdbcType=VARCHAR})
  </insert>
  <insert id="insertSelective" parameterType="yycg.base.pojo.po.LogMessage" >
    insert into log_message
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        id,
      </if>
      <if test="operationuser != null" >
        operationUser,
      </if>
      <if test="path != null" >
        path,
      </if>
      <if test="time != null" >
        time,
      </if>
      <if test="parameter != null" >
        parameter,
      </if>
      <if test="title != null" >
        title,
      </if>
      <if test="action != null" >
        action,
      </if>
      <if test="ip != null" >
        ip,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        #{id,jdbcType=INTEGER},
      </if>
      <if test="operationuser != null" >
        #{operationuser,jdbcType=VARCHAR},
      </if>
      <if test="path != null" >
        #{path,jdbcType=VARCHAR},
      </if>
      <if test="time != null" >
        #{time,jdbcType=VARCHAR},
      </if>
      <if test="parameter != null" >
        #{parameter,jdbcType=VARCHAR},
      </if>
      <if test="title != null" >
        #{title,jdbcType=VARCHAR},
      </if>
      <if test="action != null" >
        #{action,jdbcType=VARCHAR},
      </if>
      <if test="ip != null" >
        #{ip,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>
  <select id="countByExample" parameterType="yycg.base.pojo.po.LogMessageExample" resultType="java.lang.Integer" >
    select count(*) from log_message
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
  </select>
  <update id="updateByExampleSelective" parameterType="map" >
    update log_message
    <set >
      <if test="record.id != null" >
        id = #{record.id,jdbcType=INTEGER},
      </if>
      <if test="record.operationuser != null" >
        operationUser = #{record.operationuser,jdbcType=VARCHAR},
      </if>
      <if test="record.path != null" >
        path = #{record.path,jdbcType=VARCHAR},
      </if>
      <if test="record.time != null" >
        time = #{record.time,jdbcType=VARCHAR},
      </if>
      <if test="record.parameter != null" >
        parameter = #{record.parameter,jdbcType=VARCHAR},
      </if>
      <if test="record.title != null" >
        title = #{record.title,jdbcType=VARCHAR},
      </if>
      <if test="record.action != null" >
        action = #{record.action,jdbcType=VARCHAR},
      </if>
      <if test="record.ip != null" >
        ip = #{record.ip,jdbcType=VARCHAR},
      </if>
    </set>
    <if test="_parameter != null" >
      <include refid="Update_By_Example_Where_Clause" />
    </if>
  </update>
  <update id="updateByExample" parameterType="map" >
    update log_message
    set id = #{record.id,jdbcType=INTEGER},
      operationUser = #{record.operationuser,jdbcType=VARCHAR},
      path = #{record.path,jdbcType=VARCHAR},
      time = #{record.time,jdbcType=VARCHAR},
      parameter = #{record.parameter,jdbcType=VARCHAR},
      title = #{record.title,jdbcType=VARCHAR},
      action = #{record.action,jdbcType=VARCHAR},
      ip = #{record.ip,jdbcType=VARCHAR}
    <if test="_parameter != null" >
      <include refid="Update_By_Example_Where_Clause" />
    </if>
  </update>
  <update id="updateByPrimaryKeySelective" parameterType="yycg.base.pojo.po.LogMessage" >
    update log_message
    <set >
      <if test="operationuser != null" >
        operationUser = #{operationuser,jdbcType=VARCHAR},
      </if>
      <if test="path != null" >
        path = #{path,jdbcType=VARCHAR},
      </if>
      <if test="time != null" >
        time = #{time,jdbcType=VARCHAR},
      </if>
      <if test="parameter != null" >
        parameter = #{parameter,jdbcType=VARCHAR},
      </if>
      <if test="title != null" >
        title = #{title,jdbcType=VARCHAR},
      </if>
      <if test="action != null" >
        action = #{action,jdbcType=VARCHAR},
      </if>
      <if test="ip != null" >
        ip = #{ip,jdbcType=VARCHAR},
      </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
  </update>
  <update id="updateByPrimaryKey" parameterType="yycg.base.pojo.po.LogMessage" >
    update log_message
    set operationUser = #{operationuser,jdbcType=VARCHAR},
      path = #{path,jdbcType=VARCHAR},
      time = #{time,jdbcType=VARCHAR},
      parameter = #{parameter,jdbcType=VARCHAR},
      title = #{title,jdbcType=VARCHAR},
      action = #{action,jdbcType=VARCHAR},
      ip = #{ip,jdbcType=VARCHAR}
    where id = #{id,jdbcType=INTEGER}
  </update>
  
</mapper>

 

自定义注解,log

package com.df.common.log;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
    /** 方法模块  操作日志类*/
    String title() default "";
    /** 功能 */
    String action() default "";
}

 

定义类用来记录日志,使用aop后置通知原理

package com.df.common.log;


import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
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.reflect.CodeSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import yycg.base.dao.mapper.LogMessageMapper;
import yycg.base.pojo.po.LogMessage;
import yycg.base.pojo.vo.ActiveUser;
import yycg.util.DateUtils;

/**
 * @author Administrator
 * @Description 日志记录
 */
public class LogAspect {
    @Autowired
    private LogMessageMapper logMessageMapper;//日志 mapper
     
    private String requestPath = null ; // 请求地址  
    private long startTimeMillis = 0; // 开始时间  
    private long endTimeMillis = 0; // 结束时间  
    private String user = null; // 操作人
    private HttpServletRequest request = null;//请求
   /**
    * @param joinPoint
    * @Description 气质通知  方法调用前触发   记录开始时间,从session中获取操作人
    */
    public void before(JoinPoint joinPoint){  
        startTimeMillis = System.currentTimeMillis(); 
    } 
    /**
     * @param joinPoint
     * @Description 获取入参方法参数
     * @return
     */
    public Map<String, Object> getNameAndValue(JoinPoint joinPoint) {
        Map<String, Object> param = new HashMap<>();
        Object[] paramValues = joinPoint.getArgs();
        String[] paramNames = ((CodeSignature)joinPoint.getSignature()).getParameterNames();
        for (int i = 0; i < paramNames.length; i++) {
//            if(paramValues[i] instanceof Integer || paramValues[i] instanceof String) {
//                param.put(paramNames[i], paramValues[i]);
//            }
                param.put(paramNames[i], paramValues[i]);

        }
        return param;
    }
    /**
     * @param joinPoint
     * @Description 后置通知    方法调用后触发   记录结束时间 ,操作人 ,入参等
     */
    public void after(JoinPoint joinPoint) {
        request = getHttpServletRequest();
        String targetName = joinPoint.getTarget().getClass().getName();  
        String methodName = joinPoint.getSignature().getName();  
        Object[] arguments = joinPoint.getArgs();  
        Class<?> targetClass = null;
        try {
            targetClass = Class.forName(targetName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Method[] methods = targetClass.getMethods();    //获取该类下所有方法
        String title;
        String action;
        Class<?>[] clazzs;
        for (Method method : methods) {  
            if (method.getName().equals(methodName)) {  
                clazzs = method.getParameterTypes();      //获取改方法的参数
                if (clazzs!=null&&clazzs.length == arguments.length
                &&method.getAnnotation(Log.class)!=null) {  
                    request = getHttpServletRequest();
                    requestPath=request.getServletPath();    //请求路径
                    //user = (String) request.getSession().getAttribute("activeUser");    //用户登录时存session的键
                    ActiveUser activeUser = (ActiveUser)request.getSession().getAttribute("activeUser");
                    user=activeUser.getUsername();
                    title = method.getAnnotation(Log.class).title();
                    action = method.getAnnotation(Log.class).action();
                    String currnetDayParamMill = DateUtils.getCurrnetDayParamMill(new Date());
                    
                    String ipAddress = request.getHeader("x-forwarded-for");  
                    if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {  
                        ipAddress = request.getHeader("Proxy-Client-IP");  
                    }  
                    if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {  
                        ipAddress = request.getHeader("WL-Proxy-Client-IP");  
                    }  
                    if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {  
                        ipAddress = request.getRemoteAddr();  
                        if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")){  
                            //根据网卡取本机配置的IP  
                            InetAddress inet=null;  
                            try {  
                                inet = InetAddress.getLocalHost();  
                            } catch (UnknownHostException e) {  
                                e.printStackTrace();  
                            }  
                            ipAddress= inet.getHostAddress();  
                        }  
                    }  
                    //对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割  
                    if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15  
                        if(ipAddress.indexOf(",")>0){  
                            ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));  
                        }  
                    }  
                                                       
                    LogMessage log=new LogMessage(user, requestPath, currnetDayParamMill, getNameAndValue(joinPoint).toString(), title, action,ipAddress);
                    logMessageMapper.insertSelective(log);
                    break;  
                }  
            }  
        }
    }
    /**
     * @Description: 获取request  
     */
    public HttpServletRequest getHttpServletRequest(){
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();  
        ServletRequestAttributes sra = (ServletRequestAttributes)ra;  
        HttpServletRequest request = null;
        try {
            request = sra.getRequest();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
        }
        return request;
    }
    /**
     * @param joinPoint
     * @return 环绕通知
     * @throws Throwable
     */
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {  
        return null;  
    }  
    /**
     * @param joinPoint
     * @Description 异常通知
     */
    public void throwing(JoinPoint joinPoint) {
        System.out.println("异常通知");
    }
}

 

applicationContext.xml配置文件

<!-- 操作日志配置 指定扫描aop执行操作的类 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
 <!--将日志类注入到bean中。-->
<bean id="logAspect" class="com.df.common.log.LogAspect"></bean>

 <aop:config>
       <aop:aspect  ref="logAspect">
           <aop:pointcut id="log" expression="execution(* com.*.service.impl.*.*(..))"/>  
           <aop:after pointcut-ref="log" method="after"/> 
       </aop:aspect>
 </aop:config>

 

在实现类需要加日志业务加上注解即可

@Log(title="增加日志",action="增加用户信息")
@Override
public void insertSysuser(SysuserCustom sysuserCustom) throws Exception {

}

 

posted @ 2021-08-19 09:24  登风360  阅读(415)  评论(0编辑  收藏  举报