网站上传图片、文件等,最常见的就是直接上传到效劳器的webapp目录下,或许直接上传效劳的一个指定的文件夹下面。这类体式格局关于简朴的单机运用确实是很轻易、简朴,涌现的题目也会比较少。然则关于分布式项目,直接上传到项目途径的体式格局显然是不可靠的,而且跟着业务量的增添,文件也会增添,对效劳器的压力天然就增添了。这里简朴的引见本身所相识的几种体式格局保留文件。
- 直接上传到指定的效劳器途径;
- 上传到第三方内容存储器,这里引见将图片保留到七牛云
- 本身搭建文件存储效劳器,如:FastDFS
最简朴的上传
起首申明,该项目组织是SpringBoot+mybatis。由于项目运用jar情势打包,所以这里将图片保留到一个指定的目录下。<!–more–>
增加WebAppConfig设置类
@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter{
/**
* 在设置文件中设置的文件保留途径
*/
@Value("${img.location}")
private String location;
@Bean
public MultipartConfigElement multipartConfigElement(){
MultipartConfigFactory factory = new MultipartConfigFactory();
//文件最大KB,MB
factory.setMaxFileSize("2MB");
//设置总上传数据总大小
factory.setMaxRequestSize("10MB");
return factory.createMultipartConfig();
}
}
文件上传的要领,这个要领有些参数能够须要做简朴的修正,大抵就是文件先做文件保留途径的处置惩罚,然后保留文件到该途径,末了返回文件上传信息
@PutMapping("/article/img/upload")
public MarkDVo uploadImg(@RequestParam("editormd-image-file") MultipartFile multipartFile) {
if (multipartFile.isEmpty() || StringUtils.isBlank(multipartFile.getOriginalFilename())) {
throw new BusinessException(ResultEnum.IMG_NOT_EMPTY);
}
String contentType = multipartFile.getContentType();
if (!contentType.contains("")) {
throw new BusinessException(ResultEnum.IMG_FORMAT_ERROR);
}
String root_fileName = multipartFile.getOriginalFilename();
logger.info("上传图片:name={},type={}", root_fileName, contentType);
//处置惩罚图片
User currentUser = userService.getCurrentUser();
//猎取途径
String return_path = ImageUtil.getFilePath(currentUser);
String filePath = location + return_path;
logger.info("图片保留途径={}", filePath);
String file_name = null;
try {
file_name = ImageUtil.saveImg(multipartFile, filePath);
MarkDVo markDVo = new MarkDVo();
markDVo.setSuccess(0);
if(StringUtils.isNotBlank(file_name)){
markDVo.setSuccess(1);
markDVo.setMessage("上传胜利");
markDVo.setUrl(return_path+File.separator+file_name);
markDVo.setCallback(callback);
}
logger.info("返回值:{}",markDVo);
return markDVo;
} catch (IOException e) {
throw new BusinessException(ResultEnum.SAVE_IMG_ERROE);
}
}
文件保留类
/**
* 保留文件,直接以multipartFile情势
* @param multipartFile
* @param path 文件保留绝对途径
* @return 返回文件名
* @throws IOException
*/
public static String saveImg(MultipartFile multipartFile,String path) throws IOException {
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
FileInputStream fileInputStream = (FileInputStream) multipartFile.getInputStream();
String fileName = Constants.getUUID() + ".png";
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path + File.separator + fileName));
byte[] bs = new byte[1024];
int len;
while ((len = fileInputStream.read(bs)) != -1) {
bos.write(bs, 0, len);
}
bos.flush();
bos.close();
return fileName;
}
设置文件保留途径
测试:直接运用postman上传
下面须要接见预览该上传的图片
在设置文件中增加对静态资本的设置。SpringBoot对静态的的处置惩罚,Springboot 之 静态资本途径设置
然后在浏览器链接栏输入:此处应当疏忽图片
上传到七牛云
这里起首要在七牛云中注册一个账号,并开通对象存储空间,免费用户有10G的存储空间。教程:http://jiantuku.com/help/faq.html?src=settings_head
然后在本身的项目中搭建环境:运用maven导包
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>[7.2.0, 7.2.99]</version>
</dependency>
然后再适才找到适才建立密钥,复制出来保留保留在项目资本文件中
这里的bucket就是上面的存储空间称号,然后path是域名。
上传东西类:
@Component
public class QiniuUtil{
private static final Logger logger = LoggerFactory.getLogger(QiniuUtil.class);
@Value("${qiniu.accessKey}")
private String accessKey;
@Value("${qiniu.secretKey}")
private String secretKey;
@Value("${qiniu.bucket}")
private String bucket;
@Value("${qiniu.path}")
private String path;
/**
* 将图片上传到七牛云
* @param file
* @param key 保留在空间中的名字,假如为空会运用文件的hash值为文件名
* @return
*/
public String uploadImg(FileInputStream file, String key) {
//组织一个带指定Zone对象的设置类
Configuration cfg = new Configuration(Zone.zone1());
//...其他参数参考类解释
UploadManager uploadManager = new UploadManager(cfg);
//...天生上传凭据,然后预备上传
// String bucket = "oy09glbzm.bkt.clouddn.com";
//默许不指定key的情况下,以文件内容的hash值作为文件名
try {
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(bucket);
try {
Response response = uploadManager.put(file, key, upToken, null, null);
//剖析上传胜利的效果
DefaultPutRet putRet = JSON.parseObject(response.bodyString(), DefaultPutRet.class);
// DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
// System.out.println(putRet.key);
// System.out.println(putRet.hash);
String return_path = path+"/"+putRet.key;
logger.info("保留地点={}",return_path);
return return_path;
} catch (QiniuException ex) {
Response r = ex.response;
System.err.println(r.toString());
try {
System.err.println(r.bodyString());
} catch (QiniuException ex2) {
//ignore
}
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}
上传接口要领
/**
* 上传文件到七牛云存储
* @param multipartFile
* @return
* @throws IOException
*/
@PutMapping("/article/img/qiniu")
public String uploadImgQiniu(@RequestParam("editormd-image-file") MultipartFile multipartFile) throws IOException {
FileInputStream inputStream = (FileInputStream) multipartFile.getInputStream();
User currentUser = userService.getCurrentUser();
String path = qiniuUtil.uploadImg(inputStream, currentUser.getUsername()+"_"+Constants.getUUID());
return path;
}
测试
上传文件到FastDFS
起首须要搭建FastDFS效劳器,这里就不引见了。传送门:Linux下FastDFS体系的搭建
依靠
<!--FastDFS存储图片 start-->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.25.4-RELEASE</version>
</dependency>
<!--FastDFS存储图片 end-->
增加设置信息
FastDFS设置类
@Configuration
@ComponentScan(value = "com.github.tobato.fastdfs.service")
@Import(FdfsClientConfig.class)
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FastDfsConfig {
}
这里关于FastDFS文件的操纵只处置惩罚上传,上传文件类:
@Autowired
private FastFileStorageClient storageClient;
@Autowired
private FdfsWebServer fdfsWebServer;
@PutMapping("/article/img/fdfs")
public String uploadImgfdfs(@RequestParam(value = "editormd-image-file") MultipartFile multipartFile) throws IOException {
StorePath storePath= storageClient.uploadFile(multipartFile.getInputStream(), multipartFile.getSize(), "png", null);
String path = storePath.getFullPath();
logger.info("保留途径={}",path);
return path;
}
测试:
参考: