SpringBoot本地文件上传和oss文件上传+富文本编辑
一.本地上传
链接: springboot后端接收参数的几种方法
链接: 文件上传外部博客链接
链接: 文件上传外部博客链接
把用户的文件通过javaio流程复制到服务器的过程,称之为文件上传。
01.搭建一个springboot工程
02.准备一个页面文件上传的页面
- 后端 controller 的写法
package com.dailyblue.java.controller;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
@RestController
@RequestMapping("/upload")
public class UploadController {
@PostMapping
public String upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws Exception {
// file:上传文件
// 获取到 images 的具体路径
// String realPath = request.getRealPath("images");
String realPath = ResourceUtils.getURL("classpath:").getPath() + "/static/images";
System.out.println("上传的文件地址是:" + realPath);
// 服务器中对应的位置
// 产生唯一的文件名称
String fileName = UUID.getUUid();
// 获取到文件后缀
String fileType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
File src = new File(realPath, fileName + fileType);
// 将file文件传递到src去
file.transferTo(src);
return "images/" + fileName + fileType;
}
}
- 表单写法
<form action="upload" method="post" enctype="multipart/form-data">
<input type="file" name="file"/>
<button>上传</button>
</form>
- vue写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<img :src="'http://localhost:8081/'+img" v-show="flag"/>
<input type="file" @change="changeImg"/>
<button @click="upload">Vue 上传</button>
</div>
</body>
</html>
<script src="js/vue.min.js"></script>
<script src="js/axios.min.js"></script>
<script>
new Vue({
el: '#app',
data: {
file: null,
img: '',
flag: false
},
methods: {
changeImg(event) {
this.file = event.target.files[0];
},
upload() {
// 表单数据
let data = new FormData();
data.append('file', this.file);
// 定义发送格式
let type = {
headers: {
'Content-Type': 'multipart/form-data'
}
}
axios.post('http://localhost:8081/upload', data, type)
.then((response) => {
this.img = response.data;
this.flag = true;
});
}
}
});
</script>
03.实现后台的文件上传
实现上传文件的隔离功能,目录不一致!
<form action="/upload/file" method="post" enctype="multipart/form-data">
<input type="file" name="file"/>
<input type="dir" name="bbs"/>
<button>上传</button>
</form>
控制层代码:
@service
public class Uploadservice {
/**
*MultipartFile这个对象是springMvc提供的文件上传的接受的类,
*它的底层自动会去和HttpServletRequest request中的request.getInputstream()融合
*从而达到文件上传的效果。也就是告诉你一个道理:
*文件上传底层原理是:request.getInputstream()
@param multipartFile
@param dir
@return
**/
public string uploadImg(MultipartFile multipartFile,string dir){
// 1:指定文件上传的目录
File targetFile = new File("F: //tmp /" + dir);
try {
if(!targetFile.exists())
targetFile.mkdirs();
// 3:指定文件名
File targetFileName = new File(targetFile,"aaa.png")
// 2:文件上传到指定的目录
multipartFile.transferTo(targetFile);
return "ok ";
}catch (IOException e){
e.printstackTrace;
return "fail";
}
}
}
-
通过MultipartFile 我们很清楚的看到,文件已经被服务器接收。
-
但是会产生一个临时目录,这个目录是可以去配置
-
文件上传不会直接上传真是的目录,它一定要经过一个临时目录的中转以后,才会上传到真是目录。作用:
1.防止上传出现网络断开,或者用户上传直接刷新或者取消。因为如果用户的网络断开或者取消,就造成大量的垃圾文件。
2.保证真实目录上传的文件一定是有效的。 -
文件上传的大小:也可以进行配置的(文件上传的相关参数配置)
-
文件上传的类型:也是进行配置的
04.指定文件上传的目录
- 配置springboot静态资源服务,将上传的文件放入指定的目录中
@value("${file.uploadFolder}")
private string uploadFolder;
@value("${file.staticPath}")
private string staticPath;
public string uploadImg(MultipartFile multipartFile,string dir) {
try {
String realfilename = multipartFile.getoriginalFilename();
//2∶截图文件名的后缀
String imgSuffix = realfilename.substring(realfilename.lastIndexOf( str: "."));
//3:生成的唯一的文件名:能不能用中文名:不能因为统一用英文命名。
String newFileName = UUID.randomUuID().tostring()+imgSuffix;
//4:日期目录
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
String datePath = dateFormat.format(new Date());
//5:指定文件上传以后的目录
String servrepath = uploadFolder;
File targetPath = new File( servrepath +dir , datePath);
if(!targetPath.exists())
targetPath.mkdirs();
//6∶指定文件上传以后的服务器的完整的文件名
File targetFileName = new File(targetPath , newFileName) ;
// 7:文件上传到指定的目录
multipartFile.transferTo(targetFileName) ;
String filename = dir+"/"+dataPath+"/"+newFileName;
// 8.返回完整的访问路径
return staticPath+"/upimages/"+filename;
}catch (IOException e) {
e.printstackTrace();return "fail";
}
05.通过http请求服务资源
- springboot如果去指定任意目录作为的资源的访问目录?
springboot有一个日录: statici这个日录其实就是资源日录,这个日录下面的文件是可以通过htp直接问题的。但是程序话一般打成jar包,我们没办法去文性写入到这个static下,所以springboot提供静态资源目录的额外的映射机制,就是静态资源服务映射。它就类似于:nginx的静态资源服务映射。
@Configuration
public class webMvcCongfiguration implements webMvcConfigurer {
//这个就是springboot中springMvc让程序开发者去配置文件上传的额外的静态资源服务的配置
@override
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/uploadimg/**") . addResourceLocations("file:F://tmp//");//前面的(file:)不能少
}
}
核心代码分析:
registry.addResourceHandler("访问的路径").addResourceLocations("上传资源的路径");
环境隔离配置:
application-dev.yaml
# 本机配置
file:
staticPath: http://localhost:8777
staticPatternPath: /upimages/**
uploadFolder: F:/tmp/
application-prod.yaml
# 本机配置
file:
staticPath: https://域名或者ip地址:8777
staticPatternPath: /upimages/**
uploadFolder: www/upload/
application.yml
server:
port:8777
spring:
faeemarker:
suffix: .html
cache: false
profiles:
# 切换环境
active: dev
servlet:
multipart:
enabled: true
# 是单个文件大小默认1M 10KB
max-file-size: 2MB
#是设置总上传的数据大小
max-request-size: 10MB
#当文件达到多少时进行磁盘写入
file-size-threshold:20MB
#设置临时目录
location: F://data//tempxxxxxxxx
http://localhost:端口号/staticPatternPath/图片地址路径.png
自己在浏览器访问即可!!!
06.对文件上传的思考和优化控制
- 正常返回一个Map对象,put进入文件的各种信息。
pubilc Map<String,Object> 方法名(MultipartFile multpartFile,String dir){
.....................
map.put("rpath",dir+"/"datePath+"/"+newFileName);
.........................
return map;
- 想要上传文件夹去研究FTP协议
二.OSS文件存储
02.
03.创建Bucket文件存储桶
- Bucket相当于本地存储的文件夹
1.创建Bucket列表
2.创建好后找到SDK下载
3.
4.
导入依赖:
5.导入oss的sdk依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.0</version>
</dependency>
- 具体进入文档查询
定义OssUplaodService对接文件上传
实现简单上传文件:
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "yourAccessKeyId";
String accessKeySecret = "yourAccessKeySecret";
// 填写Bucket名称,例如examplebucket。
String bucketName = "examplebucket";
// 填写Object完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
String objectName = "exampledir/exampleobject.txt";
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
String content = "Hello OSS";
ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
填写对应参数:
代码展示:
本地文件上传测试
package com.tian.service;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.CannedAccessControlList;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
public class OSSservice {
public static void main(String[] args) {
String uploadfile = uploadfile(new File("e://1.txt"));
System.out.println(uploadfile);
}
public static String uploadfile(File multipartFile){
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
String endpoint = "oss-cn-beijing.aliyuncs.com";
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "LTAI5tABrZYxNYybmLhQx5ng";
String accessKeySecret = "zGzSWHp4GWUT048gt6MQQMbnUV2dvA";
// 填写Bucket名称,例如examplebucket。
String bucketName = "atian-123";
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
//如果桶不存在,创建桶。
if(!ossClient.doesBucketExist(bucketName)){
//创建桶
ossClient.createBucket(bucketName);
//设置oss实例的访问权限:公共读
ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
}
//2.获取文件上传的流
InputStream inputStream = new FileInputStream(multipartFile);
//3.构建日期目录
SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy/MM/dd");
String datePath = dateFormat.format(new Date());
//4.获取文件名
String originalFilename = multipartFile.getName();
String filename = UUID.randomUUID().toString();//生成文件名
String substring = originalFilename.substring(originalFilename.lastIndexOf("."));//截取出后缀名
String newName = filename + substring;//拼接
String fileUrl = datePath+"/"+newName;//完整的目录
//5.文件上传到阿里云服务器
ossClient.putObject(bucketName,fileUrl,inputStream);
//6.返回文件的访问路径
return "https://"+bucketName+"."+endpoint +"/"+fileUrl;
//https://atian-123.oss-cn-beijing.aliyuncs.com/2022/08/11/dfab1c62-8b2f-42e8-baa2-8ca18333a681.txt
//成功返回
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
return "fail";
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
return "fail";
} catch (Exception e) {
System.out.println("获取文件流对象失败!!");
return "fail";
}finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
正常代码:
//-------------------------------------------------------------------------------------------------------------------
package com.tian.service;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.CannedAccessControlList;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
public class OSSservice {
public String uploadfile(MultipartFile multipartFile){
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
String endpoint = "oss-cn-beijing.aliyuncs.com";
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "LTAI5tABrZYxNYybmLhQx5ng";
String accessKeySecret = "zGzSWHp4GWUT048gt6MQQMbnUV2dvA";
// 填写Bucket名称,例如examplebucket。
String bucketName = "atian-123";
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
//如果桶不存在,创建桶。
if(!ossClient.doesBucketExist(bucketName)){
//创建桶
ossClient.createBucket(bucketName);
//设置oss实例的访问权限:公共读
ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
}
//2.获取文件上传的流
InputStream inputStream = multipartFile.getInputStream();
//3.构建日期目录
SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy/MM/dd");
String datePath = dateFormat.format(new Date());
//4.获取文件名
String originalFilename = multipartFile.getOriginalFilename();
String filename = UUID.randomUUID().toString();//生成文件名
String substring = originalFilename.substring(originalFilename.lastIndexOf("."));//截取出后缀名
String newName = filename + substring;//拼接
String fileUrl = datePath+"/"+newName;//完整的目录
//5.文件上传到阿里云服务器
ossClient.putObject(bucketName,fileUrl,inputStream);
//6.返回文件的访问路径
return "https://"+bucketName+"."+endpoint +"/"+fileUrl;
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
return "fail";
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
return "fail";
} catch (Exception e) {
System.out.println("获取文件流对象失败!!");
return "fail";
}finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
静态资源访问问题:
三.富文本(wangEditor)
https://blog.csdn.net/weixin_44258964/article/details/103213167