记录日志的自定义注解
package com.apabi.leopard.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.ElementType;
/**
* @author pengjin
* @version 2.1
* @since 2.1
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogAnnotation {
String operateModelNm();
String operateFuncNm();
String operateDescribe();
}
aop切面处理方法:
package com.apabi.leopard.annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javacommon.base.BaseSpringController;
import javacommon.security.springsecurity.SpringSecurityUtils;
import org.aspectj.lang.JoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import com.apabi.leopard.model.Admin;
import com.apabi.leopard.model.OperateLog;
import com.apabi.leopard.service.OperateLogManager;
import com.apabi.leopard.sso.SsoService;
import com.apabi.leopard.sso.User;
/**
* @author pengjin
* @version 2.1
* @since 2.1
*/
public class WriteOperateLog {
@Autowired
private OperateLogManager operateLogManager;
public void writeLogInfo(JoinPoint joinPoint) throws Exception,
IllegalAccessException {
String temp = joinPoint.getStaticPart().toShortString();
String longTemp = joinPoint.getStaticPart().toLongString();
joinPoint.getStaticPart().toString();
String classType = joinPoint.getTarget().getClass().getName();
String methodName = temp.substring(10, temp.length() - 1);
Class<?> className = Class.forName(classType);
// 日志动作
@SuppressWarnings("rawtypes")
Class[] args = new Class[joinPoint.getArgs().length];
String[] sArgs = (longTemp.substring(longTemp.lastIndexOf("(") + 1,
longTemp.length() - 2)).split(",");
for (int i = 0; i < args.length; i++) {
if (sArgs[i].endsWith("String[]")) {
args[i] = Array.newInstance(Class.forName("java.lang.String"),
1).getClass();
} else if (sArgs[i].endsWith("Long[]")) {
args[i] = Array.newInstance(Class.forName("java.lang.Long"), 1)
.getClass();
} else if (sArgs[i].indexOf(".") == -1) {
if (sArgs[i].equals("int")) {
args[i] = int.class;
} else if (sArgs[i].equals("char")) {
args[i] = char.class;
} else if (sArgs[i].equals("float")) {
args[i] = float.class;
} else if (sArgs[i].equals("long")) {
args[i] = long.class;
}
} else {
args[i] = Class.forName(sArgs[i]);
}
}
Method method = className.getMethod(
methodName.substring(methodName.indexOf(".") + 1,
methodName.indexOf("(")), args);
BaseSpringController thisController = (BaseSpringController) joinPoint
.getTarget();
// 如果该方法写了注解才做操作
if (method.isAnnotationPresent(LogAnnotation.class)) {
LogAnnotation logAnnotation = method
.getAnnotation(LogAnnotation.class);
String operateModelNm = logAnnotation.operateModelNm();
String operateFuncNm = logAnnotation.operateFuncNm();
String operateDescribe = logAnnotation.operateDescribe();
List<String> logArgs = null;
if (operateDescribe.indexOf("#") != -1) {
logArgs = new ArrayList<String>();
int startIndex = operateDescribe.indexOf("#", 0);
int endIndex = operateDescribe.indexOf("#", startIndex + 1);
while (startIndex != -1) {
String tempArg = operateDescribe.substring(startIndex + 1,
endIndex);
startIndex = operateDescribe.indexOf("#", endIndex + 1);
endIndex = operateDescribe.indexOf("#", startIndex + 1);
logArgs.add(tempArg);
}
}
// 获取被注解方法的参数,实现动态注解
String logArg = null;
// 被注解方法只有一个参数的情况可用%替代要传入的参数
if (args.length == 1) {
if (args[0].getName().equals("java.lang.Long")
|| args[0].getName().equals("java.lang.Integer")
|| args[0].getName().equals("java.lang.String")) {
logArg = String.valueOf((joinPoint.getArgs())[0]);
} else if (args[0] == String[].class) {
String[] arrayArg = (String[]) (joinPoint.getArgs())[0];
logArg = Arrays.toString(arrayArg);
} else if (args[0].getName().startsWith(
"com.apabi.leopard.model")) {
Method m = args[0].getMethod("getId");
logArg = String.valueOf(m.invoke(joinPoint.getArgs()[0]));
// 包含了两个操作的日志内容如save方法中包含了增加和修改操作,根据是否存在参数来判断是什么操作
if (operateDescribe.indexOf("|") != -1) {
if (!logArg.equals("null")) {
operateDescribe = operateDescribe
.substring(operateDescribe.indexOf("|") + 1);
} else {
operateDescribe = operateDescribe.substring(0,
operateDescribe.indexOf("|"));
}
}
}
// 将注解中%转换为被拦截方法参数中的id
if (!logArg.equals("null")) {
operateDescribe = operateDescribe.indexOf("%") != -1 ? operateDescribe
.replace("%", logArg) : operateDescribe;
}
} else {
Object obj[] = joinPoint.getArgs();
for (int k = 0; k < logArgs.size(); k++) {
for (int j = k; j < obj.length; j++) {
// 如果是实体
if (logArgs.get(k).startsWith("@")) {
if (args[j].getName().startsWith(
"com.apabi.leopard.model")) {
Method m = args[j].getMethod("getId");
logArg = String.valueOf(m.invoke(joinPoint
.getArgs()[j]));
// 包含了两个操作的日志内容如save方法中包含了增加和修改操作,根据是否存在参数来判断是什么操作
if (!logArg.equals("null")) {
operateDescribe = operateDescribe
.substring(operateDescribe
.indexOf("|") + 1);
} else {
operateDescribe = operateDescribe
.substring(0, operateDescribe
.indexOf("|"));
}
} else {
continue;
}
// 数组
} else if (logArgs.get(k).startsWith("{1}quot;)) {
String[] arrayArg = thisController.request
.getParameterValues(logArgs.get(k)
.substring(1));
logArg = Arrays.toString(arrayArg);
// String
} else {
logArg = thisController.request
.getParameter(logArgs.get(k));
if (logArgs.get(k).equals("bsId") && logArg == null) {
logArg = SpringSecurityUtils.getCurrentAdmin()
.getNwOfficeId().toString();
}
if (operateDescribe.indexOf("|") != -1) {
if (!logArg.equals("null")) {
operateDescribe = operateDescribe
.substring(operateDescribe
.indexOf("|") + 1);
} else {
operateDescribe = operateDescribe
.substring(0, operateDescribe
.indexOf("|"));
}
}
}
if (logArg == null || logArg.equals("null")) {
logArg = "";
}
operateDescribe = operateDescribe.replace(
"#" + logArgs.get(k) + "#", logArg);
break;
}
}
}
OperateLog log = null;
Admin admin = SpringSecurityUtils.getCurrentAdmin();
if (admin != null) {
log = new OperateLog(admin.getNwOfficeId(),
admin.getLoginName(), operateModelNm, operateFuncNm,
operateDescribe, new Date(),
getIpAddr(thisController.request));
} else {
final User user = (User) thisController.request.getSession()
.getAttribute(SsoService.SESSION_USER);
log = new OperateLog(user.getNwOfficeId(), user.getUsername(),
operateModelNm, operateFuncNm, operateDescribe,
new Date(), user.getIpAddress());
}
operateLogManager.saveOrUpdate(log);
}
}
public static 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;
}
}
配置文件springmvc-servlet.xml增加
<aop:config proxy-target-class="true">
<aop:aspect id="goLogAspect" ref="AfterReturningAdvice">
<aop:pointcut id="actionPointcut" expression="execution(* com.*..*.web.*Controller.*(..))" />
<aop:before pointcut-ref="actionPointcut"
method="writeLogInfo" />
</aop:aspect>
</aop:config>
<bean id="AfterReturningAdvice" class="com.xxx.leopard.annotation.AfterReturningAdvice"></bean>
例:
/**
* 保存对象.
**/
@RequestMapping
@LogAnnotation(operateDescribe="公开策略")
public String save(final IssuePolicy issuePolicy, final String limitIpRange) throws Exception {
//
}
/**
* 开放公开策略.
*/
@RequestMapping
@LogAnnotation(operateDescribe="开放了id为%的公开策略")
public void open(final String[] ids) {
}
添加日志的方法:在需要添加日志的controller方法上面添加
传一个参数的情况用%
@LogAnnotation(operateModelNm = "模块名",operateFuncNm = "功能名",operateDescribe = "修好了id=%的套餐")
传多个参数的情况用#参数名#,实体类型前面加@ 数组类型前面加$,其他类型不加 例如#$参数名#
@LogAnnotation(operateModelNm = "模块名",operateFuncNm = "功能名",operateDescribe = "修好了id=#@role#,nwOfficeId=#nwOfficeId#的角色")
由于以上代码不能适应所有的情况,所以实际使用时还需要根据情况进行修改