From 27f7bef621de44c31a9736b7ca4cc35810bc0795 Mon Sep 17 00:00:00 2001 From: "Yangkai.Shen" <237497819@qq.com> Date: Wed, 21 Sep 2022 16:49:49 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E5=9F=BA=E7=A1=80=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E4=B9=8B=20=E6=96=87=E4=BB=B6=E4=B8=8A=E4=BC=A0=20?= =?UTF-8?q?=E6=A1=88=E4=BE=8B=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + demo-base/demo-base-upload/.gitignore | 25 - demo-base/demo-base-upload/README.md | 653 ++++++--------------- demo-base/demo-base-upload/pom.xml | 115 ++-- ...loadApplication.java => UploadApplication.java} | 4 +- .../upload/autoconfigure/QiniuProperties.java | 22 + .../UploadAutoConfiguration.java} | 32 +- .../upload/controller/UploadController.java | 48 +- .../com/xkcoding/upload/service/IQiNiuService.java | 25 - .../QiNiuServiceImpl.java => QiNiuService.java} | 29 +- .../src/main/resources/application.yml | 12 +- .../SpringBootDemoUploadApplicationTests.java | 16 - .../xkcoding/upload/UploadApplicationTests.java | 13 + demo-base/pom.xml | 1 + 14 files changed, 329 insertions(+), 668 deletions(-) delete mode 100644 demo-base/demo-base-upload/.gitignore rename demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/{SpringBootDemoUploadApplication.java => UploadApplication.java} (72%) create mode 100644 demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/autoconfigure/QiniuProperties.java rename demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/{config/UploadConfig.java => autoconfigure/UploadAutoConfiguration.java} (78%) delete mode 100644 demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/service/IQiNiuService.java rename demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/service/{impl/QiNiuServiceImpl.java => QiNiuService.java} (66%) delete mode 100644 demo-base/demo-base-upload/src/test/java/com/xkcoding/upload/SpringBootDemoUploadApplicationTests.java create mode 100644 demo-base/demo-base-upload/src/test/java/com/xkcoding/upload/UploadApplicationTests.java diff --git a/.gitignore b/.gitignore index 75ba006..26d05fe 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ logs/ ### VS CODE ### .vscode/ + +tmp/ diff --git a/demo-base/demo-base-upload/.gitignore b/demo-base/demo-base-upload/.gitignore deleted file mode 100644 index 82eca33..0000000 --- a/demo-base/demo-base-upload/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -/target/ -!.mvn/wrapper/maven-wrapper.jar - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr - -### NetBeans ### -/nbproject/private/ -/build/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ \ No newline at end of file diff --git a/demo-base/demo-base-upload/README.md b/demo-base/demo-base-upload/README.md index 22d01df..d96f630 100644 --- a/demo-base/demo-base-upload/README.md +++ b/demo-base/demo-base-upload/README.md @@ -2,503 +2,202 @@ > 本 demo 演示了 Spring Boot 如何实现本地文件上传以及如何上传文件至七牛云平台。前端使用 vue 和 iview 实现上传页面。 -## pom.xml +## 1.开发步骤 + +### 1.1.添加依赖 ```xml - - - 4.0.0 - - spring-boot-demo-upload - 1.0.0-SNAPSHOT - jar - - spring-boot-demo-upload - Demo project for Spring Boot - - - com.xkcoding - spring-boot-demo - 1.0.0-SNAPSHOT - - - - UTF-8 - UTF-8 - 1.8 - - - - - org.projectlombok - lombok - true - - - - org.springframework.boot - spring-boot-starter-web - - - - org.springframework.boot - spring-boot-starter-thymeleaf - - - - org.springframework.boot - spring-boot-starter-test - test - - - - cn.hutool - hutool-all - - - - com.qiniu - qiniu-java-sdk - [7.2.0, 7.2.99] - - - - - spring-boot-demo-upload - - - org.springframework.boot - spring-boot-maven-plugin - - - - - + + + com.xkcoding + common-tools + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + org.springframework.boot + spring-boot-starter-test + test + + + + com.qiniu + qiniu-java-sdk + ${qiniu.version} + + + + + com.squareup.okhttp3 + okhttp + 3.14.4 + + + + org.projectlombok + lombok + true + + ``` -## UploadConfig.java +### 1.2.七牛云配置类 ```java -/** - *

