一、AOP
1、自定义注解
package com.zongtu.aop.annotation;
import java.lang.annotation.*;
/**
* @Description: 定义注解,拦截controller
*/
@Retention(RetentionPolicy.RUNTIME)//元注解,定义注解被保留策略,一般有三种策略
//1、RetentionPolicy.SOURCE 注解只保留在源文件中,在编译成class文件的时候被遗弃
//2、RetentionPolicy.CLASS 注解被保留在class中,但是在jvm加载的时候北欧抛弃,这个是默认的声明周期
//3、RetentionPolicy.RUNTIME 注解在jvm加载的时候仍被保留
@Target({ElementType.METHOD}) //定义了注解声明在哪些元素之前
@Documented
public @interface SystemControllerLog {
//定义成员
String opType() default "";//操作的类型
String descrption() default "";//描述
}
2、日志切面类
package com.zongtu.aop.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.auth0.jwt.JWT;
import com.zongtu.aop.annotation.SystemControllerLog;
import com.zongtu.aop.util.LoggerUtils;
import com.zongtu.dao.UserController.LoginLogDao;
import com.zongtu.dao.UserController.UserControllerMagrDao;
import com.zongtu.domain.UserMagr.Log;
import com.zongtu.domain.UserMagr.User;
import com.zongtu.domain.UserMagr.UserInfo;
import com.zongtu.service.user.LogMagrService;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Description: 定义日志切入类
*/
@Aspect
@Component
@Order(-5)
public class SystemLogAspect {
@Autowired
LogMagrService logMagrService;
@Autowired
LoginLogDao loginLogDao;
@Autowired
UserControllerMagrDao userControllerMagrDao;
/***
* 定义controller切入点拦截规则,拦截SystemControllerLog注解的方法
*/
@Pointcut("@annotation(com.zongtu.aop.annotation.SystemControllerLog)")
public void controllerAspect(){}
/***
* 拦截控制层的操作日志
* @param joinPoint
* @return
* @throws Throwable
*/
@After("controllerAspect()")
public void recordLog(JoinPoint joinPoint) throws Throwable {
String loginId=null;
String name =null;
Log systemLog = new Log();
//获取session中的用户
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//获取连接点签名的方法名
String methodName = joinPoint.getSignature().getName() ;
//获取连接点参数
Object[] args = joinPoint.getArgs() ;
if (methodName.equals("login")) {//登录的情况,请求头没有token
UserInfo userInfo = (UserInfo) args[0];
loginId=userInfo.getLoginId();
User user = userControllerMagrDao.getUserByLoginId(loginId);
name = user.getName();
}
else {//登录过后的情况,请求头有token
String token = request.getHeader("token");// 从 http 请求头中取出 token
// 获取 token 中的loginId和name
if (token!=null) {
loginName = JWT.decode(token).getClaim("loginId").asString();
name = JWT.decode(token).getClaim("name").asString();
}
}
systemLog.setLoginId(loginId);//登录id
systemLog.setName(name);//姓名
//获取请求的ip
LoggerUtils loggerUtils = new LoggerUtils();
String ip = loggerUtils.getCliectIp(request);
systemLog.setLoginIp(ip);
//获取方法执行前时间
Date date=new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
systemLog.setOpTime(sdf.format(date));
//获取执行方法的注解内容
systemLog.setOpDescription(getControllerMethodDescription(joinPoint));
systemLog.setOpType(getControllerMethodOpType(joinPoint));
logMagrService.addLog(systemLog);
}
/***
* 获取controller的操作信息
* @param joinPoint
* @return
*/
public String getControllerMethodDescription(JoinPoint joinPoint) throws Exception{
//获取连接点目标类名
String targetName = joinPoint.getTarget().getClass().getName() ;
//获取连接点签名的方法名
String methodName = joinPoint.getSignature().getName() ;
//获取连接点参数
Object[] args = joinPoint.getArgs() ;
//根据连接点类的名字获取指定类
Class targetClass = Class.forName(targetName);
//获取类里面的方法
Method[] methods = targetClass.getMethods() ;
String description="" ;
for (Method method : methods) {
if (method.getName().equals(methodName)){
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == args.length){
description = method.getAnnotation(SystemControllerLog.class).descrption();
break;
}
}
}
return description ;
}
public String getControllerMethodOpType(JoinPoint joinPoint) throws Exception{
//获取连接点目标类名
String targetName = joinPoint.getTarget().getClass().getName() ;
//获取连接点签名的方法名
String methodName = joinPoint.getSignature().getName() ;
//获取连接点参数
Object[] args = joinPoint.getArgs() ;
//根据连接点类的名字获取指定类
Class targetClass = Class.forName(targetName);
//获取类里面的方法
Method[] methods = targetClass.getMethods() ;
String opType="" ;
for (Method method : methods) {
if (method.getName().equals(methodName)){
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == args.length){
opType = method.getAnnotation(SystemControllerLog.class).opType();
break;
}
}
}
return opType;
}
}
3、获取IP的工具类
package com.zongtu.aop.util;
import javax.servlet.http.HttpServletRequest;
public class LoggerUtils {
public static final String LOGGER_RETURN = "logger_return";
/**
* 获取客户端ip地址
* @param request
* @return
*/
public static String getCliectIp(HttpServletRequest request)
{
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.trim() == "" || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.trim() == "" || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.trim() == "" || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
// 多个路由时,取第一个非unknown的ip
final String[] arr = ip.split(",");
for (final String str : arr) {
if (!"unknown".equalsIgnoreCase(str)) {
ip = str;
break;
}
}
return ip;
}
/**
* 判断是否为ajax请求
* @param request
* @return
*/
public static String getRequestType(HttpServletRequest request) {
return request.getHeader("X-Requested-With");
}
}
4、使用自定义注解记录日志
详情参考博客:https://blog.csdn.net/liuweilong07/article/details/80396055
二、token
添加maven依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
1、tokenService
package com.zongtu.service.user;
import com.zongtu.domain.UserMagr.UserInfo;
public interface TokenService {
public String getToken(UserInfo userInfo,String name);
}
2、tokenServiceImpl
package com.zongtu.service.impl.user;
import java.util.Date;
import org.springframework.stereotype.Service;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.zongtu.domain.UserMagr.UserInfo;
import com.zongtu.service.user.TokenService;
@Service
public class TokenServiceImpl implements TokenService {
@Override
public String getToken(UserInfo userInfo,String name) {
Date start = new Date();
long currentTime = System.currentTimeMillis() + 1000*3600*30;//30小时有效时间
Date end = new Date(currentTime);
String token = "";
token = JWT.create().withClaim("loginId", userInfo.getLoginId()).withClaim("name", name).withIssuedAt(start).withExpiresAt(end)
.sign(Algorithm.HMAC256(userInfo.getPassword()));
return token;
}
}
3、附录:创建与解析token
创建:
String token = JWT.create().withClaim("loginId", userInfo.getLoginId()).withClaim("name", name).withIssuedAt(start).withExpiresAt(end)
.sign(Algorithm.HMAC256(userInfo.getPassword()));
解析:
//登录过后的情况,请求头有token
String token = request.getHeader("token");// 从 http 请求头中取出 token
// 获取 token 中的loginId和name
if (token!=null) {
loginName = JWT.decode(token).getClaim("loginId").asString();
name = JWT.decode(token).getClaim("name").asString();
}