Pārlūkot izejas kodu

优化异常日志打印逻辑;优化图片处理工具类;

woody 3 mēneši atpakaļ
vecāks
revīzija
5db9a5a9bf

+ 6 - 0
framework-base/src/main/java/com/chelvc/framework/base/config/ApplicationConfigurer.java

@@ -5,6 +5,7 @@ import javax.servlet.Filter;
 
 import com.chelvc.framework.base.context.DefaultSessionFactory;
 import com.chelvc.framework.base.context.SessionFactory;
+import com.chelvc.framework.base.interceptor.BufferedRequestInterceptor;
 import com.chelvc.framework.base.interceptor.ResponseWrapInterceptor;
 import com.chelvc.framework.common.util.JacksonUtils;
 import com.chelvc.framework.common.util.ObjectUtils;
@@ -59,6 +60,11 @@ public class ApplicationConfigurer {
         return interceptor;
     }
 
+    @Bean
+    public BufferedRequestInterceptor bufferedRequestInterceptor() {
+        return new BufferedRequestInterceptor();
+    }
+
     @Bean
     public FilterRegistrationBean<Filter> crossDomainAccessRegistration() {
         FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();

+ 14 - 10
framework-base/src/main/java/com/chelvc/framework/base/context/LoggingContextHolder.java

@@ -1,8 +1,11 @@
 package com.chelvc.framework.base.context;
 
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import javax.servlet.http.HttpServletRequest;
 
 import ch.qos.logback.classic.Level;
+import com.chelvc.framework.base.util.HttpUtils;
 import com.chelvc.framework.common.model.Platform;
 import com.chelvc.framework.common.model.Terminal;
 import com.chelvc.framework.common.util.ObjectUtils;
@@ -66,18 +69,20 @@ public final class LoggingContextHolder {
     public static String message(HttpServletRequest request, @NonNull Object... messages) {
         String uri = ObjectUtils.ifNull(request, HttpServletRequest::getRequestURI);
         String method = ObjectUtils.ifNull(request, HttpServletRequest::getMethod);
-        return message(uri, method, messages);
+        String parameter = HttpUtils.isMultipart(request) ? null : HttpUtils.serialize(request);
+        return message(uri, method, parameter, messages);
     }
 
     /**
      * 获取日志信息
      *
-     * @param uri      资源地址
-     * @param method   请求方式
-     * @param messages 消息内容数组
+     * @param uri       资源地址
+     * @param method    请求方式
+     * @param parameter 请求参数
+     * @param messages  消息内容数组
      * @return 消息内容
      */
-    public static String message(String uri, String method, @NonNull Object... messages) {
+    public static String message(String uri, String method, String parameter, @NonNull Object... messages) {
         Session session = SessionContextHolder.getSession(false);
         Long id = ObjectUtils.ifNull(session, Session::getId);
         String host = ObjectUtils.ifNull(session, Session::getHost);
@@ -86,6 +91,8 @@ public final class LoggingContextHolder {
         Terminal terminal = ObjectUtils.ifNull(session, Session::getTerminal);
         String version = ObjectUtils.ifNull(session, Session::getVersion);
         Long timestamp = ObjectUtils.ifNull(session, Session::getTimestamp);
+        String request = Stream.of(method, uri, parameter).filter(StringUtils::notEmpty)
+                .collect(Collectors.joining(StringUtils.SPACE));
         StringBuilder buffer = new StringBuilder("[");
         if (timestamp != null) {
             buffer.append(timestamp);
@@ -115,11 +122,8 @@ public final class LoggingContextHolder {
             buffer.append(id);
         }
         buffer.append("] [");
-        if (StringUtils.notEmpty(method)) {
-            buffer.append(method).append(" ");
-        }
-        if (StringUtils.notEmpty(uri)) {
-            buffer.append(uri);
+        if (StringUtils.notEmpty(request)) {
+            buffer.append(request);
         }
         buffer.append("]:");
         for (Object message : messages) {

+ 2 - 3
framework-base/src/main/java/com/chelvc/framework/base/interceptor/BufferedRequestInterceptor.java

@@ -8,7 +8,7 @@ import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 
-import org.apache.http.entity.ContentType;
+import com.chelvc.framework.base.util.HttpUtils;
 
 /**
  * 请求体缓存处理拦截器实现
@@ -20,8 +20,7 @@ public class BufferedRequestInterceptor implements Filter {
     @Override
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
             throws IOException, ServletException {
-        String contentType = request.getContentType();
-        if (contentType != null && contentType.contains(ContentType.MULTIPART_FORM_DATA.getMimeType())) {
+        if (HttpUtils.isMultipart(request)) {
             chain.doFilter(request, response);
         } else {
             chain.doFilter(new BufferedRequestWrapper((HttpServletRequest) request), response);

+ 12 - 41
framework-base/src/main/java/com/chelvc/framework/base/interceptor/BufferedRequestWrapper.java

@@ -10,8 +10,7 @@ import javax.servlet.ServletInputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequestWrapper;
 
-import com.chelvc.framework.common.util.CodecUtils;
-import com.chelvc.framework.common.util.FileUtils;
+import com.chelvc.framework.base.util.HttpUtils;
 import lombok.NonNull;
 
 /**
@@ -24,7 +23,7 @@ public class BufferedRequestWrapper extends HttpServletRequestWrapper {
     private final byte[] body;
 
     public BufferedRequestWrapper(@NonNull HttpServletRequest request) throws IOException {
-        this(request, getBody(request));
+        this(request, HttpUtils.getBody(request));
     }
 
     public BufferedRequestWrapper(@NonNull HttpServletRequest request, @NonNull byte[] body) {
@@ -32,22 +31,6 @@ public class BufferedRequestWrapper extends HttpServletRequestWrapper {
         this.body = body;
     }
 
-    /**
-     * 获取请求体
-     *
-     * @param request Http请求对象
-     * @return 请求体字节数组
-     * @throws IOException I/O异常
-     */
-    private static byte[] getBody(HttpServletRequest request) throws IOException {
-        try (InputStream input = request.getInputStream()) {
-            if (input instanceof BufferedServletInputStream) {
-                return ((BufferedServletInputStream) input).body;
-            }
-            return FileUtils.getBytes(input);
-        }
-    }
-
     @Override
     public BufferedReader getReader() throws IOException {
         return new BufferedReader(new InputStreamReader(this.getInputStream()));
@@ -62,42 +45,30 @@ public class BufferedRequestWrapper extends HttpServletRequestWrapper {
      * 可缓存的Servlet输入流实现
      */
     public static class BufferedServletInputStream extends ServletInputStream {
-        private final byte[] body;
-        private final InputStream delegate;
+        private final byte[] bytes;
+        private final InputStream stream;
 
-        public BufferedServletInputStream(@NonNull byte[] body) {
-            this.body = body;
-            this.delegate = new ByteArrayInputStream(body);
-        }
-
-        /**
-         * 获取请求体
-         *
-         * @return 请求体字节数组
-         */
-        public byte[] body() {
-            byte[] copy = new byte[this.body.length];
-            System.arraycopy(this.body, 0, copy, 0, this.body.length);
-            return copy;
+        public BufferedServletInputStream(@NonNull byte[] bytes) {
+            this.stream = new ByteArrayInputStream(this.bytes = bytes);
         }
 
         /**
-         * 获取请求体base64解码
+         * 获取字节数组
          *
-         * @return 请求体字节数组
+         * @return 字节数组
          */
-        public byte[] decodeBase64() {
-            return CodecUtils.decodeBase64(this.body);
+        public byte[] bytes() {
+            return this.bytes;
         }
 
         @Override
         public int read() throws IOException {
-            return this.delegate.read();
+            return this.stream.read();
         }
 
         @Override
         public int available() throws IOException {
-            return this.delegate.available();
+            return this.stream.available();
         }
 
         @Override

+ 3 - 1
framework-base/src/main/java/com/chelvc/framework/base/interceptor/GlobalExceptionInterceptor.java

@@ -21,6 +21,7 @@ import com.chelvc.framework.base.context.ApplicationContextHolder;
 import com.chelvc.framework.base.context.LoggingContextHolder;
 import com.chelvc.framework.base.context.Result;
 import com.chelvc.framework.base.context.SessionContextHolder;
+import com.chelvc.framework.base.util.HttpUtils;
 import com.chelvc.framework.common.exception.FrameworkException;
 import com.chelvc.framework.common.exception.ParameterInvalidException;
 import com.chelvc.framework.common.util.ErrorUtils;
@@ -241,7 +242,8 @@ public class GlobalExceptionInterceptor extends AbstractErrorController implemen
         String uri = (String) attributes.get("path");
         String method = request.getMethod();
         String message = (String) attributes.get("error");
-        log.warn(LoggingContextHolder.message(uri, method, message));
+        String parameter = HttpUtils.isMultipart(request) ? null : HttpUtils.serialize(request);
+        log.warn(LoggingContextHolder.message(uri, method, parameter, message));
 
         Result<?> result;
         if (status.is5xxServerError()) {

+ 23 - 8
framework-base/src/main/java/com/chelvc/framework/base/util/HttpUtils.java

@@ -20,6 +20,7 @@ import java.util.function.BiFunction;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
+import javax.servlet.ServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
@@ -32,6 +33,7 @@ import com.chelvc.framework.common.util.StringUtils;
 import com.google.common.collect.Maps;
 import lombok.NonNull;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.http.entity.ContentType;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.springframework.http.MediaType;
 import org.springframework.web.multipart.MultipartFile;
@@ -173,6 +175,17 @@ public final class HttpUtils {
         return HostUtils.DEFAULT_LOCAL_ADDRESS_IPV6.equals(ip) ? HostUtils.LOCAL_ADDRESS : ip;
     }
 
+    /**
+     * 判断ContentType是否是multipart/form-data
+     *
+     * @param request 请求对象
+     * @return true/false
+     */
+    public static boolean isMultipart(@NonNull ServletRequest request) {
+        String type = request.getContentType();
+        return type != null && type.contains(ContentType.MULTIPART_FORM_DATA.getMimeType());
+    }
+
     /**
      * 获取Body请求参数
      *
@@ -180,10 +193,10 @@ public final class HttpUtils {
      * @return 请求体字节数组
      * @throws IOException I/O异常
      */
-    public static byte[] getBody(@NonNull HttpServletRequest request) throws IOException {
+    public static byte[] getBody(@NonNull ServletRequest request) throws IOException {
         try (InputStream input = request.getInputStream()) {
             if (input instanceof BufferedRequestWrapper.BufferedServletInputStream) {
-                return ((BufferedRequestWrapper.BufferedServletInputStream) input).body();
+                return ((BufferedRequestWrapper.BufferedServletInputStream) input).bytes();
             }
             return FileUtils.getBytes(input);
         }
@@ -195,7 +208,7 @@ public final class HttpUtils {
      * @param request Http请求对象
      * @return 参数键/值映射表
      */
-    public static Map<String, String[]> getParameters(@NonNull HttpServletRequest request) {
+    public static Map<String, String[]> getParameters(@NonNull ServletRequest request) {
         // 获取表单参数
         Map<String, String[]> parameters = Maps.newHashMap();
         Enumeration<String> enumeration = request.getParameterNames();
@@ -379,9 +392,8 @@ public final class HttpUtils {
      *
      * @param request Http请求对象
      * @return 请求参数
-     * @throws IOException I/O异常
      */
-    public static String serialize(@NonNull HttpServletRequest request) throws IOException {
+    public static String serialize(@NonNull ServletRequest request) {
         return serialize(request, false);
     }
 
@@ -391,13 +403,16 @@ public final class HttpUtils {
      * @param request  Http请求对象
      * @param ordering 参数是否排序
      * @return 请求参数
-     * @throws IOException I/O异常
      */
-    public static String serialize(@NonNull HttpServletRequest request, boolean ordering) throws IOException {
+    public static String serialize(@NonNull ServletRequest request, boolean ordering) {
         String type = request.getContentType();
         if (StringUtils.notEmpty(type) && type.contains(MediaType.APPLICATION_JSON_VALUE)) {
             // Body参数
-            return new String(getBody(request));
+            try {
+                return new String(getBody(request));
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
         }
 
         // 表单参数 + URL参数

+ 40 - 6
framework-common/src/main/java/com/chelvc/framework/common/util/BarcodeUtils.java

@@ -105,17 +105,51 @@ public final class BarcodeUtils {
     }
 
     /**
-     * 将图片对象转换成base64字符串
+     * 将图片对象转换成字节数组
      *
      * @param image 图片对象
-     * @return base64字符串
+     * @return 字节数组
      */
-    public static String image2base64(@NonNull BufferedImage image) {
-        try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
-            ImageIO.write(image, DEFAULT_FORMAT_NAME, stream);
-            return DEFAULT_BASE64_PREFIX + Base64.encodeBase64String(stream.toByteArray());
+    public static byte[] image2bytes(@NonNull BufferedImage image) {
+        return image2bytes(image, DEFAULT_FORMAT_NAME);
+    }
+
+    /**
+     * 将图片对象转换成字节数组
+     *
+     * @param image  图片对象
+     * @param format 图片格式
+     * @return 字节数组
+     */
+    public static byte[] image2bytes(@NonNull BufferedImage image, @NonNull String format) {
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        try {
+            ImageIO.write(image, format, output);
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
+        return output.toByteArray();
+    }
+
+    /**
+     * 将图片对象转换成base64字符串
+     *
+     * @param image 图片对象
+     * @return base64字符串
+     */
+    public static String image2base64(@NonNull BufferedImage image) {
+        return image2base64(image, DEFAULT_FORMAT_NAME);
+    }
+
+    /**
+     * 将图片对象转换成base64字符串
+     *
+     * @param image  图片对象
+     * @param format 图片格式
+     * @return base64字符串
+     */
+    public static String image2base64(@NonNull BufferedImage image, @NonNull String format) {
+        byte[] bytes = image2bytes(image, format);
+        return DEFAULT_BASE64_PREFIX + Base64.encodeBase64String(bytes);
     }
 }

+ 1 - 12
framework-dubbo/src/main/java/com/chelvc/framework/dubbo/interceptor/DubboProviderInterceptor.java

@@ -1,11 +1,9 @@
 package com.chelvc.framework.dubbo.interceptor;
 
-import com.chelvc.framework.base.context.LoggingContextHolder;
 import com.chelvc.framework.base.context.Session;
 import com.chelvc.framework.base.context.SessionContextHolder;
 import com.chelvc.framework.dubbo.adapter.DubboObjectAdapterHolder;
 import com.chelvc.framework.dubbo.adapter.DubboObjectAdapterWrapper;
-import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.common.constants.CommonConstants;
 import org.apache.dubbo.common.extension.Activate;
 import org.apache.dubbo.rpc.AsyncRpcResult;
@@ -22,7 +20,6 @@ import org.apache.dubbo.rpc.RpcException;
  * @author Woody
  * @date 2024/1/30
  */
-@Slf4j
 @Activate(group = CommonConstants.PROVIDER)
 public class DubboProviderInterceptor implements Filter {
     /**
@@ -55,15 +52,7 @@ public class DubboProviderInterceptor implements Filter {
         Session session = (Session) RpcContext.getServerAttachment().getObjectAttachment(Session.NAMING);
         SessionContextHolder.setSession(session);
         try {
-            boolean debug = log.isDebugEnabled();
-            if (debug) {
-                log.debug(LoggingContextHolder.message(invocation.getMethodName(), null, invocation.getArguments()));
-            }
-            Result result = this.processing(invoker, invocation);
-            if (debug) {
-                log.debug(LoggingContextHolder.message(invocation.getMethodName(), null, result.getValue()));
-            }
-            return result;
+            return this.processing(invoker, invocation);
         } finally {
             SessionContextHolder.clearSessionContext();
         }

+ 0 - 7
framework-security/src/main/java/com/chelvc/framework/security/config/SecurityConfigurer.java

@@ -3,7 +3,6 @@ package com.chelvc.framework.security.config;
 import java.time.Duration;
 import java.util.Set;
 
-import com.chelvc.framework.base.interceptor.BufferedRequestInterceptor;
 import com.chelvc.framework.security.annotation.Crypto;
 import com.chelvc.framework.security.crypto.CacheableSecurityCipherHandler;
 import com.chelvc.framework.security.crypto.DefaultSecurityCipherHandler;
@@ -126,10 +125,4 @@ public class SecurityConfigurer extends GlobalMethodSecurityConfiguration implem
         }
         return handler;
     }
-
-    @Bean
-    @ConditionalOnMissingBean(BufferedRequestInterceptor.class)
-    public BufferedRequestInterceptor bufferedRequestInterceptor() {
-        return new BufferedRequestInterceptor();
-    }
 }

+ 4 - 3
framework-security/src/main/java/com/chelvc/framework/security/interceptor/SecurityValidateInterceptor.java

@@ -93,14 +93,15 @@ public class SecurityValidateInterceptor implements HandlerInterceptor, WebMvcCo
      * @throws IOException I/O异常
      */
     private HttpInputMessage decrypt(HttpInputMessage message) throws IOException {
-        byte[] ciphertext;
+        byte[] bytes;
         try (InputStream input = message.getBody()) {
             if (input instanceof BufferedRequestWrapper.BufferedServletInputStream) {
-                ciphertext = ((BufferedRequestWrapper.BufferedServletInputStream) input).decodeBase64();
+                bytes = ((BufferedRequestWrapper.BufferedServletInputStream) input).bytes();
             } else {
-                ciphertext = CodecUtils.decodeBase64(FileUtils.getBytes(input));
+                bytes = FileUtils.getBytes(input);
             }
         }
+        byte[] ciphertext = CodecUtils.decodeBase64(bytes);
         byte[] plaintext = SecurityContextHolder.getSecurityCipherHandler().decrypt(ciphertext);
         return new HttpInputMessage() {
             @Override