SpringBoot本地文件上传和oss文件上传

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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值