1:首先配置pom依赖:
<dependency>
<groupId>com.aliyun.ossgroupId>
<artifactId>aliyun-sdk-ossartifactId>
<version>3.8.0version>
dependency>
<dependency>
<groupId>com.qcloudgroupId>
<artifactId>cos_apiartifactId>
<version>5.6.75version>
dependency>
2:application.yml:
upload:
mode: windowsLocal
linuxLocal:
url: https://上传子域名/
path: /usr/local/blog/upload/
windowsLocal:
url: http://localhost:8080/upload/
path: G:/桌面/博客/mongo-blog-master/springboot/src/main/resources/upload/
oss:
url: http://Bucket域名/
endpoint: OSS配置endpoint
accessKeyId: OSS配置accessKeyId
accessKeySecret: OSS配置accessKeySecret
bucketName: OSS配置bucketName
cos:
url: https://ftz-1307097786.cos.ap-beijing.myqcloud.com/
region: ap-beijing
secretId: AKIDhKqBJPN8mDWcWFm6oVBj4A2h7IF2lFUX
secretKey: tBLekcFi27yb3IJ6i7GCzYt2ymLgtwmt
bucketName: ftz-1307097786
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
2.1:腾讯云信息查看:secretId+secretKey在访问密钥里面查看
2.2:url+region+bucketName在配置管理查看
3:Windows本地,Linux本地,阿里云,腾讯云的配置:
3.1 :Windows本地配置:
(1):首先配置application.yml:
(2***):重点:配置登录拦截器,设置虚拟路径,因为浏览器不可以直接访问电脑资源目录文件,所以需要设置虚拟路径!否则会报错:Not allowed to load local resource
;这里的路径要跟application.yml中的路径相匹配
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/upload/**").addResourceLocations("file:G:/桌面/博客/mongo-blog-master/springboot/src/main/resources/upload/");
}
(3):策略枚举层:
package com.jjhroy.blog.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum UploadModeEnum {
OSS("oss", "ossUploadStrategyImpl"),
LOCAL("linuxLocal", "localUploadStrategyImpl"),
WINDOWS("windowsLocal","windowsUploadStrategyImpl"),
COS("cos", "cosUploadStrategyImpl");
private final String mode;
private final String strategy;
public static String getStrategy(String mode) {
for (UploadModeEnum value : UploadModeEnum.values()) {
if (value.getMode().equals(mode)) {
return value.getStrategy();
}
}
return null;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
(4):文件上传策略:
package com.jjhroy.blog.strategy.context;
import com.jjhroy.blog.enums.UploadModeEnum;
import com.jjhroy.blog.strategy.UploadStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.util.Map;
@Service
public class UploadStrategyContext {
@Value("${upload.mode}")
private String uploadMode;
@Autowired
private Map<String, UploadStrategy> uploadStrategyMap;
public String executeUploadStrategy(MultipartFile file, String path) {
return uploadStrategyMap.get(UploadModeEnum.getStrategy(uploadMode)).uploadFile(file, path);
}
public String executeUploadStrategy(String fileName, InputStream inputStream, String path) {
return uploadStrategyMap.get(UploadModeEnum.getStrategy(uploadMode)).uploadFile(fileName, inputStream, path);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
(5):本地路径上传策略方法实现层:WindowsUploadStrategyImpl:
package com.jjhroy.blog.strategy.impl;
import com.jjhroy.blog.enums.FileExtEnum;
import com.jjhroy.blog.exception.BizException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.*;
import java.nio.file.Files;
import java.util.Objects;
@Service("windowsUploadStrategyImpl")
public class WindowsUploadStrategyImpl extends AbstractUploadStrategyImpl {
@Value("${upload.windowsLocal.path}")
private String localPath;
@Value("${upload.windowsLocal.url}")
private String localUrl;
@Override
public Boolean exists(String filePath) {
return new File(localPath + filePath).exists();
}
@Override
public void upload(String path, String fileName, InputStream inputStream) throws IOException {
File directory = new File(localPath + path);
if (!directory.exists()) {
if (!directory.mkdirs()) {
throw new BizException("创建目录失败");
}
}
File file = new File(localPath + path + fileName);
String ext = "." + fileName.split("\\.")[1];
switch (Objects.requireNonNull(FileExtEnum.getFileExt(ext))) {
case MD:
case TXT:
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
while (reader.ready()) {
writer.write((char) reader.read());
}
writer.flush();
writer.close();
reader.close();
break;
default:
BufferedInputStream bis = new BufferedInputStream(inputStream);
BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(file.toPath()));
byte[] bytes = new byte[1024];
int length;
while ((length = bis.read(bytes)) != -1) {
bos.write(bytes, 0, length);
}
bos.flush();
bos.close();
bis.close();
break;
}
inputStream.close();
}
@Override
public String getFileAccessUrl(String filePath) {
return localUrl+filePath;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
(6):controller层:更新用户头像为例:
@ApiOperation(value = "更新用户头像")
@ApiImplicitParam(name = "file", value = "用户头像", required = true, dataType = "MultipartFile")
@PostMapping("/users/avatar")
public Result<String> updateUserAvatar(MultipartFile file) {
return Result.ok(userInfoService.updateUserAvatar(file));
}
(7):userInfoService.updateUserAvatar层及其实现:
@Transactional(rollbackFor = Exception.class)
@Override
public String updateUserAvatar(MultipartFile file) {
String avatar = uploadStrategyContext.executeUploadStrategy(file, FilePathEnum.AVATAR.getPath());
UserInfo userInfo = UserInfo.builder()
.id(UserUtils.getLoginUser().getUserInfoId())
.avatar(avatar)
.build();
userInfoDao.updateById(userInfo);
return avatar;
}
(8):uploadStrategyContext.executeUploadStrategy:
package com.jjhroy.blog.strategy.context;
import com.jjhroy.blog.enums.UploadModeEnum;
import com.jjhroy.blog.strategy.UploadStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.util.Map;
@Service
public class UploadStrategyContext {
@Value("${upload.mode}")
private String uploadMode;
@Autowired
private Map<String, UploadStrategy> uploadStrategyMap;
public String executeUploadStrategy(MultipartFile file, String path) {
return uploadStrategyMap.get(UploadModeEnum.getStrategy(uploadMode)).uploadFile(file, path);
}
public String executeUploadStrategy(String fileName, InputStream inputStream, String path) {
return uploadStrategyMap.get(UploadModeEnum.getStrategy(uploadMode)).uploadFile(fileName, inputStream, path);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
(9):抽象上传模板
(10)文件上传工具类:
package com.jjhroy.blog.util;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.codec.binary.Hex;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.util.Objects;
@Log4j2
public class FileUtils {
public static String getMd5(InputStream inputStream) {
try {
MessageDigest md5 = MessageDigest.getInstance("md5");
byte[] buffer = new byte[8192];
int length;
while ((length = inputStream.read(buffer)) != -1) {
md5.update(buffer, 0, length);
}
return new String(Hex.encodeHex(md5.digest()));
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static String getExtName(String fileName) {
if (StringUtils.isBlank(fileName)) {
return "";
}
return fileName.substring(fileName.lastIndexOf("."));
}
public static File multipartFileToFile(MultipartFile multipartFile) {
File file = null;
try {
String originalFilename = multipartFile.getOriginalFilename();
String[] filename = Objects.requireNonNull(originalFilename).split("\\.");
file = File.createTempFile(filename[0], filename[1]);
multipartFile.transferTo(file);
file.deleteOnExit();
} catch (IOException e) {
e.printStackTrace();
}
return file;
}
private static double getAccuracy(long size) {
double accuracy;
if (size < 900) {
accuracy = 0.85;
} else if (size < 2048) {
accuracy = 0.6;
} else if (size < 3072) {
accuracy = 0.44;
} else {
accuracy = 0.4;
}
return accuracy;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
3.2:其余三种类似,只需要改变一下application.yml就好