- * 上传配置 - *

- * - * @author yangkai.shen - * @date Created in 2018-10-23 14:09 - */ -@Configuration -@ConditionalOnClass({Servlet.class, StandardServletMultipartResolver.class, MultipartConfigElement.class}) -@ConditionalOnProperty(prefix = "spring.http.multipart", name = "enabled", matchIfMissing = true) -@EnableConfigurationProperties(MultipartProperties.class) -public class UploadConfig { - @Value("${qiniu.accessKey}") - private String accessKey; - - @Value("${qiniu.secretKey}") - private String secretKey; - - private final MultipartProperties multipartProperties; - - @Autowired - public UploadConfig(MultipartProperties multipartProperties) { - this.multipartProperties = multipartProperties; - } - - /** - * 上传配置 - */ - @Bean - @ConditionalOnMissingBean - public MultipartConfigElement multipartConfigElement() { - return this.multipartProperties.createMultipartConfig(); - } - - /** - * 注册解析器 - */ - @Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) - @ConditionalOnMissingBean(MultipartResolver.class) - public StandardServletMultipartResolver multipartResolver() { - StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver(); - multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily()); - return multipartResolver; - } - - /** - * 华东机房 - */ - @Bean - public com.qiniu.storage.Configuration qiniuConfig() { - return new com.qiniu.storage.Configuration(Zone.zone0()); - } - - /** - * 构建一个七牛上传工具实例 - */ - @Bean - public UploadManager uploadManager() { - return new UploadManager(qiniuConfig()); - } - - /** - * 认证信息实例 - */ - @Bean - public Auth auth() { - return Auth.create(accessKey, secretKey); - } - - /** - * 构建七牛空间管理实例 - */ - @Bean - public BucketManager bucketManager() { - return new BucketManager(auth(), qiniuConfig()); - } +@Data +@ConfigurationProperties(prefix = "qiniu") +public class QiniuProperties { + private String accessKey; + private String secretKey; + private String bucket; + private String prefix; } ``` -## UploadController.java +### 1.3.自动装配类 ```java -/** - *

- * 文件上传 Controller - *

- * - * @author yangkai.shen - * @date Created in 2018-11-06 16:33 - */ -@RestController -@Slf4j -@RequestMapping("/upload") -public class UploadController { - @Value("${spring.servlet.multipart.location}") - private String fileTempPath; - - @Value("${qiniu.prefix}") - private String prefix; - - private final IQiNiuService qiNiuService; - - @Autowired - public UploadController(IQiNiuService qiNiuService) { - this.qiNiuService = qiNiuService; - } - - @PostMapping(value = "/local", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public Dict local(@RequestParam("file") MultipartFile file) { - if (file.isEmpty()) { - return Dict.create().set("code", 400).set("message", "文件内容为空"); - } - String fileName = file.getOriginalFilename(); - String rawFileName = StrUtil.subBefore(fileName, ".", true); - String fileType = StrUtil.subAfter(fileName, ".", true); - String localFilePath = StrUtil.appendIfMissing(fileTempPath, "/") + rawFileName + "-" + DateUtil.current(false) + "." + fileType; - try { - file.transferTo(new File(localFilePath)); - } catch (IOException e) { - log.error("【文件上传至本地】失败,绝对路径:{}", localFilePath); - return Dict.create().set("code", 500).set("message", "文件上传失败"); - } - - log.info("【文件上传至本地】绝对路径:{}", localFilePath); - return Dict.create().set("code", 200).set("message", "上传成功").set("data", Dict.create().set("fileName", fileName).set("filePath", localFilePath)); - } - - @PostMapping(value = "/yun", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public Dict yun(@RequestParam("file") MultipartFile file) { - if (file.isEmpty()) { - return Dict.create().set("code", 400).set("message", "文件内容为空"); - } - String fileName = file.getOriginalFilename(); - String rawFileName = StrUtil.subBefore(fileName, ".", true); - String fileType = StrUtil.subAfter(fileName, ".", true); - String localFilePath = StrUtil.appendIfMissing(fileTempPath, "/") + rawFileName + "-" + DateUtil.current(false) + "." + fileType; - try { - file.transferTo(new File(localFilePath)); - Response response = qiNiuService.uploadFile(new File(localFilePath)); - if (response.isOK()) { - JSONObject jsonObject = JSONUtil.parseObj(response.bodyString()); - - String yunFileName = jsonObject.getStr("key"); - String yunFilePath = StrUtil.appendIfMissing(prefix, "/") + yunFileName; - - FileUtil.del(new File(localFilePath)); - - log.info("【文件上传至七牛云】绝对路径:{}", yunFilePath); - return Dict.create().set("code", 200).set("message", "上传成功").set("data", Dict.create().set("fileName", yunFileName).set("filePath", yunFilePath)); - } else { - log.error("【文件上传至七牛云】失败,{}", JSONUtil.toJsonStr(response)); - FileUtil.del(new File(localFilePath)); - return Dict.create().set("code", 500).set("message", "文件上传失败"); - } - } catch (IOException e) { - log.error("【文件上传至七牛云】失败,绝对路径:{}", localFilePath); - return Dict.create().set("code", 500).set("message", "文件上传失败"); - } - } +@Configuration +@ConditionalOnClass({Servlet.class, StandardServletMultipartResolver.class, MultipartConfigElement.class}) +@ConditionalOnProperty(prefix = "spring.http.multipart", name = "enabled", matchIfMissing = true) +@EnableConfigurationProperties({MultipartProperties.class, QiniuProperties.class}) +@RequiredArgsConstructor(onConstructor_ = @Autowired) +public class UploadAutoConfiguration { + private final MultipartProperties multipartProperties; + private final QiniuProperties qiniuProperties; + + /** + * 上传配置 + */ + @Bean + @ConditionalOnMissingBean + public MultipartConfigElement multipartConfigElement() { + return this.multipartProperties.createMultipartConfig(); + } + + /** + * 注册解析器 + */ + @Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) + @ConditionalOnMissingBean(MultipartResolver.class) + public StandardServletMultipartResolver multipartResolver() { + StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver(); + multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily()); + return multipartResolver; + } + + /** + * 华东机房 + */ + @Bean + public com.qiniu.storage.Configuration qiniuConfig() { + return new com.qiniu.storage.Configuration(Region.region0()); + } + + /** + * 构建一个七牛上传工具实例 + */ + @Bean + public UploadManager uploadManager() { + return new UploadManager(qiniuConfig()); + } + + /** + * 认证信息实例 + */ + @Bean + public Auth auth() { + return Auth.create(qiniuProperties.getAccessKey(), qiniuProperties.getSecretKey()); + } + + /** + * 构建七牛空间管理实例 + */ + @Bean + public BucketManager bucketManager() { + return new BucketManager(auth(), qiniuConfig()); + } } ``` -## QiNiuServiceImpl.java +### 1.4.七牛云上传代码 ```java -/** - *

- * 七牛云上传Service - *

- * - * @author yangkai.shen - * @date Created in 2018-11-06 17:22 - */ -@Service @Slf4j -public class QiNiuServiceImpl implements IQiNiuService, InitializingBean { - private final UploadManager uploadManager; - - private final Auth auth; - - @Value("${qiniu.bucket}") - private String bucket; - - private StringMap putPolicy; - - @Autowired - public QiNiuServiceImpl(UploadManager uploadManager, Auth auth) { - this.uploadManager = uploadManager; - this.auth = auth; - } - - /** - * 七牛云上传文件 - * - * @param file 文件 - * @return 七牛上传Response - * @throws QiniuException 七牛异常 - */ - @Override - public Response uploadFile(File file) throws QiniuException { - Response response = this.uploadManager.put(file, file.getName(), getUploadToken()); - int retry = 0; - while (response.needRetry() && retry < 3) { - response = this.uploadManager.put(file, file.getName(), getUploadToken()); - retry++; - } - return response; - } - - @Override - public void afterPropertiesSet() { - this.putPolicy = new StringMap(); - putPolicy.put("returnBody", "{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"bucket\":\"$(bucket)\",\"width\":$(imageInfo.width), \"height\":${imageInfo.height}}"); - } - - /** - * 获取上传凭证 - * - * @return 上传凭证 - */ - private String getUploadToken() { - return this.auth.uploadToken(bucket, null, 3600, putPolicy); - } +@Service +@RequiredArgsConstructor(onConstructor_ = @Autowired) +public class QiNiuService implements InitializingBean { + private final Auth auth; + private final UploadManager uploadManager; + private final QiniuProperties qiniuProperties; + + private StringMap putPolicy; + + + /** + * 七牛云上传文件 + * + * @param file 文件 + * @return 七牛上传Response + * @throws QiniuException 七牛异常 + */ + public Response uploadFile(File file) throws QiniuException { + Response response = this.uploadManager.put(file, file.getName(), getUploadToken()); + int retry = 0; + while (response.needRetry() && retry < 3) { + response = this.uploadManager.put(file, file.getName(), getUploadToken()); + retry++; + } + return response; + } + + @Override + public void afterPropertiesSet() { + this.putPolicy = new StringMap(); + putPolicy.put("returnBody", + "{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"bucket\":\"$(bucket)\",\"width\":$(imageInfo.width), \"height\":${imageInfo.height}}"); + } + + /** + * 获取上传凭证 + * + * @return 上传凭证 + */ + private String getUploadToken() { + return this.auth.uploadToken(qiniuProperties.getBucket(), null, 3600, putPolicy); + } } ``` -## index.html - -```html - - - - - - - spring-boot-demo-upload - - - - - - - - -
- - - -

- - 本地上传 -

-
- - 选择文件 - - - {{ local.loadingStatus ? '本地文件上传中' : '本地上传' }} - -
-
-
状态:{{local.log.message}}
-
文件名:{{local.log.fileName}}
-
文件路径:{{local.log.filePath}}
-
-
-
- - -

- - 七牛云上传 -

-
- - 选择文件 - - - {{ yun.loadingStatus ? '七牛云文件上传中' : '七牛云上传' }} - -
-
-
状态:{{yun.log.message}}
-
文件名:{{yun.log.fileName}}
-
文件路径:{{yun.log.filePath}}
-
-
-
-
-
- - - -``` +### 1.5.测试Controller及前端页面 + +> 不是专业前端,就不在 README 献丑了,代码直接参考 `resources/templates/index.html` 即可 + +## 2.测试 + +> 注意:测试七牛云时,需要先在 `application.yml` 中配置 `qiniu.xxx` 相关参数 + +启动 `UploadApplication` ,打开浏览器,输入 http://localhost:8080/demo + +上传几张图片试试~ + +![测试上传](https://static.xkcoding.com/spring-boot-demo/demo-base/demo-base-upload/2022-09-21-083229.png) + +## 3.参考 + +- [Spring Boot 官方文档之文件上传](https://docs.spring.io/spring-boot/docs/3.0.0-M4/reference/htmlsingle/#howto.spring-mvc.multipart-file-uploads) -## 参考 +- [七牛云官方文档之 Java SDK](https://developer.qiniu.com/kodo/1239/java) -1. Spring 官方文档:https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#howto-multipart-file-upload-configuration -2. 七牛云官方文档:https://developer.qiniu.com/kodo/sdk/1239/java#5 +## 4.特别感谢 +- 感谢 [七牛云](https://portal.qiniu.com/signup?utm_source=kaiyuan&utm_media=xkcoding) 提供的免费云存储与 CDN 加速支持 \ No newline at end of file diff --git a/demo-base/demo-base-upload/pom.xml b/demo-base/demo-base-upload/pom.xml index 7f0792d..62d08dc 100644 --- a/demo-base/demo-base-upload/pom.xml +++ b/demo-base/demo-base-upload/pom.xml @@ -1,70 +1,77 @@ - 4.0.0 - - demo-upload + + com.xkcoding + demo-base 1.0.0-SNAPSHOT - jar + + + 4.0.0 + + demo-base-upload + 1.0.0-SNAPSHOT + jar + + demo-base-upload + Demo project for Spring Boot - demo-upload - Demo project for Spring Boot + + 17 - - com.xkcoding - spring-boot-demo - 1.0.0-SNAPSHOT - + 7.11.0 + - - UTF-8 - UTF-8 - 1.8 - + + + com.xkcoding + common-tools + - - - org.projectlombok - lombok - true - + + org.springframework.boot + spring-boot-starter-web + - - org.springframework.boot - spring-boot-starter-web - + + org.springframework.boot + spring-boot-starter-thymeleaf + - - org.springframework.boot - spring-boot-starter-thymeleaf - + + org.springframework.boot + spring-boot-starter-test + test + - - org.springframework.boot - spring-boot-starter-test - test - + + com.qiniu + qiniu-java-sdk + ${qiniu.version} + - - cn.hutool - hutool-all - + + + com.squareup.okhttp3 + okhttp + 3.14.4 + - - com.qiniu - qiniu-java-sdk - [7.2.0, 7.2.99] - - + + org.projectlombok + lombok + true + + - - demo-upload - - - org.springframework.boot - spring-boot-maven-plugin - - - + + demo-base-upload + + + org.springframework.boot + spring-boot-maven-plugin + + + diff --git a/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/SpringBootDemoUploadApplication.java b/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/UploadApplication.java similarity index 72% rename from demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/SpringBootDemoUploadApplication.java rename to demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/UploadApplication.java index ff9fba8..e5a513e 100644 --- a/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/SpringBootDemoUploadApplication.java +++ b/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/UploadApplication.java @@ -12,9 +12,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; * @date Created in 2018-10-20 21:23 */ @SpringBootApplication -public class SpringBootDemoUploadApplication { +public class UploadApplication { public static void main(String[] args) { - SpringApplication.run(SpringBootDemoUploadApplication.class, args); + SpringApplication.run(UploadApplication.class, args); } } diff --git a/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/autoconfigure/QiniuProperties.java b/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/autoconfigure/QiniuProperties.java new file mode 100644 index 0000000..3e20796 --- /dev/null +++ b/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/autoconfigure/QiniuProperties.java @@ -0,0 +1,22 @@ +package com.xkcoding.upload.autoconfigure; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + *

+ * 七牛云配置 + *

+ * + * @author yangkai.shen + * @date 2022-09-21 16:09 + */ + +@Data +@ConfigurationProperties(prefix = "qiniu") +public class QiniuProperties { + private String accessKey; + private String secretKey; + private String bucket; + private String prefix; +} diff --git a/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/config/UploadConfig.java b/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/autoconfigure/UploadAutoConfiguration.java similarity index 78% rename from demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/config/UploadConfig.java rename to demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/autoconfigure/UploadAutoConfiguration.java index f7a835e..7e33133 100644 --- a/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/config/UploadConfig.java +++ b/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/autoconfigure/UploadAutoConfiguration.java @@ -1,11 +1,13 @@ -package com.xkcoding.upload.config; +package com.xkcoding.upload.autoconfigure; -import com.qiniu.common.Zone; import com.qiniu.storage.BucketManager; +import com.qiniu.storage.Region; import com.qiniu.storage.UploadManager; import com.qiniu.util.Auth; +import jakarta.servlet.MultipartConfigElement; +import jakarta.servlet.Servlet; +import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -17,9 +19,6 @@ import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.support.StandardServletMultipartResolver; import org.springframework.web.servlet.DispatcherServlet; -import javax.servlet.MultipartConfigElement; -import javax.servlet.Servlet; - /** *

* 上传配置 @@ -31,20 +30,11 @@ import javax.servlet.Servlet; @Configuration @ConditionalOnClass({Servlet.class, StandardServletMultipartResolver.class, MultipartConfigElement.class}) @ConditionalOnProperty(prefix = "spring.http.multipart", name = "enabled", matchIfMissing = true) -@EnableConfigurationProperties(MultipartProperties.class) -public class UploadConfig { - @Value("${qiniu.accessKey}") - private String accessKey; - - @Value("${qiniu.secretKey}") - private String secretKey; - +@EnableConfigurationProperties({MultipartProperties.class, QiniuProperties.class}) +@RequiredArgsConstructor(onConstructor_ = @Autowired) +public class UploadAutoConfiguration { private final MultipartProperties multipartProperties; - - @Autowired - public UploadConfig(MultipartProperties multipartProperties) { - this.multipartProperties = multipartProperties; - } + private final QiniuProperties qiniuProperties; /** * 上传配置 @@ -71,7 +61,7 @@ public class UploadConfig { */ @Bean public com.qiniu.storage.Configuration qiniuConfig() { - return new com.qiniu.storage.Configuration(Zone.zone0()); + return new com.qiniu.storage.Configuration(Region.region0()); } /** @@ -87,7 +77,7 @@ public class UploadConfig { */ @Bean public Auth auth() { - return Auth.create(accessKey, secretKey); + return Auth.create(qiniuProperties.getAccessKey(), qiniuProperties.getSecretKey()); } /** diff --git a/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/controller/UploadController.java b/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/controller/UploadController.java index bf77666..77d30a5 100644 --- a/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/controller/UploadController.java +++ b/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/controller/UploadController.java @@ -7,10 +7,12 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.qiniu.http.Response; -import com.xkcoding.upload.service.IQiNiuService; +import com.xkcoding.upload.autoconfigure.QiniuProperties; +import com.xkcoding.upload.service.QiNiuService; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.web.servlet.MultipartProperties; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -29,21 +31,22 @@ import java.io.IOException; * @author yangkai.shen * @date Created in 2018-11-06 16:33 */ -@RestController @Slf4j +@RestController @RequestMapping("/upload") +@RequiredArgsConstructor(onConstructor_ = @Autowired) public class UploadController { - @Value("${spring.servlet.multipart.location}") - private String fileTempPath; + private final MultipartProperties multipartProperties; - @Value("${qiniu.prefix}") - private String prefix; + private final QiniuProperties qiniuProperties; - private final IQiNiuService qiNiuService; + private final QiNiuService qiNiuService; - @Autowired - public UploadController(IQiNiuService qiNiuService) { - this.qiNiuService = qiNiuService; + private String processLocalTmpFilePath(MultipartFile file) { + String fileName = file.getOriginalFilename(); + String rawFileName = StrUtil.subBefore(fileName, ".", true); + String fileType = StrUtil.subAfter(fileName, ".", true); + return StrUtil.appendIfMissing(multipartProperties.getLocation(), "/") + rawFileName + "-" + DateUtil.current() + "." + fileType; } @PostMapping(value = "/local", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @@ -51,10 +54,7 @@ public class UploadController { if (file.isEmpty()) { return Dict.create().set("code", 400).set("message", "文件内容为空"); } - String fileName = file.getOriginalFilename(); - String rawFileName = StrUtil.subBefore(fileName, ".", true); - String fileType = StrUtil.subAfter(fileName, ".", true); - String localFilePath = StrUtil.appendIfMissing(fileTempPath, "/") + rawFileName + "-" + DateUtil.current(false) + "." + fileType; + String localFilePath = processLocalTmpFilePath(file); try { file.transferTo(new File(localFilePath)); } catch (IOException e) { @@ -63,18 +63,16 @@ public class UploadController { } log.info("【文件上传至本地】绝对路径:{}", localFilePath); - return Dict.create().set("code", 200).set("message", "上传成功").set("data", Dict.create().set("fileName", fileName).set("filePath", localFilePath)); + return Dict.create().set("code", 200).set("message", "上传成功") + .set("data", Dict.create().set("fileName", file.getOriginalFilename()).set("filePath", localFilePath)); } @PostMapping(value = "/yun", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public Dict yun(@RequestParam("file") MultipartFile file) { + public Dict qiniu(@RequestParam("file") MultipartFile file) { if (file.isEmpty()) { return Dict.create().set("code", 400).set("message", "文件内容为空"); } - String fileName = file.getOriginalFilename(); - String rawFileName = StrUtil.subBefore(fileName, ".", true); - String fileType = StrUtil.subAfter(fileName, ".", true); - String localFilePath = StrUtil.appendIfMissing(fileTempPath, "/") + rawFileName + "-" + DateUtil.current(false) + "." + fileType; + String localFilePath = processLocalTmpFilePath(file); try { file.transferTo(new File(localFilePath)); Response response = qiNiuService.uploadFile(new File(localFilePath)); @@ -82,19 +80,21 @@ public class UploadController { JSONObject jsonObject = JSONUtil.parseObj(response.bodyString()); String yunFileName = jsonObject.getStr("key"); - String yunFilePath = StrUtil.appendIfMissing(prefix, "/") + yunFileName; + String yunFilePath = StrUtil.appendIfMissing(qiniuProperties.getPrefix(), "/") + yunFileName; + // 删除本地临时文件 FileUtil.del(new File(localFilePath)); log.info("【文件上传至七牛云】绝对路径:{}", yunFilePath); - return Dict.create().set("code", 200).set("message", "上传成功").set("data", Dict.create().set("fileName", yunFileName).set("filePath", yunFilePath)); + return Dict.create().set("code", 200).set("message", "上传成功") + .set("data", Dict.create().set("fileName", yunFileName).set("filePath", yunFilePath)); } else { log.error("【文件上传至七牛云】失败,{}", JSONUtil.toJsonStr(response)); FileUtil.del(new File(localFilePath)); return Dict.create().set("code", 500).set("message", "文件上传失败"); } } catch (IOException e) { - log.error("【文件上传至七牛云】失败,绝对路径:{}", localFilePath); + log.error("【文件上传至七牛云】失败,绝对路径:{}", localFilePath, e); return Dict.create().set("code", 500).set("message", "文件上传失败"); } } diff --git a/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/service/IQiNiuService.java b/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/service/IQiNiuService.java deleted file mode 100644 index b0d11d4..0000000 --- a/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/service/IQiNiuService.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.xkcoding.upload.service; - -import com.qiniu.common.QiniuException; -import com.qiniu.http.Response; - -import java.io.File; - -/** - *

- * 七牛云上传Service - *

- * - * @author yangkai.shen - * @date Created in 2018-11-06 17:21 - */ -public interface IQiNiuService { - /** - * 七牛云上传文件 - * - * @param file 文件 - * @return 七牛上传Response - * @throws QiniuException 七牛异常 - */ - Response uploadFile(File file) throws QiniuException; -} diff --git a/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/service/impl/QiNiuServiceImpl.java b/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/service/QiNiuService.java similarity index 66% rename from demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/service/impl/QiNiuServiceImpl.java rename to demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/service/QiNiuService.java index 5b08523..9b9f228 100644 --- a/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/service/impl/QiNiuServiceImpl.java +++ b/demo-base/demo-base-upload/src/main/java/com/xkcoding/upload/service/QiNiuService.java @@ -1,15 +1,15 @@ -package com.xkcoding.upload.service.impl; +package com.xkcoding.upload.service; import com.qiniu.common.QiniuException; import com.qiniu.http.Response; import com.qiniu.storage.UploadManager; import com.qiniu.util.Auth; import com.qiniu.util.StringMap; -import com.xkcoding.upload.service.IQiNiuService; +import com.xkcoding.upload.autoconfigure.QiniuProperties; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.io.File; @@ -22,23 +22,16 @@ import java.io.File; * @author yangkai.shen * @date Created in 2018-11-06 17:22 */ -@Service @Slf4j -public class QiNiuServiceImpl implements IQiNiuService, InitializingBean { - private final UploadManager uploadManager; - +@Service +@RequiredArgsConstructor(onConstructor_ = @Autowired) +public class QiNiuService implements InitializingBean { private final Auth auth; - - @Value("${qiniu.bucket}") - private String bucket; + private final UploadManager uploadManager; + private final QiniuProperties qiniuProperties; private StringMap putPolicy; - @Autowired - public QiNiuServiceImpl(UploadManager uploadManager, Auth auth) { - this.uploadManager = uploadManager; - this.auth = auth; - } /** * 七牛云上传文件 @@ -47,7 +40,6 @@ public class QiNiuServiceImpl implements IQiNiuService, InitializingBean { * @return 七牛上传Response * @throws QiniuException 七牛异常 */ - @Override public Response uploadFile(File file) throws QiniuException { Response response = this.uploadManager.put(file, file.getName(), getUploadToken()); int retry = 0; @@ -61,7 +53,8 @@ public class QiNiuServiceImpl implements IQiNiuService, InitializingBean { @Override public void afterPropertiesSet() { this.putPolicy = new StringMap(); - putPolicy.put("returnBody", "{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"bucket\":\"$(bucket)\",\"width\":$(imageInfo.width), \"height\":${imageInfo.height}}"); + putPolicy.put("returnBody", + "{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"bucket\":\"$(bucket)\",\"width\":$(imageInfo.width), \"height\":${imageInfo.height}}"); } /** @@ -70,6 +63,6 @@ public class QiNiuServiceImpl implements IQiNiuService, InitializingBean { * @return 上传凭证 */ private String getUploadToken() { - return this.auth.uploadToken(bucket, null, 3600, putPolicy); + return this.auth.uploadToken(qiniuProperties.getBucket(), null, 3600, putPolicy); } } diff --git a/demo-base/demo-base-upload/src/main/resources/application.yml b/demo-base/demo-base-upload/src/main/resources/application.yml index 828d856..cfb5a43 100644 --- a/demo-base/demo-base-upload/src/main/resources/application.yml +++ b/demo-base/demo-base-upload/src/main/resources/application.yml @@ -4,17 +4,17 @@ server: context-path: /demo qiniu: ## 此处填写你自己的七牛云 access key - accessKey: + accessKey: xx ## 此处填写你自己的七牛云 secret key - secretKey: + secretKey: xxx ## 此处填写你自己的七牛云 bucket - bucket: + bucket: blog ## 此处填写你自己的七牛云 域名 - prefix: + prefix: https://static.xkcoding.com/ spring: servlet: multipart: enabled: true - location: /Users/yangkai.shen/Documents/code/back-end/spring-boot-demo/spring-boot-demo-upload/tmp + location: /Users/yangkai.shen/Codes/xkcoding/spring-boot-demo/tmp file-size-threshold: 5MB - max-file-size: 20MB \ No newline at end of file + max-file-size: 20MB diff --git a/demo-base/demo-base-upload/src/test/java/com/xkcoding/upload/SpringBootDemoUploadApplicationTests.java b/demo-base/demo-base-upload/src/test/java/com/xkcoding/upload/SpringBootDemoUploadApplicationTests.java deleted file mode 100644 index 44ce0e8..0000000 --- a/demo-base/demo-base-upload/src/test/java/com/xkcoding/upload/SpringBootDemoUploadApplicationTests.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.xkcoding.upload; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest -public class SpringBootDemoUploadApplicationTests { - - @Test - public void contextLoads() { - } - -} diff --git a/demo-base/demo-base-upload/src/test/java/com/xkcoding/upload/UploadApplicationTests.java b/demo-base/demo-base-upload/src/test/java/com/xkcoding/upload/UploadApplicationTests.java new file mode 100644 index 0000000..71babc2 --- /dev/null +++ b/demo-base/demo-base-upload/src/test/java/com/xkcoding/upload/UploadApplicationTests.java @@ -0,0 +1,13 @@ +package com.xkcoding.upload; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class UploadApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/demo-base/pom.xml b/demo-base/pom.xml index 3b5fa19..f438db7 100644 --- a/demo-base/pom.xml +++ b/demo-base/pom.xml @@ -24,6 +24,7 @@ demo-base-async demo-base-exception demo-base-email + demo-base-upload