选择使用拦截器实现,在实现中遇到两个个问题:
a. POST请求 @RequestBody 传的参数不知怎么获取?
b. 返回结果如何获取?
c.拦截器中service 无法注入;(已解决)
不知道有没有人遇到这种情况,拦截器没有解决上述问题,后来使用 spring AOP 处理。
《一》拦截器方式
@Configuration
public class OptPermissionHandlerInterceptor extends HandlerInterceptorAdapter {
private Logger logger = LoggerFactory.getLogger(OptPermissionHandlerInterceptor.class);
@Autowired
private OptLogService optLogService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
}
@SuppressWarnings("rawtypes")
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
try {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
String beanName = handlerMethod.getBean().getClass().toString();
String methodName = handlerMethod.getMethod().getName();
String uri = request.getRequestURI();
String remoteAddr = getIpAddr(request);
String sessionId = request.getSession().getId();
String user = (String) request.getSession().getAttribute(Constant.USER);
String method = request.getMethod();
System.out.println("请求方式为="+method);
Map params = null;
if("POST".equals(method)){
//........
}else{
params = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
}
// 取不到值
MethodParameter[] mps = ((HandlerMethod) handler).getMethodParameters();
for(MethodParameter mp : mps){
System.out.println(mp.getParameterName() + " -- "+ mp.getParameterType());
}
// 取不到值
Map params2 = request.getParameterMap();
//拦截器中optLogService 没有注入成功时,重新获取;
if (optLogService == null) {
System.out.println("optLogService is null !!!");
BeanFactory factory =
WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
optLogService = (OptLogService) factory.getBean("optLogService");
}
optLogService.saveOptLog(.....);
}
} catch (Exception e) {
logger.error("用户操作日志记录异常", e);
}
super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
//获取客户端IP
private 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;
}
}
《二》Spring AOP方式(面向切面)
1.在pom.xml 中引入spring aop 依赖
org.springframework.boot
spring-boot-starter-aop
2.在 application.properties 文件中添加:
spring.aop.auto=true
spring.aop.proxy-target-class=false
3.实现切面
@Aspect
@Component
public class WebRequestLogAspect {
private static Logger logger = LoggerFactory.getLogger(WebRequestLogAspect.class);
private ThreadLocal tlocal = new ThreadLocal();
@Autowired
private OptLogService optLogService;
@Pointcut("execution(public * com.whitelover.test..*.create*(..))")
public void webRequestLog() {}
// @Order(5)
@Before("webRequestLog()")
public void doBefore(JoinPoint joinPoint) {
try {
long beginTime = System.currentTimeMillis();
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String beanName = joinPoint.getSignature().getDeclaringTypeName();
String methodName = joinPoint.getSignature().getName();
String uri = request.getRequestURI();
String remoteAddr = getIpAddr(request);
String sessionId = request.getSession().getId();
String user = (String) request.getSession().getAttribute("user");
String method = request.getMethod();
String params = "";
if ("POST".equals(method)) {
Object[] paramsArray = joinPoint.getArgs();
params = argsArrayToString(paramsArray);
} else {
Map, ?> paramsMap = (Map, ?>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
params = paramsMap.toString();
}
logger.debug("uri=" + uri + "; beanName=" + beanName + "; remoteAddr=" + remoteAddr + "; user=" + user
+ "; methodName=" + methodName + "; params=" + params);
OperatorLog optLog = new OperatorLog();
optLog.setBeanName(beanName);
optLog.setCurUser(user);
optLog.setMethodName(methodName);
optLog.setParams(params != null ? params.toString() : "");
optLog.setRemoteAddr(remoteAddr);
optLog.setSessionId(sessionId);
optLog.setUri(uri);
optLog.setRequestTime(beginTime);
tlocal.set(optLog);
} catch (Exception e) {
logger.error("***操作请求日志记录失败doBefore()***", e);
}
}
// @Order(5)
@AfterReturning(returning = "result", pointcut = "webRequestLog()")
public void doAfterReturning(Object result) {
try {
// 处理完请求,返回内容
OperatorLog optLog = tlocal.get();
optLog.setResult(result.toString());
long beginTime = optLog.getRequestTime();
long requestTime = (System.currentTimeMillis() - beginTime) / 1000;
optLog.setRequestTime(requestTime);
System.out.println("请求耗时:" + optLog.getRequestTime() + optLog.getUri() + " ** " + optLog.getParams() + " ** "
+ optLog.getMethodName());
System.out.println("RESPONSE : " + result);
optLogService.saveLog(optLog);
} catch (Exception e) {
logger.error("***操作请求日志记录失败doAfterReturning()***", e);
}
}
/**
* 获取登录用户远程主机ip地址
*
* @param request
* @return
*/
private 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;
}
/**
* 请求参数拼装
*
* @param paramsArray
* @return
*/
private String argsArrayToString(Object[] paramsArray) {
String params = "";
if (paramsArray != null && paramsArray.length > 0) {
for (int i = 0; i < paramsArray.length; i++) {
Object jsonObj = JSON.toJSON(paramsArray[i]);
params += jsonObj.toString() + " ";
}
}
return params.trim();
}
}
spring aop参考网站:
http://blog.didispace.com/springbootaoplog/
@PointCut 表达式参考网站:
http://www.cnblogs.com/lic309/p/4079194.html
转载地址:https://my.oschina.net/gmd/blog/704372