導入的依賴均為 JavaWeb界面線上配置代碼生成器
這篇文章,你隻需将這篇文章的maven依賴導入即可。
SpringAop利用注解的特性進行日志管理,隻需在對應的方法上加上自己編寫的注解,即可完美實作日志管理。
日志管理的目的是,将背景管理人員,安卓人員,第三方人員每天請求的url和是誰操作的,在哪操作,使用什麼系統操作,輸入的那些參數,使用什麼請求等等統統記錄下來。友善異常排查和應對外來的web攻擊。
關于Controller和spring-mvc.xml使用了shiro,關于shiro方面可以參考我的如下文章,進行學習:
MP實戰系列(九)之內建Shiro shiro實戰系列步驟如下:
一、編寫注解類
package com.anotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
String type() default "";//日志類型
String action() default "";//作用
String method() default "";//請求方式
}
二、編寫Aspect
package com.anotation;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.entity.SysCompany;
import com.entity.SysUser;
import com.service.SysCompanyService;
import com.service.SysLogService;
import com.service.SysUserService;
import cn.hutool.core.date.DateUtil;
import cn.hutool.system.HostInfo;
import cn.hutool.system.OsInfo;
import cn.hutool.system.SystemUtil;
public class SysLogAspect {
@Autowired
private SysLogService sysLogService;
@Autowired
private SysUserService userService;
@Autowired
private SysCompanyService companyService;
/**
* 環繞通知
*
* @param joinPoint
* @return
* @throws Throwable
*/
public Object aroud(ProceedingJoinPoint joinPoint) throws Throwable {
// 開始時間
long beginTime = System.currentTimeMillis();
// 執行目标方法
Object result = joinPoint.proceed();
// 執行時長(毫秒)
long time = System.currentTimeMillis() - beginTime;
// 儲存日志
saveSysLog(joinPoint, time);
return result;
}
/**
* 儲存日志
*
* @param joinPoint
* @param time
*/
private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
SysLog sysLog = method.getAnnotation(SysLog.class);
com.entity.SysLog log = new com.entity.SysLog();
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
//擷取session
String userCode = (String) request.getSession().getAttribute("userCode");
//擷取使用者資訊
EntityWrapper<SysUser> wrapper = new EntityWrapper<SysUser>();
wrapper.eq("user_code", userCode);
SysUser user = userService.selectOne(wrapper);
//擷取公司資訊
EntityWrapper<SysCompany> wrapper2 = new EntityWrapper<SysCompany>();
wrapper2.eq("company_code", user.getCorpCode());
SysCompany company = companyService.selectOne(wrapper2);
if (sysLog != null) {
HostInfo hostInfo = SystemUtil.getHostInfo();
OsInfo osInfo = SystemUtil.getOsInfo();
log.setLogType(sysLog.type());
log.setLogTitle(sysLog.action());
log.setRequestMethod(sysLog.method());
log.setRequestUri(request.getRequestURI());
log.setRemoteAddr(request.getRemoteAddr());
log.setDeviceName(osInfo.getName());
log.setBrowserName(request.getHeader("User-Agent"));
log.setRequestParams(request.getQueryString());
log.setCreateBy(user.getUserName());
log.setCreateByName(user.getUserName());
log.setCreateDate(DateUtil.date().toString());
log.setServerAddr(hostInfo.getAddress());
log.setExecuteTime(BigDecimal.valueOf(time));
log.setIsException("否");
log.setCorpCode(company.getCorpCode());
log.setCorpName(company.getCompanyName());
}
// 儲存系統日志
sysLogService.insert(log);
}
}
三、在spring-mvc.xml配置aop
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c" xmlns:util="http://www.springframework.org/schema/util"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xmlns:ehcache="http://www.springmodules.org/schema/ehcache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springmodules.org/schema/ehcache http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd">
<aop:aspectj-autoproxy />
<!-- Controller包(自動注入) -->
<context:component-scan base-package="com.controller"/>
<!-- 将 springSwaggerConfig加載到spring容器 -->
<bean class="com.mangofactory.swagger.configuration.SpringSwaggerConfig" />
<mvc:default-servlet-handler/>
<bean class="com.listener.InitDataListener"/>
<!-- FastJson注入 -->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean id="fastJsonHttpMessageConverter"
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 上傳限制 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上傳檔案大小限制為31M,31*1024*1024 -->
<property name="maxUploadSize" value="32505856"/>
</bean>
<!-- shiro 驗證注解start -->
<!-- 保證實作了Shiro内部lifecycle函數的bean執行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true" />
</bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
<!-- 異常處理 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="org.apache.shiro.authz.UnauthorizedException">/error/unauthorized</prop>
<prop key="org.apache.shiro.authz.UnauthenticatedException">/error/unlogined</prop>
</props>
</property>
</bean>
<!-- 切面 -->
<bean id="sysLogAspect" class="com.anotation.SysLogAspect"></bean>
<aop:config>
<aop:aspect ref="sysLogAspect">
<aop:pointcut expression="@annotation(com.anotation.SysLog)" id="sysLogPointcut"/>
<aop:around method="aroud" pointcut-ref="sysLogPointcut"/>
</aop:aspect>
</aop:config>
</beans>
四、在對應的Controller方法上加上注解即可
/**
* 賬号登入
* @param request
* @return
*/
@PostMapping(value = "/login",produces="application/json;charset=utf-8")
@SysLog(type="背景系統",action="登入功能",method="POST")
@ApiOperation(value="登入",httpMethod="POST",notes="登入")
public JSONObject login(@RequestParam String username, @RequestParam String password, HttpSession session,HttpServletResponse response) {
//接收前台參數
logger.info("使用者名:"+username);
logger.info("密碼:"+password);
//調用查詢邏輯
EntityWrapper<SysUser> wrapper = new EntityWrapper<SysUser>();
wrapper.eq("login_code", username);
SysUser user = userService.selectOne(wrapper);
JSONObject json = new JSONObject();
if(user != null && "0".equals(user.getStatus())) {
//擷取目前使用者
Subject subject = SecurityUtils.getSubject();
//根據前台傳的使用者名和密碼進行認證
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
//認證通過
subject.login(token);
String encode = Base64.encode(user.getUserCode());
//Cookie有效期預設為8小時
int time=28800;
//将Cookie加密為16進制字元串
CookieUtils.setCookie(response, "userCode", encode, time);
user.setLastLoginDate(DateUtil.date());
userService.updateById(user);
//将userCode放入session中儲存
session.setAttribute("userCode", user.getUserCode());
json.put("token", subject.getSession().getId());
json.put(CommonEnum.RETURN_CODE, "000000");
json.put(CommonEnum.RETURN_MSG, "登入成功");
} catch (IncorrectCredentialsException e) {
json.put(CommonEnum.RETURN_CODE, "111111");
json.put(CommonEnum.RETURN_MSG, "使用者名或密碼錯誤");
}catch (Exception e) {
json.put(CommonEnum.RETURN_CODE, "222222");
json.put(CommonEnum.RETURN_MSG, "特殊異常");
}
}else {
json.put(CommonEnum.RETURN_CODE, "500");
json.put(CommonEnum.RETURN_MSG, "使用者不存在");
}
return json;
}