## 上传说明 + 文件上传通过亚马逊s3协议,对多种文件存储服务(包含:minIO,阿里云oss,腾讯云cos,七牛云kodo)进行统一管理,进行文件上传操作 + 文件上传的流程:后端生成一个带签名并且有时限的url返回给前端,前端通过该签名url进行文件文件上传 --- ## 后台实现代码 我们查看后台`FileController` 这里对文件上传的接口进行了统一的管理: ```java @RestController @RequestMapping("/admin/file") @AllArgsConstructor public class FileController { private final AttachFileService attachFileService; @GetMapping("/getPreSignUrl") @Parameters({ @Parameter(name = "fileName", description = "文件名"), @Parameter(name = "isImFile", description = "是否为客服聊天文件") }) @Operation(summary = "获取预签名url(s3协议)") public ServerResponseEntity getPreSignUrl(String fileName, Boolean isImFile) { Long shopId = Constant.PLATFORM_SHOP_ID; PreSignUrlVO preSingUrlVO = attachFileService.getPreSingUrl(shopId, fileName, isImFile); return ServerResponseEntity.success(preSingUrlVO); } } ``` 同时我们查看`AwsS3Config`类,里面具体展示如何通过s3协议进行生成签名url,上传文件,删除文件 ```java @Configuration @RequiredArgsConstructor public class AwsS3Config { private final ShopConfig shopConfig; private S3Presigner getS3Presigner(UploadFile config) { // aws-s3会自动转成桶域名进行访问(https://bucketName.endpoint),minio不存在桶域名概念,需固定访问路径样式 boolean isForcePathStyle = Objects.equals(StorageTypeEnum.MINIO.getValue(), config.getStorageType()); return S3Presigner.builder() .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(config.getAccessKey(), config.getSecretKey()))) .region(Region.AWS_GLOBAL) .endpointOverride(URI.create(config.getEndPoint())) .serviceConfiguration(S3Configuration.builder() .pathStyleAccessEnabled(isForcePathStyle) .chunkedEncodingEnabled(false) .build()) .build(); } /** * 获取预签名url * @param fileName 文件名(支持路径形式'xx/xx/xxx.png') * @return 预签名url */ public String getPreSignUrl(String fileName) { UploadFile config = shopConfig.getUploadFile(); S3Presigner s3Presigner = this.getS3Presigner(config); PutObjectPresignRequest presignRequest = this.buildPreSignReq(fileName, config.getBucketName()); PresignedPutObjectRequest presignedRequest = s3Presigner.presignPutObject(presignRequest); return presignedRequest.url().toString(); } /** * 构建上传对象预签名请求 * @param fileName 文件名 * @param bucketName 桶名 * @return 上传对象预签名请求 */ private PutObjectPresignRequest buildPreSignReq(String fileName, String bucketName) { return PutObjectPresignRequest.builder() .signatureDuration(Duration.ofSeconds(Constant.S3_URL_DURATION_SECONDS)) .putObjectRequest(PutObjectRequest.builder() .bucket(bucketName) .key(fileName) .build()) .build(); } } ``` ## 配置 当然,上面只是实现的代码而已,所以配置在哪配置呢? 答:需要配置挺多地方的 1. key 和 secret的配置 ![](../img/文件上传配置.png) 2.url的配置 2.1 修改文件资源服务器域名 ![](../img/文件上传url配置.png) 2.2 修改后台vue项目,修改图片域名,也就是管理系统(`mall4vs-bbc`、`mall4vp-bbc`) 开发环境: `.env.development` 生产环境: `.env.production` 如图: ``` # 静态资源文件url VITE_APP_RESOURCES_URL = 'https://img.mall4j.com/' ``` ![](../img/后台vue资源文件url.png) 2.3 修改uniapp图片域名(`mall4uni-bbc`) 开发环境: `.env.development` 生产环境: `.env.production` ``` # 图片域名 VITE_APP_RESOURCES_URL = 'https://img.mall4j.com/' ``` ![](../img/uniapp资源文件url.png) 2.4 用户pc端,无需修改 ## nginx配置 虽然普通的文件上传由前端进行上传,但是excel导入的文件上传还是要经过服务器,而nginx的有限制文件上传大小的配置,这时需要配置nginx文件上传大小 ```config client_max_body_size 20m; ``` ![](../img/nginx文件上传配置.png) ## spring boot使用tomcat容器的时候要注意 spring boot 使用的web容器为tomcat的时候,每次上传会上传到一个临时的文件夹中,而linux系统会在30天后删除该文件夹,导致文件上传异常。此时需要在配置文件配置临时上传的文件夹 我们在`application.yml`指定了这个文件夹为linux系统的默认临时文件夹,解决了这个问题。 ```yaml server: tomcat: basedir: /temp ```