关于SpringBoot中AOP拦截⼊参记录⽇志报错的原因分析
异常:java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
package aspect;
import n.utils.RedisUserUtil;
import security.domain.User;
import security.domain.vo.UserInfoVo;
import security.service.LoginService;
import utils.utils.HttpRequestUtil;
import utils.utils.StringUtils;
import utils.utils.SystemControllerLog;
import utils.utils.SystemServiceLog;
import com.alibaba.fastjson.JSON;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.t.request.RequestContextHolder;
import org.t.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import flect.Method;
@Aspect
@Component
@SuppressWarnings("all")
public class SystemLogAspect {
Logger logger = Class());
@Autowired
private LoginService loginService;
@Autowired
private RedisUserUtil redisUserUtil;
@Pointcut("@annotation(utils.utils.SystemServiceLog)")
public void serviceAspect(){
}
@Pointcut("@annotation(utils.utils.SystemControllerLog)")
public void controllerAspect(){
}
@Before("controllerAspect()")
public  void doBefore(JoinPoint joinPoint) {
HttpServletRequest request = ((ServletRequestAttributes) RequestAttributes()).getRequest();
String token =(Attribute("token");
String userName="";
if(StringUtils.isNotBlank(token)) {
//读取session中的⽤户,注意:proai项⽬中读取redis缓存⽤户数据异常.
//读取session中的⽤户,注意:proai项⽬中读取redis缓存⽤户数据异常.
//            UserInfoVo user = CurrentUser(token);
User userInfoVo = UserInfo(token);
UserName();
}
//请求的IP
String ip = RemoteAddr();
String params = "";
Object[] arguments  = new Args().length];
if (Args() != null && Args().length > 0) {
for (int i = 0; i < Args().length; i++) {
//这⾥出现参数不能转换问题,想了半天最后发现⾥⾯有request对象不能被序列化
//最后把这些对象过滤了。
//                params += Args()[i]) + ";";
if (Args()[i] instanceof ServletRequest || Args()[i] instanceof ServletResponse || Args()[i] instanceof MultipartFile) {                    //HttpServletRequest不能序列化,从⼊参⾥排除,否则报异常:java.lang.IllegalStateException:
// It is illegal to call this method if the current request is not in asynchronous mode
// (i.e. isAsyncStarted() returns false)
continue;
}
arguments[i] = Args()[i];
}
}
if (arguments != null  && arguments.length > 0) {
try {
//这⾥有个很严重的问题,因为JSON序列化有问题,所以这⾥会报错,改为Google 的Gson类来转换即可
params = JSONString(arguments);
} catch (Exception e) {
params = String();
}
}
try {
//*========控制台输出=========*//
logger.info("=====前置通知开始=====");
logger.info("请求⽅法:" + (Target().getClass().getName() + "." + Signature().getName() + "()"));
logger.info("⽅法描述:" + getControllerMethodDescription(joinPoint));
logger.info("请求⼈:" + userName);
logger.info("请求IP:" + ip);
logger.info("请求参数:" + params);
logger.info("=====前置通知结束=====");
}  catch (Exception e) {
//记录本地异常⽇志
<("==前置通知异常==");
<("异常信息:{}", e.getMessage());
}
}
@AfterThrowing(pointcut = "serviceAspect()",throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Throwable e){
HttpServletRequest request = ((ServletRequestAttributes) RequestAttributes()).getRequest();
String token =(Attribute("token");
String userName="";
if(StringUtils.isNotBlank(token)) {
//读取session中的⽤户注意:proai项⽬中读取redis缓存⽤户数据异常.
//            UserInfoVo user = CurrentUser(token);
User userInfoVo = UserInfo(token);
UserName();
}
//获取请求ip
String ip = Host(request);
//获取⽤户请求⽅法的参数并序列化为JSON格式字符串
String params = "";
Object[] arguments  = new Args().length];
if (Args() != null && Args().length > 0) {
for (int i = 0; i < Args().length; i++) {
for (int i = 0; i < Args().length; i++) {
//                params += Args()[i]) + ";";
if (Args()[i] instanceof ServletRequest || Args()[i] instanceof ServletResponse || Args()[i] instanceof MultipartFile) {                    //HttpServletRequest不能序列化,从⼊参⾥排除,否则报异常:java.lang.IllegalStateException:
// It is illegal to call this method if the current request is not in asynchronous mode
// (i.e. isAsyncStarted() returns false)
continue;
}
arguments[i] = Args()[i];
}
}
if (arguments != null  && arguments.length > 0) {
try {
params = JSONString(arguments);
} catch (Exception e1) {
params = String();
}
}
try {
StackTraceElement s= e.getStackTrace()[0];
/*========控制台输出=========*/
logger.info("=====异常通知开始=====");
logger.info("异常代码类/⽅法/⾏数:" +Target().getClass().getName()+"/"+s.getMethodName()+"/"+s.getLineNumber());
/*logger.info("异常⽅法:" + (Target().getClass().getName() + "." + Signature().getName() + "()"));*/
logger.info("⽅法描述:" + getServiceMethodDescription(joinPoint));
logger.info("请求⼈:" + userName);
//            logger.info("请求IP:" + ip);
logger.info("请求参数:" + params);
logger.info("=====异常通知结束=====");
} catch (Exception ex) {
//记录本地异常⽇志
("==异常通知异常==");
<("异常信息:{}", ex.getMessage());
}
}
public static String getServiceMethodDescription(JoinPoint joinPoint)throws Exception{
String targetName = Target().getClass().getName();
String methodName = Signature().getName();
Object[] arguments = Args();
Class targetClass = Class.forName(targetName);
Method[] methods = Methods();
String description = "";
for (Method method:methods) {
if (Name().equals(methodName)){
Class[] clazzs = ParameterTypes();
if (clazzs.length==arguments.length){
description = Annotation(SystemServiceLog.class).description();
break;
}
}
}
return description;
}
public  static String getControllerMethodDescription(JoinPoint joinPoint)  throws Exception {
String targetName = Target().getClass().getName();
String methodName = Signature().getName();
Object[] arguments = Args();
Class targetClass = Class.forName(targetName);
Method[] methods = Methods();
String description = "";
for (Method method : methods) {
if (Name().equals(methodName)) {
Class[] clazzs = ParameterTypes();
if (clazzs.length == arguments.length) {
if (clazzs.length == arguments.length) {
description = Annotation(SystemControllerLog. class).description();
break;
}
}
}
return description;
}
}
最初的观察并没有发现明显的问题,因为paramter本⾝就是String类型; 后进⾏debug后,定位出问题所在位置: paramter = JSONString(args); 在执⾏后报错:java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
上⽹查询资料后发现,是因为使⽤ Object[] args = Args(); 获取⼊参的时候,args还包含了⼀些其他的内容,⽐如ServletRequest等,⽽这些⼊参并不能进⾏序列化,所以JSONString时报错,只能注释这⾏代码了,重新改造⼀下,在上⾯的代码中已经实现了。
if (Args() != null && Args().length > 0) {
for (int i = 0; i < Args().length; i++) {
//这⾥出现参数不能转换问题,想了半天最后发现⾥⾯有request对象不能被序列化
//最后把这些对象过滤了。
//                params += Args()[i]) + ";";
arguments[i] = Args()[i];
}
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。