项目中有个自定义注解,由于之前没有使用过,做个笔记
/**
* 系统日志注解
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AutoLog {
/**
* 日志内容
*
* @return
*/
String value() default "";
/**
* 日志类型
*
* @return 0:操作日志;1:登录日志;2:定时任务;
*/
int logType() default CommonConstant.LOG_TYPE_2;
}
使用@interface表明是注解类
凡是在目标上使用@AutoLog都会触发AOP操作
@Retention(RetentionPolicy.RUNTIME)用来修饰注解
RetentionPolicy枚举类每一项元素的含义:
- SOURCE:编译器处理完Annotation后不存储在class中
- CLASS: 编译器把Annotation存储在class中,这是默认值
- RUNTIME: 编译器把Annotation存储在class中,可以由虚拟机读取,反射需要
@Target(ElementType.METHOD):这个自定义注解作用的目标
ElementType 枚举元素表示的作用目标:
- TYPE:接口、类、枚举、注解
- FIELD:字段、枚举的常
- METHOD:方法
- PARAMETER:方法参数
- CONSTRUCTOR:构造函数
- LOCAL_VARIABLE:局部变量
- ANNOTATION_TYPE:注解
- PACKAGE:包
@Documented注解表明这个注释是由 javadoc记录的
相关代码
获得ip地址
package org.jeecg.common.util;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* IP地址
*
*/
public class IPUtils {
private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
/**
* 获取IP地址
*
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
*/
public static String getIpAddr(HttpServletRequest request) {
String ip = null;
try {
ip = request.getHeader("x-forwarded-for");
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
} catch (Exception e) {
logger.error("IPUtils ERROR ", e);
}
// //使用代理,则获取第一个IP地址
// if(StringUtils.isEmpty(ip) && ip.length() > 15) {
// if(ip.indexOf(",") > 0) {
// ip = ip.substring(0, ip.indexOf(","));
// }
// }
return ip;
}
}
管理上下文实例
package org.jeecg.common.util;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@Component
public class SpringContextUtils implements ApplicationContextAware {
/**
* 上下文对象实例
*/
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/**
* 获取applicationContext
*
* @return
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 获取HttpServletRequest
*/
public static HttpServletRequest getHttpServletRequest() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
}
public static String getDomain(){
HttpServletRequest request = getHttpServletRequest();
StringBuffer url = request.getRequestURL();
return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
}
public static String getOrigin(){
HttpServletRequest request = getHttpServletRequest();
return request.getHeader("Origin");
}
/**
* 通过name获取 Bean.
*
* @param name
* @return
*/
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
/**
* 通过class获取Bean.
*
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
/**
* 通过name,以及Clazz返回指定的Bean
*
* @param name
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
系统日志表
package org.jeecg.modules.model.entity;
import java.util.Date;
import org.jeecg.common.aspect.annotation.Dict;
import org.springframework.format.annotation.DateTimeFormat;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 系统日志表
* </p>
*
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class SysLog implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(type = IdType.ID_WORKER_STR)
private String id;
/**
* 创建人
*/
private String createBy;
/**
* 创建时间
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新人
*/
private String updateBy;
/**
* 更新时间
*/
private Date updateTime;
/**
* 耗时
*/
private Long costTime;
/**
* IP
*/
private String ip;
/**
* 请求参数
*/
private String requestParam;
/**
* 请求类型
*/
private String requestType;
/**
* 请求路径
*/
private String requestUrl;
/**
* 请求方法
*/
private String method;
/**
* 操作人用户名称
*/
private String username;
/**
* 操作人用户账户
*/
private String userid;
/**
* 操作详细日志
*/
private String logContent;
/**
* 日志类型(1登录日志,2操作日志)
*/
@Dict(dicCode = "log_type")
private Integer logType;
/**
* 操作类型()
*/
private Integer operateType;
}
系统日志服务类
package org.jeecg.modules.system.service;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.jeecg.modules.model.entity.SysLog;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 系统日志表 服务类
* </p>
*
*/
public interface ISysLogService extends IService<SysLog> {
/**
* @功能:清空所有日志记录
*/
public void removeAll();
/**
* 获取系统总访问次数
*
* @return Long
*/
Long findTotalVisitCount();
/**
* 获取系统今日访问次数
*
* @return Long
*/
Long findTodayVisitCount(Date dayStart, Date dayEnd);
/**
* 获取系统今日访问 IP数
*
* @return Long
*/
Long findTodayIp(Date dayStart, Date dayEnd);
/**
* 首页:根据时间统计访问数量/ip数量
* @param dayStart
* @param dayEnd
* @return
*/
List<Map<String,Object>> findVisitCount(Date dayStart, Date dayEnd);
}
切面处理类
package org.jeecg.modules.system.aspect;
import java.lang.reflect.Method;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.SecurityUtils;
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.aspectj.lang.reflect.MethodSignature;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.IPUtils;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.modules.model.entity.SysLog;
import org.jeecg.modules.system.service.ISysLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONObject;
/**
* 系统日志,切面处理类
*
*/
@Aspect
@Component
public class AutoLogAspect {
@Autowired
private ISysLogService sysLogService;
@Pointcut("@annotation(org.jeecg.common.aspect.annotation.AutoLog)")
public void logPointCut() {
}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis();
//执行方法
Object result = point.proceed();
//执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
//保存日志
saveSysLog(point, time);
return result;
}
private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
SysLog sysLog = new SysLog();
AutoLog syslog = method.getAnnotation(AutoLog.class);
if(syslog != null){
//注解上的描述,操作日志内容
sysLog.setLogContent(syslog.value());
sysLog.setLogType(syslog.logType());
}
//请求的方法名
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
sysLog.setMethod(className + "." + methodName + "()");
//请求的参数
Object[] args = joinPoint.getArgs();
try{
String params = JSONObject.toJSONString(args);
sysLog.setRequestParam(params);
}catch (Exception e){
}
//获取request
HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
//设置IP地址
sysLog.setIp(IPUtils.getIpAddr(request));
//获取登录用户信息
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
if(sysUser!=null){
sysLog.setUserid(sysUser.getUsername());
sysLog.setUsername(sysUser.getRealname());
}
//耗时
sysLog.setCostTime(time);
sysLog.setCreateTime(new Date());
//保存系统日志
sysLogService.save(sysLog);
}
}