本篇文章实现类本地、阿里云、腾讯云文件的上传。
# 引入需求的依赖
<dependency> | |
<groupId>io.swagger</groupId> | |
<artifactId>swagger-annotations</artifactId> | |
<version>1.6.5</version> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.commons</groupId> | |
<artifactId>commons-lang3</artifactId> | |
<version>3.10</version> | |
</dependency> | |
<dependency> | |
<groupId>commons-io</groupId> | |
<artifactId>commons-io</artifactId> | |
<version>2.7</version> | |
</dependency> | |
<dependency> | |
<groupId>com.aliyun.oss</groupId> | |
<artifactId>aliyun-sdk-oss</artifactId> | |
<version>3.14.0</version> | |
</dependency> | |
<dependency> | |
<groupId>com.qcloud</groupId> | |
<artifactId>cos_api</artifactId> | |
<version>5.6.22</version> | |
</dependency> | |
<dependency> | |
<groupId>javax.validation</groupId> | |
<artifactId>validation-api</artifactId> | |
<version>2.0.1.Final</version> | |
</dependency> |
# 定义需要的实体和对象
# 对象
Refer
package com.example.demo.dto; | |
/** | |
* 一种存储结构 | |
*/ | |
public class Refer { | |
private String id; | |
private String code; | |
private String name; | |
public Refer(String id, String code, String name) { | |
this.id = id; | |
this.code = code; | |
this.name = name; | |
} | |
public String getId() { | |
return id; | |
} | |
public void setId(String id) { | |
this.id = id; | |
} | |
public String getCode() { | |
return code; | |
} | |
public void setCode(String code) { | |
this.code = code; | |
} | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
} |
Attach
package com.example.demo.dto; | |
import io.swagger.annotations.ApiModel; | |
import io.swagger.annotations.ApiModelProperty; | |
import java.io.Serializable; | |
/** | |
* 返回附件地址 | |
*/ | |
@ApiModel(description = "附件") | |
public class Attach implements Serializable { | |
@ApiModelProperty(value = "编号") | |
private String id; | |
@ApiModelProperty(value = "名字") | |
private String name; | |
@ApiModelProperty(value = "地址") | |
private String url; | |
public String getId() { | |
return id; | |
} | |
public void setId(String id) { | |
this.id = id; | |
} | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
public String getUrl() { | |
return url; | |
} | |
public void setUrl(String url) { | |
this.url = url; | |
} | |
} |
UploadFileForm
package com.example.demo.dto; | |
import io.swagger.annotations.ApiModel; | |
import io.swagger.annotations.ApiModelProperty; | |
import org.springframework.web.multipart.MultipartFile; | |
import javax.validation.constraints.NotNull; | |
import java.io.Serializable; | |
/** | |
* 文件上传表单. | |
*/ | |
@ApiModel(description = "文件上传表单") | |
public class UploadFileForm implements Serializable { | |
@ApiModelProperty(value = "文件目录") | |
private String catalogCode; | |
@ApiModelProperty(value = "文件数据", notes = "multipart", required = true) | |
private MultipartFile file; | |
public String getCatalogCode() { | |
return catalogCode; | |
} | |
public void setCatalogCode(String catalogCode) { | |
this.catalogCode = catalogCode; | |
} | |
public MultipartFile getFile() { | |
return file; | |
} | |
public void setFile(MultipartFile file) { | |
this.file = file; | |
} | |
} |
# 实体
AbstractEntity
package com.example.demo.entity; | |
import com.example.demo.dto.Refer; | |
/** | |
* 实体基类 | |
*/ | |
public class AbstractEntity { | |
protected String id; | |
protected String code; | |
protected String name; | |
public Refer toRefer() { | |
return new Refer(id, code, name); | |
} | |
public String getId() { | |
return id; | |
} | |
public void setId(String id) { | |
this.id = id; | |
} | |
public String getCode() { | |
return code; | |
} | |
public void setCode(String code) { | |
this.code = code; | |
} | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
} |
StorageEntity
package com.example.demo.entity; | |
import io.swagger.annotations.ApiModel; | |
import io.swagger.annotations.ApiModelProperty; | |
/** | |
* 用来定义文件存储地(阿里云、腾讯云、本地等等) | |
*/ | |
@ApiModel(description = "存储空间") | |
public class StorageEntity extends AbstractEntity{ | |
@ApiModelProperty(value = "服务类型") | |
private String instance; | |
/** | |
* 服务地址. | |
* 后台 API 的操作地址; | |
*/ | |
@ApiModelProperty(value = "服务地址") | |
private String service; | |
@ApiModelProperty(value = "用户名") | |
private String username; | |
@ApiModelProperty(value = "密码") | |
private String password; | |
@ApiModelProperty(value = "根路径") | |
private String root; | |
/** | |
* 访问路径. | |
* 生成的 url 访问路径,用于前端访问地址; | |
*/ | |
@ApiModelProperty(value = "访问路径") | |
private String address; | |
public String getInstance() { | |
return instance; | |
} | |
public void setInstance(String instance) { | |
this.instance = instance; | |
} | |
public String getService() { | |
return service; | |
} | |
public void setService(String service) { | |
this.service = service; | |
} | |
public String getUsername() { | |
return username; | |
} | |
public void setUsername(String username) { | |
this.username = username; | |
} | |
public String getPassword() { | |
return password; | |
} | |
public void setPassword(String password) { | |
this.password = password; | |
} | |
public String getRoot() { | |
return root; | |
} | |
public void setRoot(String root) { | |
this.root = root; | |
} | |
public String getAddress() { | |
return address; | |
} | |
public void setAddress(String address) { | |
this.address = address; | |
} | |
} |
CatalogEntity
package com.example.demo.entity; | |
import com.example.demo.dto.Refer; | |
import io.swagger.annotations.ApiModel; | |
import io.swagger.annotations.ApiModelProperty; | |
/** | |
* 用于定义文件存储位置以及对文件的限制 | |
*/ | |
@ApiModel(description = "目录") | |
public class CatalogEntity extends AbstractEntity{ | |
@ApiModelProperty(value = "存储空间") | |
private Refer storage; | |
@ApiModelProperty(value = "相对路径") | |
private String path; | |
@ApiModelProperty(value = "过期设置") | |
private long expire; | |
@ApiModelProperty(value = "大小限制") | |
private long size; | |
@ApiModelProperty(value = "文件类型") | |
private String[] accepts; | |
/** | |
* UUID:根虎 UUID 命名文件 | |
* DATETIME:根据当前时间戳命名文件 | |
* ORIGIN:原文件名 | |
* ORIGIN_DATETIME:原文件名_时间戳命名文件 | |
*/ | |
@ApiModelProperty(value = "重命名规则", notes = "UUID|DATETIME|ORIGIN|ORIGIN_DATETIME", example = "UUID") | |
private String rename; | |
public Refer getStorage() { | |
return storage; | |
} | |
public void setStorage(Refer storage) { | |
this.storage = storage; | |
} | |
public String getPath() { | |
return path; | |
} | |
public void setPath(String path) { | |
this.path = path; | |
} | |
public long getExpire() { | |
return expire; | |
} | |
public void setExpire(long expire) { | |
this.expire = expire; | |
} | |
public long getSize() { | |
return size; | |
} | |
public void setSize(long size) { | |
this.size = size; | |
} | |
public String[] getAccepts() { | |
return accepts; | |
} | |
public void setAccepts(String[] accepts) { | |
this.accepts = accepts; | |
} | |
public String getRename() { | |
return rename; | |
} | |
public void setRename(String rename) { | |
this.rename = rename; | |
} | |
} |
AttachmentEntity
package com.example.demo.entity; | |
import com.example.demo.dto.Attach; | |
import com.example.demo.dto.Refer; | |
import io.swagger.annotations.ApiModelProperty; | |
/** | |
* 用于文件存储记录 | |
*/ | |
public class AttachmentEntity extends AbstractEntity{ | |
@ApiModelProperty(value = "附件标题") | |
private String title; | |
@ApiModelProperty(value = "内容描述") | |
private String content; | |
@ApiModelProperty(value = "存储空间") | |
private Refer storage; | |
@ApiModelProperty(value = "存储目录") | |
private Refer catalog; | |
@ApiModelProperty(value = "文件") | |
private String file; | |
@ApiModelProperty(value = "类型") | |
private String type; | |
@ApiModelProperty(value = "文件大小") | |
private long size; | |
@ApiModelProperty(value = "url") | |
private String url; | |
@ApiModelProperty(value = "备注") | |
private String note; | |
public Attach toAttach() { | |
Attach attach = new Attach(); | |
attach.setId(id); | |
attach.setUrl(url); | |
attach.setName(name); | |
return attach; | |
} | |
public String getTitle() { | |
return title; | |
} | |
public void setTitle(String title) { | |
this.title = title; | |
} | |
public String getContent() { | |
return content; | |
} | |
public void setContent(String content) { | |
this.content = content; | |
} | |
public Refer getStorage() { | |
return storage; | |
} | |
public void setStorage(Refer storage) { | |
this.storage = storage; | |
} | |
public Refer getCatalog() { | |
return catalog; | |
} | |
public void setCatalog(Refer catalog) { | |
this.catalog = catalog; | |
} | |
public String getFile() { | |
return file; | |
} | |
public void setFile(String file) { | |
this.file = file; | |
} | |
public String getType() { | |
return type; | |
} | |
public void setType(String type) { | |
this.type = type; | |
} | |
public long getSize() { | |
return size; | |
} | |
public void setSize(long size) { | |
this.size = size; | |
} | |
public String getUrl() { | |
return url; | |
} | |
public void setUrl(String url) { | |
this.url = url; | |
} | |
public String getNote() { | |
return note; | |
} | |
public void setNote(String note) { | |
this.note = note; | |
} | |
} |
# 定义需要的数据层和服务层
# 数据层
StorageDao
package com.example.demo.dao; | |
import com.example.demo.entity.StorageEntity; | |
import org.springframework.stereotype.Component; | |
import java.util.HashMap; | |
import java.util.Map; | |
@Component | |
public class StorageDao { | |
// 采用临时存储,可连接数据库 | |
private static Map<String, StorageEntity> map = new HashMap<>(); | |
static { | |
StorageEntity entity = new StorageEntity(); | |
entity.setCode("LOCAL"); | |
entity.setName("本地存储空间"); | |
entity.setAddress("E:/file/demo"); | |
entity.setInstance("simple"); | |
entity.setService("E:/file"); | |
entity.setRoot("demo"); | |
map.put(entity.getCode(), entity); | |
} | |
static { | |
StorageEntity entity = new StorageEntity(); | |
entity.setCode("ALIYUN"); | |
entity.setName("阿里云存储空间"); | |
entity.setAddress("https://aliyun.com/demo"); | |
entity.setInstance("oss"); | |
entity.setService("https://aliyun.com/"); | |
entity.setRoot("demo"); | |
entity.setUsername("阿里云的ID"); | |
entity.setPassword("阿里云的秘钥"); | |
map.put(entity.getCode(), entity); | |
} | |
public StorageEntity findByCode(String code) { | |
return map.get(code); | |
} | |
} |
CatalogDao
package com.example.demo.dao; | |
import com.example.demo.entity.CatalogEntity; | |
import com.example.demo.dto.Refer; | |
import org.springframework.stereotype.Component; | |
import java.util.HashMap; | |
import java.util.Map; | |
@Component | |
public class CatalogDao { | |
// 采用临时存储,可连接数据库 | |
private static Map<String, CatalogEntity> map = new HashMap<>(); | |
static { | |
CatalogEntity entity = new CatalogEntity(); | |
entity.setCode("FILE"); | |
entity.setName("文件"); | |
// 存储空间,取 StorageDao 里面的数据 | |
entity.setStorage(new Refer("", "LOCAL", "本地存储空间")); | |
entity.setPath("file"); | |
entity.setRename("UUID"); | |
entity.setSize(1024*1024*10); | |
map.put(entity.getCode(), entity); | |
} | |
static { | |
CatalogEntity entity = new CatalogEntity(); | |
entity.setCode("PICTURE"); | |
entity.setName("图片"); | |
// 存储空间,取 StorageDao 里面的数据 | |
entity.setStorage(new Refer("", "ALIYUN", "阿里云存储空间")); | |
entity.setPath("picture"); | |
entity.setRename("UUID"); | |
entity.setSize(1024*1024*10); | |
map.put(entity.getCode(), entity); | |
} | |
public CatalogEntity findByCode(String code) { | |
return map.get(code); | |
} | |
} |
AttachmentDao
package com.example.demo.dao; | |
import com.example.demo.entity.AttachmentEntity; | |
import org.springframework.stereotype.Component; | |
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.UUID; | |
@Component | |
public class AttachmentDao { | |
private static Map<String, AttachmentEntity> map = new HashMap<>(); | |
public AttachmentEntity add(AttachmentEntity attachment) { | |
attachment.setId(UUID.randomUUID().toString()); | |
map.put(attachment.getId(), attachment); | |
return attachment; | |
} | |
public List<AttachmentEntity> queryAll() { | |
return new ArrayList<AttachmentEntity>(map.values()); | |
} | |
public AttachmentEntity get(String attachId) { | |
return map.get(attachId); | |
} | |
} |
# 服务层
AttachmentService
package com.example.demo.service; | |
import com.example.demo.dao.AttachmentDao; | |
import com.example.demo.entity.AttachmentEntity; | |
import com.example.demo.entity.CatalogEntity; | |
import com.example.demo.entity.StorageEntity; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.stereotype.Service; | |
import java.util.UUID; | |
@Service | |
public class AttachmentService { | |
public static final Logger LOG = LoggerFactory.getLogger(AttachmentService.class); | |
@Autowired | |
private AttachmentDao attachmentDao; | |
public AttachmentEntity upload(CatalogEntity catalog, StorageEntity storage, | |
String name, String file, String type, long size) { | |
AttachmentEntity attachment = new AttachmentEntity(); | |
// 目录 | |
attachment.setCatalog(catalog.toRefer()); | |
// 存储空间 | |
attachment.setStorage(storage.toRefer()); | |
attachment.setCode(System.currentTimeMillis() + ""); | |
// 原始文件名 | |
attachment.setName(naming(name)); | |
// 重命名文件名 | |
attachment.setFile(renaming(naming(file), catalog.getRename())); | |
attachment.setType(type); | |
attachment.setSize(size); | |
attachment.setUrl(storage.getAddress() + "/" + catalog.getPath() + "/" + attachment.getFile()); | |
attachment.setNote("开始上传文件"); | |
return attachmentDao.add(attachment); | |
} | |
/** | |
* 获取文件名称 | |
*/ | |
private String naming(String file) { | |
int index = 0; | |
index = file.lastIndexOf("/"); | |
if (index > 0) { | |
return file.substring(index + 1); | |
} | |
index = file.lastIndexOf("\\"); | |
if (index > 0) { | |
return file.substring(index + 1); | |
} | |
return file; | |
} | |
/** | |
* 重命名 | |
*/ | |
private String renaming(String file, String rename) { | |
String r = ""; | |
switch (rename) { | |
case "ORIGIN": | |
return file; | |
case "DATETIME": | |
return System.currentTimeMillis() + suffix(file); | |
case "ORIGIN_DATETIME": | |
return file + "_" + System.currentTimeMillis() + suffix(file); | |
default: | |
return UUID.randomUUID() + suffix(file); | |
} | |
} | |
/** | |
* 文件后缀 | |
*/ | |
private String suffix(String file) { | |
int index = file.lastIndexOf("."); | |
if (index > 0) { | |
return file.substring(index); | |
} | |
return ""; | |
} | |
} |
# 定义文件上传相关类
# 上传工具抽象类
UploadHelper
package com.example.demo.helper; | |
import com.example.demo.entity.AttachmentEntity; | |
import com.example.demo.entity.CatalogEntity; | |
import com.example.demo.entity.StorageEntity; | |
import com.example.demo.helper.upload.SimpleHelper; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import java.io.InputStream; | |
import java.lang.reflect.InvocationTargetException; | |
import java.util.HashMap; | |
import java.util.Map; | |
/** | |
* 上传工具抽象类 | |
*/ | |
public abstract class UploadHelper { | |
private static final Logger LOG = LoggerFactory.getLogger(UploadHelper.class); | |
private static final Map<String, String> helpers; | |
static { | |
helpers = new HashMap<>(); | |
helpers.put("simple", "com.example.demo.helper.upload.SimpleHelper"); | |
helpers.put("oss", "com.example.demo.helper.upload.OssHelper"); | |
helpers.put("cos", "com.example.demo.helper.upload.CosHelper"); | |
// TODO 可拓展其他上传实现类 | |
} | |
public static UploadHelper getInstance(String key) { | |
LOG.debug("{}:{}", key, helpers.get(key)); | |
try { | |
return (UploadHelper) Class.forName(helpers.get(key)).getConstructor().newInstance(); | |
} catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException | | |
InstantiationException | NoSuchMethodException | SecurityException | InvocationTargetException ex) { | |
LOG.error("没有找到合适的文件上传实现类", ex); | |
} | |
return new SimpleHelper(); | |
} | |
public abstract AttachmentEntity upload(StorageEntity storage, CatalogEntity catalog, | |
AttachmentEntity attachment, InputStream content) throws Exception; | |
} |
# 上传具体实现类
SimpleHelper
package com.example.demo.helper.upload; | |
import com.example.demo.entity.AttachmentEntity; | |
import com.example.demo.entity.CatalogEntity; | |
import com.example.demo.entity.StorageEntity; | |
import com.example.demo.helper.UploadHelper; | |
import org.apache.commons.io.FileUtils; | |
import org.apache.commons.io.IOUtils; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import java.io.File; | |
import java.io.InputStream; | |
/** | |
* 本地文件 | |
*/ | |
public class SimpleHelper extends UploadHelper { | |
public static final Logger LOG = LoggerFactory.getLogger(SimpleHelper.class); | |
@Override | |
public AttachmentEntity upload(StorageEntity storage, CatalogEntity catalog, AttachmentEntity attachment, InputStream content) throws Exception { | |
String path = storage.getService() + "/" + storage.getRoot() + "/" + catalog.getPath() + "/"; | |
LOG.debug("{}{}", path, attachment.getFile()); | |
File file = new File(path); | |
file.mkdirs(); | |
FileUtils.writeByteArrayToFile( | |
new File(path + attachment.getFile()), | |
IOUtils.toByteArray(content)); | |
return attachment; | |
} | |
} |
OssHelper
package com.example.demo.helper.upload; | |
import com.aliyun.oss.OSS; | |
import com.aliyun.oss.OSSClientBuilder; | |
import com.aliyun.oss.model.ObjectMetadata; | |
import com.example.demo.entity.AttachmentEntity; | |
import com.example.demo.entity.CatalogEntity; | |
import com.example.demo.entity.StorageEntity; | |
import com.example.demo.helper.UploadHelper; | |
import org.apache.commons.lang3.StringUtils; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import java.io.InputStream; | |
import java.io.UnsupportedEncodingException; | |
import java.net.URLEncoder; | |
/** | |
* 阿里云对象存储. | |
*/ | |
public class OssHelper extends UploadHelper { | |
public static final Logger LOG = LoggerFactory.getLogger(OssHelper.class); | |
@Override | |
public AttachmentEntity upload( | |
StorageEntity storage, CatalogEntity catalog, | |
AttachmentEntity attachment, InputStream content) | |
throws Exception { | |
OSS ossClient = new OSSClientBuilder().build( | |
storage.getService(), storage.getUsername(), storage.getPassword()); | |
ossClient.putObject( | |
storage.getRoot(), catalog.getPath() + "/" + attachment.getFile(), | |
content, | |
meta(attachment.getType(), attachment.getName())); | |
ossClient.shutdown(); | |
return attachment; | |
} | |
private ObjectMetadata meta() { | |
ObjectMetadata meta = new ObjectMetadata(); | |
//metadata.setContentLength(length); | |
meta.setCacheControl("no-cache"); | |
meta.setContentEncoding("UTF-8"); | |
return meta; | |
} | |
private ObjectMetadata meta(String type, String file) { | |
ObjectMetadata meta = meta(); | |
if (StringUtils.isNotBlank(type)) { | |
meta.setContentType(type); | |
} | |
if (StringUtils.isNotBlank(file)) { | |
try { | |
meta.setContentDisposition("attachment; filename=\"" + URLEncoder.encode(file, "UTF-8") + "\""); | |
} catch (UnsupportedEncodingException ex) { | |
} | |
} | |
return meta; | |
} | |
} |
CosHelper
package com.example.demo.helper.upload; | |
import com.example.demo.entity.AttachmentEntity; | |
import com.example.demo.entity.CatalogEntity; | |
import com.example.demo.entity.StorageEntity; | |
import com.example.demo.helper.UploadHelper; | |
import com.qcloud.cos.COSClient; | |
import com.qcloud.cos.ClientConfig; | |
import com.qcloud.cos.auth.BasicCOSCredentials; | |
import com.qcloud.cos.auth.COSCredentials; | |
import com.qcloud.cos.model.ObjectMetadata; | |
import com.qcloud.cos.region.Region; | |
import org.apache.commons.lang3.StringUtils; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.net.URLEncoder; | |
import java.nio.charset.StandardCharsets; | |
/** | |
* 腾讯云对象存储. | |
*/ | |
public class CosHelper extends UploadHelper { | |
public static final Logger LOG = LoggerFactory.getLogger(CosHelper.class); | |
@Override | |
public AttachmentEntity upload( | |
StorageEntity storage, CatalogEntity catalog, | |
AttachmentEntity attachment, InputStream content) | |
throws Exception { | |
// 1 初始化用户身份信息 (secretId, secretKey) | |
COSCredentials cred = new BasicCOSCredentials(storage.getUsername(), storage.getPassword()); | |
// 2 设置 bucket 的区域,COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224 | |
//clientConfig 中包含了设置 region, https (默认 http), 超时,代理等 set 方法,使用可参见源码或者接口文档 FAQ 中说明 | |
ClientConfig clientConfig = new ClientConfig(new Region("ap-shanghai")); | |
// 3 生成 cos 客户端 | |
COSClient cosClient = new COSClient(cred, clientConfig); | |
cosClient.putObject(storage.getRoot(), catalog.getPath() + "/" + attachment.getFile(), | |
content, | |
meta(attachment.getType(), attachment.getName(), content)); | |
return attachment; | |
} | |
private ObjectMetadata meta(InputStream content) { | |
ObjectMetadata meta = new ObjectMetadata(); | |
try { | |
meta.setContentLength(content.available()); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
meta.setCacheControl("no-cache"); | |
meta.setContentEncoding("UTF-8"); | |
return meta; | |
} | |
private ObjectMetadata meta(String type, String file, InputStream content) { | |
ObjectMetadata meta = meta(content); | |
if (StringUtils.isNotBlank(type)) { | |
meta.setContentType(type); | |
} | |
if (StringUtils.isNotBlank(file)) { | |
meta.setContentDisposition("attachment; filename=\"" + URLEncoder.encode(file, StandardCharsets.UTF_8) + "\""); | |
} | |
return meta; | |
} | |
} |
FtpHelper
package com.example.demo.helper.upload; | |
import com.example.demo.entity.AttachmentEntity; | |
import com.example.demo.entity.CatalogEntity; | |
import com.example.demo.entity.StorageEntity; | |
import com.example.demo.helper.UploadHelper; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import java.io.InputStream; | |
/** | |
* FTP. | |
*/ | |
public class FtpHelper extends UploadHelper { | |
private static final Logger LOG = LoggerFactory.getLogger(FtpHelper.class); | |
@Override | |
public AttachmentEntity upload(StorageEntity storage, CatalogEntity catalog, | |
AttachmentEntity attachment, InputStream content) { | |
throw new UnsupportedOperationException("Not supported yet."); | |
} | |
} |
其他上传实现类......
# 文件上传
FileController
package com.example.demo.controller; | |
import com.example.demo.dao.CatalogDao; | |
import com.example.demo.dao.StorageDao; | |
import com.example.demo.dto.Attach; | |
import com.example.demo.dto.UploadFileForm; | |
import com.example.demo.entity.AttachmentEntity; | |
import com.example.demo.entity.CatalogEntity; | |
import com.example.demo.entity.StorageEntity; | |
import com.example.demo.helper.UploadHelper; | |
import com.example.demo.service.AttachmentService; | |
import io.swagger.annotations.ApiOperation; | |
import org.apache.commons.lang3.StringUtils; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.http.MediaType; | |
import org.springframework.validation.annotation.Validated; | |
import org.springframework.web.bind.annotation.PostMapping; | |
import org.springframework.web.bind.annotation.RequestMapping; | |
import org.springframework.web.bind.annotation.RestController; | |
import org.springframework.web.multipart.MultipartFile; | |
import javax.validation.ValidationException; | |
@RequestMapping(value = "/file") | |
@RestController | |
public class FileController { | |
@Autowired | |
private CatalogDao catalogDao; | |
@Autowired | |
private StorageDao storageDao; | |
@Autowired | |
private AttachmentService attachmentService; | |
public static final Logger LOG = LoggerFactory.getLogger(FileController.class); | |
@ApiOperation(value = "上传附件(MultipartFile)", notes = "通过表单上传文件") | |
@PostMapping(value = "/uploadFile", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) | |
public Attach uploadFile(@Validated UploadFileForm uploadFile) { | |
LOG.info("开始进行文件上传:"); | |
MultipartFile file = uploadFile.getFile(); | |
// 文件的相关校验 | |
CatalogEntity catalog = validator(uploadFile.getCatalogCode(), uploadFile.getFile()); | |
// 存储空间 | |
StorageEntity storage = this.storageDao.findByCode(catalog.getStorage().getCode()); | |
// 保存文件上传记录 | |
AttachmentEntity attachment = this.attachmentService.upload(catalog, storage, file.getOriginalFilename(), | |
file.getOriginalFilename(), file.getContentType(), file.getSize()); | |
// 获取具体上传的实现 | |
UploadHelper uploadHelper = UploadHelper.getInstance(storage.getInstance()); | |
try { | |
// 文件上传 | |
uploadHelper.upload(storage, catalog, attachment, file.getInputStream()); | |
} catch (Exception e) { | |
LOG.error("上传文件出现问题", e); | |
} | |
LOG.info("文件上传结束:"); | |
return attachment.toAttach(); | |
} | |
/** | |
* 文件的相关校验 | |
*/ | |
private CatalogEntity validator(String catalogCode, MultipartFile file) { | |
CatalogEntity catalog = this.catalogDao.findByCode(catalogCode); | |
if (catalog == null) { | |
throw new ValidationException("文件目录不正确"); | |
} | |
if (catalog.getSize() < file.getSize()) { | |
throw new ValidationException("文件大小[" + file.getSize() + "]超过设置值"); | |
} | |
validatorByAccepts(catalog.getAccepts(), file.getContentType()); | |
return catalog; | |
} | |
/** | |
* 文件类型校验 | |
*/ | |
private void validatorByAccepts(String[] accepts, String type) { | |
if (accepts == null || accepts.length == 0) { | |
return; | |
} | |
for (String accept : accepts) { | |
if (StringUtils.equalsIgnoreCase(accept, type)) { | |
return; | |
} | |
} | |
throw new ValidationException("文件类型[" + type + "]不合法"); | |
} | |
} |
# 测试
使用 Apifox 或者 Postman 测试
调用接口:localhost:8080/file/uploadFile
传参:
file: demo.txt
catelogCode: FILE
返回接口
{ | |
"id": "10785fdc-8dad-420b-98ff-9c827fcadc50", | |
"name": "demo.txt", | |
"url": "E:/file/demo/file/b1aa9547-5b27-486f-8cdf-7744ac0ac8e3.txt" | |
} |
要想连接阿里云存储测试,需要在数据层更改请求地址以及请求的账号密码。