✨ 新增文件上传模块
🐛 修复日志记录开关以及文件上传时由于日志记录导致的文件读取异常
This commit is contained in:
@@ -45,7 +45,11 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-json</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-core</artifactId>
|
||||
<version>3.2.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -59,6 +59,11 @@ public enum ResultStatus {
|
||||
*/
|
||||
MALICIOUS_REQUEST(90002, "Malicious Request"),
|
||||
|
||||
/**
|
||||
* 文件上传异常
|
||||
*/
|
||||
FILE_UPLOAD_ERROR(90003, "File Upload Error"),
|
||||
|
||||
/**
|
||||
* 未知异常
|
||||
*/
|
||||
|
||||
@@ -17,10 +17,6 @@
|
||||
<groupId>com.xuxueli</groupId>
|
||||
<artifactId>xxl-job-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.hccake.ballcat.commom.log.access.filter;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.hccake.ballcat.commom.log.access.service.AccessLogHandlerService;
|
||||
import com.hccake.ballcat.commom.log.util.LogUtils;
|
||||
import com.hccake.ballcat.common.core.filter.RepeatBodyRequestWrapper;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
@@ -36,12 +37,20 @@ public class AccessLogFilter extends OncePerRequestFilter {
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
||||
|
||||
// 排除监控请求 TODO 可配置
|
||||
if (StrUtil.containsAnyIgnoreCase(request.getRequestURI(),"/actuator")){
|
||||
if (StrUtil.containsAnyIgnoreCase(request.getRequestURI(), "/actuator")) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
// 包装request,以保证可以重复读取body
|
||||
RepeatBodyRequestWrapper requestWrapper = new RepeatBodyRequestWrapper(request);
|
||||
|
||||
|
||||
// 包装request,以保证可以重复读取body 但不对文件上传请求body进行处理
|
||||
HttpServletRequest requestWrapper;
|
||||
if (LogUtils.isMultipartContent(request)) {
|
||||
requestWrapper = request;
|
||||
}else {
|
||||
requestWrapper = new RepeatBodyRequestWrapper(request);
|
||||
}
|
||||
|
||||
|
||||
// 开始时间
|
||||
Long startTime = System.currentTimeMillis();
|
||||
@@ -68,4 +77,7 @@ public class AccessLogFilter extends OncePerRequestFilter {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -52,4 +52,20 @@ public class LogUtils {
|
||||
return body;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断是否是multipart/form-data请求
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public static boolean isMultipartContent(HttpServletRequest request) {
|
||||
if (!HttpMethod.POST.name().equals(request.getMethod().toUpperCase())) {
|
||||
return false;
|
||||
}
|
||||
//获取Content-Type
|
||||
String contentType = request.getContentType();
|
||||
return (contentType != null) && (contentType.toLowerCase().startsWith("multipart/"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.hccake.ballcat.commom.log.operation.OperationLogAutoConfiguration,\
|
||||
com.hccake.ballcat.commom.log.access.AccessLogAutoConfiguration,\
|
||||
com.hccake.ballcat.commom.log.error.ErrorLogAutoConfiguration
|
||||
|
||||
25
ballcat-common/ballcat-common-storage/pom.xml
Normal file
25
ballcat-common/ballcat-common-storage/pom.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>ballcat-common</artifactId>
|
||||
<groupId>com.hccake</groupId>
|
||||
<version>0.0.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>ballcat-common-storage</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.hccake.ballcat.commom.storage;
|
||||
|
||||
|
||||
import com.hccake.ballcat.commom.storage.aliyun.AliyunOssClient;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
/**
|
||||
* oss 自动配置类
|
||||
* @author Hccake
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@EnableConfigurationProperties({FileStorageProperties.class})
|
||||
public class FileStorageAutoConfiguration {
|
||||
private final FileStorageProperties properties;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(FileStorageClient.class)
|
||||
@ConditionalOnProperty(name = "file.storage.type", havingValue = "aliyun")
|
||||
FileStorageClient aliyunOssClient() {
|
||||
return new AliyunOssClient(
|
||||
properties.getEndpoint(),
|
||||
properties.getAccessKey(),
|
||||
properties.getAccessSecret(),
|
||||
properties.getBucketName()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.hccake.ballcat.commom.storage;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @author Hccake
|
||||
* @version 1.0
|
||||
* @date 2020/1/7 16:28
|
||||
*/
|
||||
public interface FileStorageClient {
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @param objectName 存储对象名称
|
||||
* @param inputStream 文件输入流
|
||||
* @return 文件相对路径
|
||||
*/
|
||||
String putObject(String objectName, InputStream inputStream);
|
||||
|
||||
|
||||
/**
|
||||
* 文件删除
|
||||
* @param objectName 存储对象名称
|
||||
*/
|
||||
void deleteObject(String objectName);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.hccake.ballcat.commom.storage;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author Hccake
|
||||
* @version 1.0
|
||||
* @date 2019/7/16 15:34
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "file.storage")
|
||||
public class FileStorageProperties {
|
||||
|
||||
/**
|
||||
* endpoint 服务地址 http://oss-cn-qingdao.aliyuncs.com
|
||||
*/
|
||||
private String endpoint;
|
||||
/**
|
||||
* 密钥key
|
||||
*/
|
||||
private String accessKey;
|
||||
/**
|
||||
* 密钥Secret
|
||||
*/
|
||||
private String accessSecret;
|
||||
/**
|
||||
* bucketName
|
||||
*/
|
||||
private String bucketName;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.hccake.ballcat.commom.storage.aliyun;
|
||||
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import com.hccake.ballcat.commom.storage.FileStorageClient;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
|
||||
/**
|
||||
* @author Hccake
|
||||
* @version 1.0
|
||||
* @date 2019/7/16 15:45
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class AliyunOssClient implements FileStorageClient, InitializingBean, DisposableBean {
|
||||
private final String endpoint;
|
||||
private final String accessKey;
|
||||
private final String accessSecret;
|
||||
private final String bucketName;
|
||||
|
||||
private OSS client;
|
||||
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param objectName 存储对象名称
|
||||
* @param inputStream 文件输入流
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String putObject(String objectName, InputStream inputStream) {
|
||||
client.putObject(bucketName, objectName, inputStream);
|
||||
return objectName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件删除
|
||||
* @param objectName 存储对象名称
|
||||
*/
|
||||
@Override
|
||||
public void deleteObject(String objectName){
|
||||
if (client.doesObjectExist(bucketName, objectName)) {
|
||||
client.deleteObject(bucketName, objectName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
Assert.hasText(endpoint, "endpoint 为空");
|
||||
Assert.hasText(accessKey, "Oss accessKey为空");
|
||||
Assert.hasText(accessSecret, "Oss accessSecret为空");
|
||||
client = new OSSClientBuilder().build(endpoint, accessKey, accessSecret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
if (this.client != null) {
|
||||
this.client.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.hccake.ballcat.commom.storage.FileStorageAutoConfiguration
|
||||
@@ -20,6 +20,7 @@
|
||||
<module>ballcat-common-conf</module>
|
||||
<module>ballcat-common-job</module>
|
||||
<module>ballcat-common-swagger</module>
|
||||
<module>ballcat-common-storage</module>
|
||||
</modules>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user