SpringMVC 记录用户的操作日志

版权声明:原创文章,转载请标明出处... https://blog.csdn.net/u010670151/article/details/78270592

用spring mvc 做用户的操作日志记录基本有两种方式

1.利用aop做(推荐)

2.利用拦截器做(不推荐)


AOP做操作日志记录基本步骤

 1.数据库创建日志表(定义UserOperateLog实体类)

@Entity
@Table(name = "USER_OPERATE_LOG")
public class UserOperateLog implements java.io.Serializable {
    /** 版本号 */
    private static final long serialVersionUID = 3322584679786620277L;

    /**  */
    private Integer id;

    /** 用户id */
    private String custId;

    /** 用户名 */
    private String custName;

    /** 真实姓名 */
    private String realName;

    /** 操作模块 */
    private String moduleName;

    /** 操作描述 */
    private String operateDesc;

    /** 操作IP */
    private String ipAddress;

    /** 操作时间 */
    private Date createTime;

    /**
     * 获取
     * 
     * @return 
     */
    @Id
    @GeneratedValue(generator = "idGenerator")
    @GenericGenerator(name = "idGenerator", strategy = "native")
    @Column(name = "ID", unique = true, nullable = false, length = 10)
    public Integer getId() {
        return this.id;
    }

    /**
     * 设置
     * 
     * @param id
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * 获取用户id
     * 
     * @return 用户id
     */
    @Column(name = "CUST_ID", nullable = true, length = 255)
    public String getCustId() {
        return this.custId;
    }

    /**
     * 设置用户id
     * 
     * @param custId
     *          用户id
     */
    public void setCustId(String custId) {
        this.custId = custId;
    }

    /**
     * 获取用户名
     * 
     * @return 用户名
     */
    @Column(name = "CUST_NAME", nullable = true, length = 255)
    public String getCustName() {
        return this.custName;
    }

    /**
     * 设置用户名
     * 
     * @param custName
     *          用户名
     */
    public void setCustName(String custName) {
        this.custName = custName;
    }

    /**
     * 获取真实姓名
     * 
     * @return 真实姓名
     */
    @Column(name = "REAL_NAME", nullable = true, length = 255)
    public String getRealName() {
        return this.realName;
    }

    /**
     * 设置真实姓名
     * 
     * @param realName
     *          真实姓名
     */
    public void setRealName(String realName) {
        this.realName = realName;
    }

    /**
     * 获取操作模块
     * 
     * @return 操作模块
     */
    @Column(name = "MODULE_NAME", nullable = true, length = 255)
    public String getModuleName() {
        return this.moduleName;
    }

    /**
     * 设置操作模块
     * 
     * @param moduleName
     *          操作模块
     */
    public void setModuleName(String moduleName) {
        this.moduleName = moduleName;
    }

    /**
     * 获取操作描述
     * 
     * @return 操作描述
     */
    @Column(name = "OPERATE_DESC", nullable = true, length = 255)
    public String getOperateDesc() {
        return this.operateDesc;
    }

    /**
     * 设置操作描述
     * 
     * @param operateDesc
     *          操作描述
     */
    public void setOperateDesc(String operateDesc) {
        this.operateDesc = operateDesc;
    }

    /**
     * 获取操作IP
     * 
     * @return 操作IP
     */
    @Column(name = "IP_ADDRESS", nullable = true, length = 255)
    public String getIpAddress() {
        return this.ipAddress;
    }

    /**
     * 设置操作IP
     * 
     * @param ipAddress
     *          操作IP
     */
    public void setIpAddress(String ipAddress) {
        this.ipAddress = ipAddress;
    }

    /**
     * 获取操作时间
     * 
     * @return 操作时间
     */
    @Column(name = "CREATE_TIME", nullable = true)
    public Date getCreateTime() {
        return this.createTime;
    }

    /**
     * 设置操作时间
     * 
     * @param createTime
     *          操作时间
     */
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
}


 2.自定义用户操作注解 (定义UserOperate注解)

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy; 

@Retention(RetentionPolicy.RUNTIME)  
@Target({ElementType.METHOD})
@Documented
public @interface UserOperate {

	//模块名  
    String moduleName() default "";  
    //操作内容  
    String option() default "";  
}


 3.spring mvc配置文件中配置

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

spring核心控制器配置文件配置

<tx:method name="interceptorApplogicA" propagation="REQUIRES_NEW"/>
当注解打在controller层时,注意事务是否有冲突,导致原先可以对数据库进行写操作的代码现在无法对数据库进行写操作。解决方法建议修改事务的拦截配置如下:

<!-- 事务拦截配置 -->
	<aop:config expose-proxy="true">
		<aop:pointcut id="txPointcut"
			expression=" !execution(* com.yourpackage.controller..*.*(..))" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
	</aop:config>

 4.spring 切片定义(定义LogAspect切片)

/**
 * 处理用户操作日志切面类
 * @author HuYa
 *
 */
@Aspect  
@Component
public class LogAspect {
	
	static UserInfo anonyUser = new UserInfo();
    static {
    	anonyUser.setCustId("-1");
    	anonyUser.setRealName("游客");
    	anonyUser.setCustName("anonymous");
    }
	
	@Autowired
	private UserOperateLogService userOperateLogService;
	    
    @Pointcut("@annotation(com.fhzz.business.annotation.UserOperate)")  
    public void controllerAspecta(){}
    
    @AfterReturning(value = "controllerAspecta() && @annotation(annotation) &&args(object,..) ", argNames = "annotation,object")
    public void interceptorApplogicA(UserOperate annotation, Object object) {
        	HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            UserInfo userInfo = (UserInfo)request.getSession().getAttribute("USERINFO");
            if(userInfo==null){
            	userInfo = anonyUser;
            }
            UserOperateLog uol = new UserOperateLog();
            String custName = userInfo.getCustName();
            String realName = userInfo.getRealName();
            String custId = userInfo.getCustId();
            String ip = this.getIpAddr(request);
            String moduleName = annotation.moduleName();
            String option = annotation.option();
         
            uol.setOperateDesc(option);

            uol.setModuleName(moduleName);
  
            uol.setCustId(custId);
            uol.setCustName(custName);
            uol.setRealName(realName);
            uol.setIpAddress(ip);
            uol.setCreateTime(new Date());
            userOperateLogService.interceptorApplogicA(uol);
    }
    
    /**
	 * 获取IP地址
	 * @param request
	 * @return
	 */
	private  String getIpAddr(HttpServletRequest request) { 
	       String ip = request.getHeader("x-forwarded-for"); 
	       if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	           ip = request.getHeader("Proxy-Client-IP"); 
	       } 
	       if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	           ip = request.getHeader("WL-Proxy-Client-IP"); 
	       } 
	       if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	           ip = request.getRemoteAddr(); 
	       } 
	       return ip; 
	} 
   
}


 5.在相应controller或service层添加注解,当调用相关接口或操作数据库时自动生成记录

@UserOperate(moduleName = "模块名",option = "对模块相关操作")
类似的将该注解加到接口或service层,当调用该接口时数据库则会生成相关记录


以上只是简单的实现用aop生成日志操作的记录


如果需要用拦截器做的话则需要生产接口与相关接口所做功能的映射表,实现起来较aop来说稍微麻烦一点,这里不做描述,读者可以按自己思路去实现




   

展开阅读全文

没有更多推荐了,返回首页