From 87300cf3dd21ca522602d5d446600486615913ea Mon Sep 17 00:00:00 2001 From: waynaqua <1669738430@qq.com> Date: Fri, 4 Aug 2023 00:07:30 +0800 Subject: [PATCH] =?UTF-8?q?feat(mall):=20=E4=BB=A3=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- waynboot-admin-api/pom.xml | 6 +- .../admin/framework/config/MvcConfig.java | 11 ++ .../framework/config/RequestWrapper.java | 65 ++++++++ .../config/RequestWrapperFilter.java | 33 ++++ .../com/wayn/common/aspect/LogAspect.java | 144 ++++++++++++++++++ .../com/wayn/common/config/WaynConfig.java | 1 - .../common/exception/BusinessException.java | 10 +- .../com/wayn/common/util/ServletUtils.java | 6 + .../com/wayn/common/util/http/HttpUtil.java | 4 + 9 files changed, 271 insertions(+), 9 deletions(-) create mode 100644 waynboot-admin-api/src/main/java/com/wayn/admin/framework/config/RequestWrapper.java create mode 100644 waynboot-admin-api/src/main/java/com/wayn/admin/framework/config/RequestWrapperFilter.java create mode 100644 waynboot-common/src/main/java/com/wayn/common/aspect/LogAspect.java diff --git a/waynboot-admin-api/pom.xml b/waynboot-admin-api/pom.xml index 981a625..fff8ef0 100644 --- a/waynboot-admin-api/pom.xml +++ b/waynboot-admin-api/pom.xml @@ -97,7 +97,11 @@ sshj 0.35.0 - + + cn.hutool + hutool-all + ${hutool.version} + de.codecentric spring-boot-admin-starter-client diff --git a/waynboot-admin-api/src/main/java/com/wayn/admin/framework/config/MvcConfig.java b/waynboot-admin-api/src/main/java/com/wayn/admin/framework/config/MvcConfig.java index 141aaa5..bdf4b18 100644 --- a/waynboot-admin-api/src/main/java/com/wayn/admin/framework/config/MvcConfig.java +++ b/waynboot-admin-api/src/main/java/com/wayn/admin/framework/config/MvcConfig.java @@ -1,6 +1,8 @@ package com.wayn.admin.framework.config; import com.wayn.common.config.WaynConfig; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -13,4 +15,13 @@ public class MvcConfig implements WebMvcConfigurer { // 本地文件上传路径 registry.addResourceHandler("/upload/**").addResourceLocations("file:" + WaynConfig.getUploadDir() + "/"); } + + @Bean + public FilterRegistrationBean firstFilter() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(new RequestWrapperFilter()); + registrationBean.addUrlPatterns("/*"); + registrationBean.setOrder(20); + return registrationBean; + } } diff --git a/waynboot-admin-api/src/main/java/com/wayn/admin/framework/config/RequestWrapper.java b/waynboot-admin-api/src/main/java/com/wayn/admin/framework/config/RequestWrapper.java new file mode 100644 index 0000000..4a93675 --- /dev/null +++ b/waynboot-admin-api/src/main/java/com/wayn/admin/framework/config/RequestWrapper.java @@ -0,0 +1,65 @@ +package com.wayn.admin.framework.config; + + +import cn.hutool.extra.servlet.ServletUtil; +import com.wayn.common.util.ServletUtils; +import jakarta.servlet.ReadListener; +import jakarta.servlet.ServletInputStream; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; + +public class RequestWrapper extends HttpServletRequestWrapper { + + + private byte[] body; + + public RequestWrapper(HttpServletRequest request) throws IOException { + super(request); + body = ServletUtils.getBodyBytes(request); + } + + @Override + public BufferedReader getReader() throws IOException { + return new BufferedReader(new InputStreamReader(getInputStream())); + } + + @Override + public ServletInputStream getInputStream() { + + final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body); + + return new ServletInputStream() { + + @Override + public int read() { + return byteArrayInputStream.read(); + } + + @Override + public boolean isFinished() { + return false; + } + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setReadListener(ReadListener readListener) { + + } + + }; + } + + public void setInputStream(byte[] body) { + this.body = body; + } + +} diff --git a/waynboot-admin-api/src/main/java/com/wayn/admin/framework/config/RequestWrapperFilter.java b/waynboot-admin-api/src/main/java/com/wayn/admin/framework/config/RequestWrapperFilter.java new file mode 100644 index 0000000..84826b4 --- /dev/null +++ b/waynboot-admin-api/src/main/java/com/wayn/admin/framework/config/RequestWrapperFilter.java @@ -0,0 +1,33 @@ +package com.wayn.admin.framework.config; + +import com.wayn.common.util.http.HttpUtil; +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletRequest; + +import java.io.IOException; + +public class RequestWrapperFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException + , IOException { + HttpServletRequest req = (HttpServletRequest) request; + if (HttpUtil.isJsonRequest(req)) { + ServletRequest requestWrapper = new RequestWrapper((HttpServletRequest) request); + chain.doFilter(requestWrapper, response); + } else { + chain.doFilter(request, response); + } + } + + @Override + public void destroy() { + + } + +} diff --git a/waynboot-common/src/main/java/com/wayn/common/aspect/LogAspect.java b/waynboot-common/src/main/java/com/wayn/common/aspect/LogAspect.java new file mode 100644 index 0000000..b3cf540 --- /dev/null +++ b/waynboot-common/src/main/java/com/wayn/common/aspect/LogAspect.java @@ -0,0 +1,144 @@ +package com.wayn.common.aspect; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.wayn.common.util.ServletUtils; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.*; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.task.TaskExecutor; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; +import java.util.Date; +import java.util.Map; +import java.util.Objects; + +@Aspect +@Component +@Slf4j +public class OperLogAspect { + + private static final ThreadLocal startTimeLocal = ThreadLocal.withInitial(() -> 0L); + + @Autowired + private OperMgrLogDao operMgrLogDao; + + @Autowired + @Qualifier("operLogTaskExecutor") + private TaskExecutor operLogTaskExecutor; + + @Pointcut("@annotation(com.vc.mgr.modules.vc.model.annotation.Log)") + public void logPointCut() { + } + + /** + * 当方法执行前 + * + * @param joinPoint 切点 + */ + @Before(value = "logPointCut()") + public void doBefore(JoinPoint joinPoint) { + startTimeLocal.set(System.nanoTime()); + } + + /** + * 当方法正常返回时执行 + * + * @param joinPoint 切点 + */ + @AfterReturning(value = "logPointCut()", returning = "response") + public void doAfterReturning(JoinPoint joinPoint, Object response) { + handlerLog(joinPoint, null, response); + } + + /** + * 当方法异常返回时执行 + * + * @param joinPoint 切点 + */ + @AfterThrowing(value = "logPointCut()", throwing = "e") + public void doAfterThrowing(JoinPoint joinPoint, Exception e) { + handlerLog(joinPoint, e, null); + } + + /** + * 日志处理方法 + * + * @param joinPoint 切点 + * @param e 异常 + * @param response 切面方法返回 + */ + private void handlerLog(JoinPoint joinPoint, Exception e, Object response) { + long executeTime; + try { + executeTime = System.nanoTime() - startTimeLocal.get(); + MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); + Method method = methodSignature.getMethod(); + HttpServletRequest request = ServletUtils.getRequest(); + // 获取日志注解 + Log log = method.getAnnotation(Log.class); + LoginUserBean loginUserBean = (LoginUserBean) request.getSession().getAttribute(Constants.CURRENT_ADMIN_KEY); + if (loginUserBean == null) { + return; + } + if (log != null) { + // 创建操作日志对象 + OperMgrLog operLog = new OperMgrLog(); + operLog.setCreateTime(new Date()); + operLog.setModuleName(log.value().getName()); + operLog.setOperation(log.operator().getCode()); + operLog.setUserName(loginUserBean.getAname()); + operLog.setUrl(StringUtils.substring(request.getRequestURI(), 0, 100)); + // 设置方法名称 + String className = joinPoint.getTarget().getClass().getName(); + String methodName = method.getName(); + operLog.setMethod(className + "." + methodName + "()"); + operLog.setOperState(Constants.OPERATOR_SUCCESS); + operLog.setRequestMethod(request.getMethod()); + operLog.setExecuteTime(executeTime / 1000000); + // 保存请求响应 + if (Objects.nonNull(response)) { + operLog.setRequestResponse(StringUtils.substring(JSON.toJSONString(response), 0, 2000)); + } + + if (log.isNeedParam()) { + String reqParmeter = ""; + if (ServletUtil.isJsonRequest(request)) { + reqParmeter = ServletUtil.getBody(request); + } else { + // 保存请求参数 + Map parameterMap = request.getParameterMap(); + JSONObject obj = new JSONObject(true); + for (Map.Entry entry : parameterMap.entrySet()) { + String key = entry.getKey(); + String[] value = entry.getValue(); + if (value.length == 1 && StringUtils.isNotEmpty(value[0])) { + obj.put(key, value[0]); + } else { + obj.put(key, value); + } + } + reqParmeter = obj.toJSONString(); + } + operLog.setRequestParams(StringUtils.substring(reqParmeter, 0, 2000)); + } + if (e != null) { + operLog.setOperState(Constants.OPERATOR_fail); + operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000)); + } + operLogTaskExecutor.execute(() -> operMgrLogDao.insert(operLog)); + } + } catch (Exception exception) { + log.error("handlerLog", exception); + } finally { + startTimeLocal.remove(); + } + + } +} diff --git a/waynboot-common/src/main/java/com/wayn/common/config/WaynConfig.java b/waynboot-common/src/main/java/com/wayn/common/config/WaynConfig.java index bbee277..2efb755 100644 --- a/waynboot-common/src/main/java/com/wayn/common/config/WaynConfig.java +++ b/waynboot-common/src/main/java/com/wayn/common/config/WaynConfig.java @@ -1,6 +1,5 @@ package com.wayn.common.config; -import com.alipay.api.domain.BidDetailVO; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; diff --git a/waynboot-common/src/main/java/com/wayn/common/exception/BusinessException.java b/waynboot-common/src/main/java/com/wayn/common/exception/BusinessException.java index db4b8f6..50eeb67 100644 --- a/waynboot-common/src/main/java/com/wayn/common/exception/BusinessException.java +++ b/waynboot-common/src/main/java/com/wayn/common/exception/BusinessException.java @@ -24,12 +24,8 @@ public class BusinessException extends RuntimeException { this.msg = returnCodeEnum.getMsg(); } - public BusinessException(String message, Throwable cause) { - super(message, cause); + public BusinessException(String msg) { + this.msg = msg; + this.code = ReturnCodeEnum.CUSTOM_ERROR.getCode(); } - - public BusinessException(String message) { - super(message); - } - } diff --git a/waynboot-common/src/main/java/com/wayn/common/util/ServletUtils.java b/waynboot-common/src/main/java/com/wayn/common/util/ServletUtils.java index 1ec8f0d..cc275bc 100644 --- a/waynboot-common/src/main/java/com/wayn/common/util/ServletUtils.java +++ b/waynboot-common/src/main/java/com/wayn/common/util/ServletUtils.java @@ -2,8 +2,10 @@ package com.wayn.common.util; import com.wayn.common.constant.Constants; import com.wayn.common.util.http.HttpUtil; +import jakarta.servlet.ServletRequest; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import org.apache.commons.io.IOUtils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; @@ -112,4 +114,8 @@ public class ServletUtils { response.setHeader("Content-Disposition", HttpUtil.safeHttpHeader("attachment;filename=" + URLEncoder.encode(fileName, Constants.UTF_ENCODING))); response.setContentType("application/octet-stream"); } + + public static byte[] getBodyBytes(ServletRequest request) throws IOException { + return IOUtils.readFully(request.getInputStream(), 1024); + } } diff --git a/waynboot-common/src/main/java/com/wayn/common/util/http/HttpUtil.java b/waynboot-common/src/main/java/com/wayn/common/util/http/HttpUtil.java index d6c28bf..e03c7ce 100644 --- a/waynboot-common/src/main/java/com/wayn/common/util/http/HttpUtil.java +++ b/waynboot-common/src/main/java/com/wayn/common/util/http/HttpUtil.java @@ -322,4 +322,8 @@ public class HttpUtil { return temp; } + public static boolean isJsonRequest(HttpServletRequest request) { + return request.getHeader("Content-Type") != null + && request.getHeader("Content-Type").contains("application/json"); + } }