SpringBoot自定义starter-统一上传服务
为什么要用starter
在日常的开发中,许多功能都是重复的,比如上传,权限认证,redis的一些操作等。如果采用模块的方式在每一个项目中都加载这些模块,会导致项目比较大,且结构不清晰。
如果采用了starter就可以简便很多,在开发中,只需要从仓库依赖需要的jar即可。
背景
前两天,国内的码云抽风了,导致大家的图床都受到了影响,无法查看到图片。我的社区也收到了影响,于是,我将上传操作相关构建成starter,使其支持本地、git、oss、七牛云等。
如何操作呢?
首先是上传可以上传到不同的地方,根据面向对象的思想,我们将上传抽离出一个上传接口-统一规范。不管上传到哪里,都根据多态调用统一上传接口。
定义我们的yml
upload:
#上传类型-local-git-oss
type: local
#本地上传
local:
path: /data/nginx/html/upload/
url: http://oss.mxchaoba.top/
git:
#码云私人令牌
access-token: xxxx
#码云个人空间名
owner: chaoba
#上传指定仓库
repo: chaoba
#码云存放路径
path: /uploadImg/
定义UploadProperties
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@ConfigurationProperties(prefix = "upload")
@EnableConfigurationProperties(UploadProperties.class)
public class UploadProperties {
private String type = "local";
private LocalProperties local = new LocalProperties();
private GitProperties git = new GitProperties();
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public LocalProperties getLocal() {
return local;
}
public void setLocal(LocalProperties local) {
this.local = local;
}
public GitProperties getGit() {
return git;
}
public void setGit(GitProperties git) {
this.git = git;
}
public class LocalProperties {
private String path;
private String url;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
public class GitProperties {
private String accessToken;
private String owner;
private String repo;
private String path;
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getRepo() {
return repo;
}
public void setRepo(String repo) {
this.repo = repo;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
}
定义上传服务接口
import org.springframework.web.multipart.MultipartFile;
/**
* 上传接口,统一统一的规范,不同上传,统一入口
*/
public interface UploadService {
/***
* 上传
* @param file 要上传的文件
* @return 返回上传后的地址
*/
String upload(MultipartFile file);
/**
* 获取文件名
*
* @param fileName
* @return
*/
String getExt(String fileName);
/**
* 检查文件名是否满足
*
* @param ext
* @return
*/
boolean checkExt(String ext);
}
不同上传实现上传接口
其他上传类型同理
/**
* 本地上传
*/
public class LocalUploadServiceImpl implements UploadService {
/**
* 存放路径
*/
private UploadProperties.LocalProperties localProperties;
@Override
public String upload(MultipartFile file) {
try {
if (file == null || file.isEmpty() || file.getSize() == 0L) {
throw new CustomException("文件为空");
}
String originalFilename = file.getOriginalFilename();
String ext = getExt(originalFilename);
if (!checkExt(ext)) {
throw new CustomException("文件类型错误");
}
InputStream inputStream = file.getInputStream();
String returnPath = CommunityUtil.generateUUID() + "/" + CommunityUtil.generateUUID() + ext;
String filePath = localProperties.getPath() + returnPath;
File file1 = new File(filePath);
if (!file1.exists()){
file1.getParentFile().mkdirs();
}
FileOutputStream fos = new FileOutputStream(file1);
byte[] buf = new byte[1024];
while (inputStream.read(buf) != -1) {
fos.write(buf);
fos.flush();
}
fos.close();
return localProperties.getUrl()+returnPath;
} catch (Exception e) {
e.printStackTrace();
}
throw new CustomException("上传失败");
}
@Override
public String getExt(String fileName) {
return FileUtils.getFileSuffix(fileName);
}
@Override
public boolean checkExt(String ext) {
return FileUtils.checkExt(ext);
}
public UploadProperties.LocalProperties getLocalProperties() {
return localProperties;
}
public void setLocalProperties(UploadProperties.LocalProperties localProperties) {
this.localProperties = localProperties;
}
}
配置类
@EnableConfigurationProperties(UploadProperties.class)
@Configuration
public class UploadAutoConfig{
@Autowired
private UploadProperties uploadProperties;
/**
* 初始化git上传服务
*@ConditionalOnProperty(name = "upload.type", havingValue = "git")
* 上面的ConditionalOnProperty表示,如果upload.type的值等于git 则将初始化下面的bean
* @return
*/
@Bean
@ConditionalOnProperty(name = "upload.type", havingValue = "git")
public UploadService gitUploadService() {
GitUploadServiceImpl gitUploadService = new GitUploadServiceImpl();
gitUploadService.setGitProperties(uploadProperties.getGit());
return gitUploadService;
}
/**
* 初始化本地上传服务
*
* @return
*/
@Bean
@ConditionalOnProperty(name = "upload.type", havingValue = "local")
public UploadService localUploadService() {
LocalUploadServiceImpl localUploadService = new LocalUploadServiceImpl();
localUploadService.setLocalProperties(uploadProperties.getLocal());
return localUploadService;
}
}
创建spring.factories
在resources创建META-INF,在META-INF下创建spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.chaoba.upload.UploadAutoConfig
安装到本地仓库或者发布到远程仓库
发布完成后,正常引入即可使用
uploadService.upload(file);
一万年太久,只争朝夕!