(注意接口地址改变RequestFilter 中urlPatterns 也要改变 ,否则无法获取前台的request)
package com.unisound.iot.smart.operlog;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Objects;
/**
- request body 作为流式只能被读取一次,如果行多次阅读,必须将其保存下来
*
- 目前暂时不做body的读取,所以暂时去掉次过滤器
*/
//@WebFilter(filterName = "requestFilter", urlPatterns = "/*")
//这个是控制接口的,如果接口有改变urlPatterns 也要改变
@WebFilter(filterName ="requestFilter", urlPatterns ="/saas/*")
public class RequestFilter implements Filter {
@Override public void init(FilterConfig filterConfig) throws ServletException {
}
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest request1 =(HttpServletRequest) request; if (Objects.isNull(request1.getHeader("Content-Type")) ||request1.getHeader("Content-Type").contains("multipart/form-data;")) { chain.doFilter(request, response); } else { chain.doFilter(new InputStreamReadRepeatableRequestWrapper(request1), response); }
}
@Override public void destroy() {
}
}
package com.unisound.iot.smart.operlog;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.unisound.iot.smart.dao.model.operlog.OperationLog;
import com.unisound.iot.smart.dao.model.saas.LoginUserVO;
import com.unisound.iot.smart.entity.ym.MemberVo;
import com.unisound.iot.smart.service.operlog.OperationLogService;
import com.unisound.iot.smart.utils.IPUtil;
import com.unisound.iot.smart.utils.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
- 切面处理类,操作日志异常日志记录处理
*
@author wu
@date 2019/03/21
*/
@Slf4j
@Aspect
@Component
public class OperLogAspect {
@Autowired private OperationLogService operationLogService; /** * 设置操作日志切入点 记录操作日志 在注解的位置切入代码 */ @Pointcut("@annotation(com.unisound.iot.smart.operlog.OperLog)") public void operLogPoinCut() {
}
/** * 正常返回通知,拦截用户操作日志,连接点正常执行完成后执行, 如果连接点抛出异常,则不会执行 * * @param joinPoint 切入点 * @param keys 返回结果 */ @AfterReturning(value ="operLogPoinCut()", returning ="keys") public void saveOperLog(JoinPoint joinPoint, Object keys) { // 获取RequestAttributes RequestAttributes requestAttributes =RequestContextHolder.getRequestAttributes(); // 从获取RequestAttributes中获取HttpServletRequest的信息 HttpServletRequest request =(HttpServletRequest) requestAttributes .resolveReference(RequestAttributes.REFERENCE_REQUEST); OperationLog operlog =new OperationLog(); try { // 从切面织入点处通过反射机制获取织入点处的方法 MethodSignature signature =(MethodSignature) joinPoint.getSignature(); // 获取切入点所在的方法 Method method =signature.getMethod(); // 获取操作 OperLog opLog =method.getAnnotation(OperLog.class); if (opLog !=null) { String operModul =opLog.operModul(); String operType =opLog.operType(); String operDesc =opLog.operDesc(); operlog.setOperModul(operModul); // 操作模块 operlog.setOperType(operType); // 操作类型 operlog.setOperDesc(operDesc); // 操作描述 } LoginUserVO loginUserVO =UserUtils.getCurrentUser(request); Long userId =null; String userName =null; Integer custId=null; if (loginUserVO !=null) { userId =Long.valueOf(loginUserVO.getLoginUserId()); userName =loginUserVO.getLoginName(); //custId = loginUserVO.getCustId(); } // 获取请求的类名 String className =joinPoint.getTarget().getClass().getName(); // 获取请求的方法名 String methodName =method.getName(); methodName =className +"." +methodName; String RequParam =null; // 请求的参数 Map<String, Object> rtnMap = converMap(request.getParameterMap()); // 将参数所在的数组转换成json String params =null; JSONObject jsonObject =new JSONObject(); if (rtnMap !=null &&rtnMap.size() >0) { //params = JSONObject.object(rtnMap);
//RequParam += "params=" + params;
JSONObject jo =new JSONObject(rtnMap); jsonObject.put("params", jo); } //添加body /* 为了避免低效【过滤器过滤每个url,保存body,暂时去掉】 开启方式:1.打开此段注释 2.打开RequestFilter中的@WebFilter 注释即可*/ try { //获取前台传过来的request,如果接口地址有改变 打开RequestFilter中的urlPatterns 也要改变,否则request为空 Map bodyMap =RequestHelper.getBodyString(request); String body =null; if (bodyMap !=null) { //body = JSON.toJSONString(bodyMap);
//RequParam += "body=" + body;
JSONObject jo =new JSONObject(bodyMap); jsonObject.put("body", jo); } } catch (Exception e) { log.error("读取 request body 出错! 请查看RequestFilter拦截地址是否包含!{}", e, e.getMessage()); } operlog.setRequParam(jsonObject.toJSONString()); // 请求参数 operlog.setRespParam(JSON.toJSONString(keys)); // 返回结果 operlog.setUserId(userId); // 请求用户ID operlog.setUserName(userName); // 请求用户名称 operlog.setOperIp(IPUtil.realIP(request)); // 请求IP operlog.setOperUri(request.getRequestURI()); // 请求URI
//operlog.setCustId(custId);
operationLogService.insert(operlog); } catch (Exception e) { e.printStackTrace(); }
}
/** * 转换request 请求参数 * * @param paramMap request获取的参数数组 */ public Map<String, Object> converMap(Map<String, String[]> paramMap) { Map<String, Object> rtnMap =new HashMap<String, Object>(); for (String key :paramMap.keySet()) { rtnMap.put(key, paramMap.get(key)[0]); } return rtnMap; }
}