用aspect在springboot中记录操作日志至数据库的详细过程
生活随笔
收集整理的這篇文章主要介紹了
用aspect在springboot中记录操作日志至数据库的详细过程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
代碼來自若依管理系統的后臺,我截取的其中用于記錄操作日志的部分
- 1.切面
- 2.操作日志表
- 3.spring工具類
- 4.客戶端工具類
- 異步工廠(產生任務用)
- 異步任務管理器
- 5.服務層
- 6.控制層
1.切面
/*** 操作日志記錄處理* * @author ruoyi*/ @Aspect @Component public class LogAspect {private static final Logger log = LoggerFactory.getLogger(LogAspect.class);/** 排除敏感屬性字段 */public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };// 配置織入點@Pointcut("@annotation(com.ruoyi.common.annotation.Log)")public void logPointCut(){System.out.println("yes999");}/*** 處理完請求后執行** @param joinPoint 切點*/@AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")public void doAfterReturning(JoinPoint joinPoint, Object jsonResult){handleLog(joinPoint, null, jsonResult);}/*** 攔截異常操作* * @param joinPoint 切點* @param e 異常*/@AfterThrowing(value = "logPointCut()", throwing = "e")public void doAfterThrowing(JoinPoint joinPoint, Exception e){handleLog(joinPoint, e, null);}protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult){try{// 獲得注解Log controllerLog = getAnnotationLog(joinPoint);if (controllerLog == null){return;}// 獲取當前的用戶SysUser currentUser = ShiroUtils.getSysUser();// *========數據庫日志=========*//SysOperLog operLog = new SysOperLog();operLog.setStatus(BusinessStatus.SUCCESS.ordinal());// 請求的地址String ip = ShiroUtils.getIp();operLog.setOperIp(ip);// 返回參數if (StringUtils.isNotNull(jsonResult)){operLog.setJsonResult(StringUtils.substring(JSON.marshal(jsonResult), 0, 2000));}operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());if (currentUser != null){operLog.setOperName(currentUser.getLoginName());if (StringUtils.isNotNull(currentUser.getDept())&& StringUtils.isNotEmpty(currentUser.getDept().getDeptName())){operLog.setDeptName(currentUser.getDept().getDeptName());}}if (e != null){operLog.setStatus(BusinessStatus.FAIL.ordinal());operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));}// 設置方法名稱String className = joinPoint.getTarget().getClass().getName();String methodName = joinPoint.getSignature().getName();operLog.setMethod(className + "." + methodName + "()");// 設置請求方式operLog.setRequestMethod(ServletUtils.getRequest().getMethod());// 處理設置注解上的參數getControllerMethodDescription(joinPoint, controllerLog, operLog);// 保存數據庫AsyncManager.me().execute(AsyncFactory.recordOper(operLog));}catch (Exception exp){// 記錄本地異常日志log.error("==前置通知異常==");log.error("異常信息:{}", exp.getMessage());exp.printStackTrace();}}/*** 獲取注解中對方法的描述信息 用于Controller層注解* * @param log 日志* @param operLog 操作日志* @throws Exception*/public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog) throws Exception{// 設置action動作operLog.setBusinessType(log.businessType().ordinal());// 設置標題operLog.setTitle(log.title());// 設置操作人類別operLog.setOperatorType(log.operatorType().ordinal());// 是否需要保存request,參數和值if (log.isSaveRequestData()){// 獲取參數的信息,傳入到數據庫中。setRequestValue(joinPoint, operLog);}}/*** 獲取請求的參數,放到log中* * @param operLog 操作日志* @throws Exception 異常*/private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception{Map<String, String[]> map = ServletUtils.getRequest().getParameterMap();if (StringUtils.isNotEmpty(map)){String params = JSONObject.toJSONString(map, excludePropertyPreFilter());operLog.setOperParam(StringUtils.substring(params, 0, 2000));}else{Object args = joinPoint.getArgs();if (StringUtils.isNotNull(args)){String params = argsArrayToString(joinPoint.getArgs());operLog.setOperParam(StringUtils.substring(params, 0, 2000));}}}/*** 是否存在注解,如果存在就獲取*/private Log getAnnotationLog(JoinPoint joinPoint) throws Exception{Signature signature = joinPoint.getSignature();MethodSignature methodSignature = (MethodSignature) signature;Method method = methodSignature.getMethod();if (method != null){return method.getAnnotation(Log.class);}return null;}/*** 忽略敏感屬性*/public PropertyPreFilters.MySimplePropertyPreFilter excludePropertyPreFilter(){return new PropertyPreFilters().addFilter().addExcludes(EXCLUDE_PROPERTIES);}/*** 參數拼裝*/private String argsArrayToString(Object[] paramsArray){String params = "";if (paramsArray != null && paramsArray.length > 0){for (int i = 0; i < paramsArray.length; i++){if (StringUtils.isNotNull(paramsArray[i]) && !isFilterObject(paramsArray[i])){Object jsonObj = JSONObject.toJSONString(paramsArray[i], excludePropertyPreFilter());params += jsonObj.toString() + " ";}}}return params.trim();}/*** 判斷是否需要過濾的對象。* * @param o 對象信息。* @return 如果是需要過濾的對象,則返回true;否則返回false。*/@SuppressWarnings("rawtypes")public boolean isFilterObject(final Object o){Class<?> clazz = o.getClass();if (clazz.isArray()){return clazz.getComponentType().isAssignableFrom(MultipartFile.class);}else if (Collection.class.isAssignableFrom(clazz)){Collection collection = (Collection) o;for (Iterator iter = collection.iterator(); iter.hasNext();){return iter.next() instanceof MultipartFile;}}else if (Map.class.isAssignableFrom(clazz)){Map map = (Map) o;for (Iterator iter = map.entrySet().iterator(); iter.hasNext();){Map.Entry entry = (Map.Entry) iter.next();return entry.getValue() instanceof MultipartFile;}}return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse|| o instanceof BindingResult;} }2.操作日志表
/*** 操作日志記錄表 oper_log* * @author ruoyi*/ public class SysOperLog extends BaseEntity {private static final long serialVersionUID = 1L;/** 日志主鍵 */@Excel(name = "操作序號", cellType = ColumnType.NUMERIC)private Long operId;/** 操作模塊 */@Excel(name = "操作模塊")private String title;/** 業務類型(0其它 1新增 2修改 3刪除) */@Excel(name = "業務類型", readConverterExp = "0=其它,1=新增,2=修改,3=刪除,4=授權,5=導出,6=導入,7=強退,8=生成代碼,9=清空數據")private Integer businessType;/** 業務類型數組 */private Integer[] businessTypes;/** 請求方法 */@Excel(name = "請求方法")private String method;/** 請求方式 */@Excel(name = "請求方式")private String requestMethod;/** 操作類別(0其它 1后臺用戶 2手機端用戶) */@Excel(name = "操作類別", readConverterExp = "0=其它,1=后臺用戶,2=手機端用戶")private Integer operatorType;/** 操作人員 */@Excel(name = "操作人員")private String operName;/** 部門名稱 */@Excel(name = "部門名稱")private String deptName;/** 請求url */@Excel(name = "請求地址")private String operUrl;/** 操作地址 */@Excel(name = "操作地址")private String operIp;/** 操作地點 */@Excel(name = "操作地點")private String operLocation;/** 請求參數 */@Excel(name = "請求參數")private String operParam;/** 返回參數 */@Excel(name = "返回參數")private String jsonResult;/** 操作狀態(0正常 1異常) */@Excel(name = "狀態", readConverterExp = "0=正常,1=異常")private Integer status;/** 錯誤消息 */@Excel(name = "錯誤消息")private String errorMsg;/** 操作時間 */@Excel(name = "操作時間", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")private Date operTime;public Long getOperId(){return operId;}public void setOperId(Long operId){this.operId = operId;}public String getTitle(){return title;}public void setTitle(String title){this.title = title;}public Integer getBusinessType(){return businessType;}public void setBusinessType(Integer businessType){this.businessType = businessType;}public Integer[] getBusinessTypes(){return businessTypes;}public void setBusinessTypes(Integer[] businessTypes){this.businessTypes = businessTypes;}public String getMethod(){return method;}public void setMethod(String method){this.method = method;}public String getRequestMethod(){return requestMethod;}public void setRequestMethod(String requestMethod){this.requestMethod = requestMethod;}public Integer getOperatorType(){return operatorType;}public void setOperatorType(Integer operatorType){this.operatorType = operatorType;}public String getOperName(){return operName;}public void setOperName(String operName){this.operName = operName;}public String getDeptName(){return deptName;}public void setDeptName(String deptName){this.deptName = deptName;}public String getOperUrl(){return operUrl;}public void setOperUrl(String operUrl){this.operUrl = operUrl;}public String getOperIp(){return operIp;}public void setOperIp(String operIp){this.operIp = operIp;}public String getOperLocation(){return operLocation;}public void setOperLocation(String operLocation){this.operLocation = operLocation;}public String getOperParam(){return operParam;}public void setOperParam(String operParam){this.operParam = operParam;}public String getJsonResult(){return jsonResult;}public void setJsonResult(String jsonResult){this.jsonResult = jsonResult;}public Integer getStatus(){return status;}public void setStatus(Integer status){this.status = status;}public String getErrorMsg(){return errorMsg;}public void setErrorMsg(String errorMsg){this.errorMsg = errorMsg;}public Date getOperTime(){return operTime;}public void setOperTime(Date operTime){this.operTime = operTime;}@Overridepublic String toString() {return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE).append("operId", getOperId()).append("title", getTitle()).append("businessType", getBusinessType()).append("businessTypes", getBusinessTypes()).append("method", getMethod()).append("requestMethod", getRequestMethod()).append("operatorType", getOperatorType()).append("operName", getOperName()).append("deptName", getDeptName()).append("operUrl", getOperUrl()).append("operIp", getOperIp()).append("operLocation", getOperLocation()).append("operParam", getOperParam()).append("status", getStatus()).append("errorMsg", getErrorMsg()).append("operTime", getOperTime()).toString();} } /*** 異步任務管理器* * @author liuhulu*/ public class AsyncManager {/*** 操作延遲10毫秒*/private final int OPERATE_DELAY_TIME = 10;/*** 異步操作任務調度線程池*/private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");/*** 單例模式*/private AsyncManager(){}private static AsyncManager me = new AsyncManager();public static AsyncManager me(){return me;}/*** 執行任務* * @param task 任務*/public void execute(TimerTask task){executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);}/*** 停止任務線程池*/public void shutdown(){Threads.shutdownAndAwaitTermination(executor);} }3.spring工具類
/*** spring工具類 方便在非spring管理環境中獲取bean* * @author ruoyi*/ @Component public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware {/** Spring應用上下文環境 */private static ConfigurableListableBeanFactory beanFactory;private static ApplicationContext applicationContext;@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException{SpringUtils.beanFactory = beanFactory;}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException{SpringUtils.applicationContext = applicationContext;}/*** 獲取對象** @param name* @return Object 一個以所給名字注冊的bean的實例* @throws org.springframework.beans.BeansException**/@SuppressWarnings("unchecked")public static <T> T getBean(String name) throws BeansException{return (T) beanFactory.getBean(name);}/*** 獲取類型為requiredType的對象** @param clz* @return* @throws org.springframework.beans.BeansException**/public static <T> T getBean(Class<T> clz) throws BeansException{T result = (T) beanFactory.getBean(clz);return result;}/*** 如果BeanFactory包含一個與所給名稱匹配的bean定義,則返回true** @param name* @return boolean*/public static boolean containsBean(String name){return beanFactory.containsBean(name);}/*** 判斷以給定名字注冊的bean定義是一個singleton還是一個prototype。 如果與給定名字相應的bean定義沒有被找到,將會拋出一個異常(NoSuchBeanDefinitionException)** @param name* @return boolean* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException**/public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException{return beanFactory.isSingleton(name);}/*** @param name* @return Class 注冊對象的類型* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException**/public static Class<?> getType(String name) throws NoSuchBeanDefinitionException{return beanFactory.getType(name);}/*** 如果給定的bean名字在bean定義中有別名,則返回這些別名** @param name* @return* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException**/public static String[] getAliases(String name) throws NoSuchBeanDefinitionException{return beanFactory.getAliases(name);}/*** 獲取aop代理對象* * @param invoker* @return*/@SuppressWarnings("unchecked")public static <T> T getAopProxy(T invoker){return (T) AopContext.currentProxy();}/*** 獲取當前的環境配置,無配置返回null** @return 當前的環境配置*/public static String[] getActiveProfiles(){return applicationContext.getEnvironment().getActiveProfiles();}/*** 獲取當前的環境配置,當有多個環境配置時,只獲取第一個** @return 當前的環境配置*/public static String getActiveProfile(){final String[] activeProfiles = getActiveProfiles();return StringUtils.isNotEmpty(activeProfiles) ? activeProfiles[0] : null;} }4.客戶端工具類
/*** 客戶端工具類* * @author ruoyi*/ public class ServletUtils {/*** 定義移動端請求的所有可能類型*/private final static String[] agent = { "Android", "iPhone", "iPod", "iPad", "Windows Phone", "MQQBrowser" };/*** 獲取String參數*/public static String getParameter(String name){return getRequest().getParameter(name);}/*** 獲取String參數*/public static String getParameter(String name, String defaultValue){return Convert.toStr(getRequest().getParameter(name), defaultValue);}/*** 獲取Integer參數*/public static Integer getParameterToInt(String name){return Convert.toInt(getRequest().getParameter(name));}/*** 獲取Integer參數*/public static Integer getParameterToInt(String name, Integer defaultValue){return Convert.toInt(getRequest().getParameter(name), defaultValue);}/*** 獲取request*/public static HttpServletRequest getRequest(){return getRequestAttributes().getRequest();}/*** 獲取response*/public static HttpServletResponse getResponse(){return getRequestAttributes().getResponse();}/*** 獲取session*/public static HttpSession getSession(){return getRequest().getSession();}public static ServletRequestAttributes getRequestAttributes(){RequestAttributes attributes = RequestContextHolder.getRequestAttributes();return (ServletRequestAttributes) attributes;}/*** 將字符串渲染到客戶端* * @param response 渲染對象* @param string 待渲染的字符串* @return null*/public static String renderString(HttpServletResponse response, String string){try{response.setContentType("application/json");response.setCharacterEncoding("utf-8");response.getWriter().print(string);}catch (IOException e){e.printStackTrace();}return null;}/*** 是否是Ajax異步請求* * @param request*/public static boolean isAjaxRequest(HttpServletRequest request){String accept = request.getHeader("accept");if (accept != null && accept.indexOf("application/json") != -1){return true;}String xRequestedWith = request.getHeader("X-Requested-With");if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1){return true;}String uri = request.getRequestURI();if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")){return true;}String ajax = request.getParameter("__ajax");if (StringUtils.inStringIgnoreCase(ajax, "json", "xml")){return true;}return false;}/*** 判斷User-Agent 是不是來自于手機*/public static boolean checkAgentIsMobile(String ua){boolean flag = false;if (!ua.contains("Windows NT") || (ua.contains("Windows NT") && ua.contains("compatible; MSIE 9.0;"))){// 排除 蘋果桌面系統if (!ua.contains("Windows NT") && !ua.contains("Macintosh")){for (String item : agent){if (ua.contains(item)){flag = true;break;}}}}return flag;} }異步工廠(產生任務用)
/*** 異步工廠(產生任務用)* * @author liuhulu**/ public class AsyncFactory {private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");/*** 同步session到數據庫* * @param session 在線用戶會話* @return 任務task*/public static TimerTask syncSessionToDb(final OnlineSession session){return new TimerTask(){@Overridepublic void run(){SysUserOnline online = new SysUserOnline();online.setSessionId(String.valueOf(session.getId()));online.setDeptName(session.getDeptName());online.setLoginName(session.getLoginName());online.setStartTimestamp(session.getStartTimestamp());online.setLastAccessTime(session.getLastAccessTime());online.setExpireTime(session.getTimeout());online.setIpaddr(session.getHost());online.setLoginLocation(AddressUtils.getRealAddressByIP(session.getHost()));online.setBrowser(session.getBrowser());online.setOs(session.getOs());online.setStatus(session.getStatus());SpringUtils.getBean(ISysUserOnlineService.class).saveOnline(online);}};}/*** 操作日志記錄* * @param operLog 操作日志信息* @return 任務task*/public static TimerTask recordOper(final SysOperLog operLog){return new TimerTask(){@Overridepublic void run(){// 遠程查詢操作地點operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));SpringUtils.getBean(ISysOperLogService.class).insertOperlog(operLog);}};}/*** 記錄登錄信息* * @param username 用戶名* @param status 狀態* @param message 消息* @param args 列表* @return 任務task*/public static TimerTask recordLogininfor(final String username, final String status, final String message, final Object... args){final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));final String ip = ShiroUtils.getIp();return new TimerTask(){@Overridepublic void run(){String address = AddressUtils.getRealAddressByIP(ip);StringBuilder s = new StringBuilder();s.append(LogUtils.getBlock(ip));s.append(address);s.append(LogUtils.getBlock(username));s.append(LogUtils.getBlock(status));s.append(LogUtils.getBlock(message));// 打印信息到日志sys_user_logger.info(s.toString(), args);// 獲取客戶端操作系統String os = userAgent.getOperatingSystem().getName();// 獲取客戶端瀏覽器String browser = userAgent.getBrowser().getName();// 封裝對象SysLogininfor logininfor = new SysLogininfor();logininfor.setLoginName(username);logininfor.setIpaddr(ip);logininfor.setLoginLocation(address);logininfor.setBrowser(browser);logininfor.setOs(os);logininfor.setMsg(message);// 日志狀態if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)){logininfor.setStatus(Constants.SUCCESS);}else if (Constants.LOGIN_FAIL.equals(status)){logininfor.setStatus(Constants.FAIL);}// 插入數據SpringUtils.getBean(SysLogininforServiceImpl.class).insertLogininfor(logininfor);}};} }異步任務管理器
/*** 異步任務管理器* * @author liuhulu*/ public class AsyncManager {/*** 操作延遲10毫秒*/private final int OPERATE_DELAY_TIME = 10;/*** 異步操作任務調度線程池*/private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");/*** 單例模式*/private AsyncManager(){}private static AsyncManager me = new AsyncManager();public static AsyncManager me(){return me;}/*** 執行任務* * @param task 任務*/public void execute(TimerTask task){executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);}/*** 停止任務線程池*/public void shutdown(){Threads.shutdownAndAwaitTermination(executor);} }SpringUtils.getBean(ISysOperLogService.class).insertOperlog(operLog);
操作日志服務層
插入日志
@Overridepublic void insertOperlog(SysOperLog operLog){operLogMapper.insertOperlog(operLog);} <insert id="insertOperlog" parameterType="SysOperLog">insert into sys_oper_log(title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, oper_time)values (#{title}, #{businessType}, #{method}, #{requestMethod}, #{operatorType}, #{operName}, #{deptName}, #{operUrl}, #{operIp}, #{operLocation}, #{operParam}, #{jsonResult}, #{status}, #{errorMsg}, sysdate())</insert>3.注解
/*** 自定義操作日志記錄注解* * @author ruoyi*/ @Target({ ElementType.PARAMETER, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Log {/*** 模塊 */public String title() default "";/*** 功能*/public BusinessType businessType() default BusinessType.OTHER;/*** 操作人類別*/public OperatorType operatorType() default OperatorType.MANAGE;/*** 是否保存請求的參數*/public boolean isSaveRequestData() default true; }5.服務層
public interface ISysOperLogService {/*** 新增操作日志* * @param operLog 操作日志對象*/public void insertOperlog(SysOperLog operLog);/*** 查詢系統操作日志集合* * @param operLog 操作日志對象* @return 操作日志集合*/public List<SysOperLog> selectOperLogList(SysOperLog operLog);/*** 批量刪除系統操作日志* * @param ids 需要刪除的數據* @return 結果*/public int deleteOperLogByIds(String ids);/*** 查詢操作日志詳細* * @param operId 操作ID* @return 操作日志對象*/public SysOperLog selectOperLogById(Long operId);/*** 清空操作日志*/public void cleanOperLog(); } /*** 操作日志 服務層處理* * @author ruoyi*/ @Service public class SysOperLogServiceImpl implements ISysOperLogService {@Autowiredprivate SysOperLogMapper operLogMapper;/*** 新增操作日志* * @param operLog 操作日志對象*/@Overridepublic void insertOperlog(SysOperLog operLog){operLogMapper.insertOperlog(operLog);}/*** 查詢系統操作日志集合* * @param operLog 操作日志對象* @return 操作日志集合*/@Overridepublic List<SysOperLog> selectOperLogList(SysOperLog operLog){return operLogMapper.selectOperLogList(operLog);}/*** 批量刪除系統操作日志* * @param ids 需要刪除的數據* @return*/@Overridepublic int deleteOperLogByIds(String ids){return operLogMapper.deleteOperLogByIds(Convert.toStrArray(ids));}/*** 查詢操作日志詳細* * @param operId 操作ID* @return 操作日志對象*/@Overridepublic SysOperLog selectOperLogById(Long operId){return operLogMapper.selectOperLogById(operId);}/*** 清空操作日志*/@Overridepublic void cleanOperLog(){operLogMapper.cleanOperLog();} }6.控制層
/*** 操作日志記錄* * @author ruoyi*/ @Controller @RequestMapping("/monitor/operlog") public class SysOperlogController extends BaseController {private String prefix = "monitor/operlog";@Autowiredprivate ISysOperLogService operLogService;@RequiresPermissions("monitor:operlog:view")@GetMapping()public String operlog(){return prefix + "/operlog";}@RequiresPermissions("monitor:operlog:list")@PostMapping("/list")@ResponseBodypublic TableDataInfo list(SysOperLog operLog){startPage();List<SysOperLog> list = operLogService.selectOperLogList(operLog);return getDataTable(list);}@Log(title = "操作日志", businessType = BusinessType.EXPORT)@RequiresPermissions("monitor:operlog:export")@PostMapping("/export")@ResponseBodypublic AjaxResult export(SysOperLog operLog){List<SysOperLog> list = operLogService.selectOperLogList(operLog);ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class);return util.exportExcel(list, "操作日志");}@Log(title = "操作日志", businessType = BusinessType.DELETE)@RequiresPermissions("monitor:operlog:remove")@PostMapping("/remove")@ResponseBodypublic AjaxResult remove(String ids){return toAjax(operLogService.deleteOperLogByIds(ids));}@RequiresPermissions("monitor:operlog:detail")@GetMapping("/detail/{operId}")public String detail(@PathVariable("operId") Long operId, ModelMap mmap){mmap.put("operLog", operLogService.selectOperLogById(operId));return prefix + "/detail";}@Log(title = "操作日志", businessType = BusinessType.CLEAN)@RequiresPermissions("monitor:operlog:remove")@PostMapping("/clean")@ResponseBodypublic AjaxResult clean(){operLogService.cleanOperLog();return success();} }總結
以上是生活随笔為你收集整理的用aspect在springboot中记录操作日志至数据库的详细过程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: springboot项目修改个人头像
- 下一篇: springboot启动时An atte