【方案】图片上传

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_42322103/article/details/98170833

最近在模仿学习做一个企业级的项目,很想感受一下一个大而完整的项目是什么样子的。在学习的过程中图片上传的处理让我涨了见识,这里记录一下。

前端部分

前端部分使用的是element-ui , 发现“上传”组件超级好用:: http://element-ui.cn/#/zh-CN/component/upload
相关的参数 文档介绍的很详细 基本上直接可以拿来使用它

下面的是使用的时候的实例可以参考一下,因为涉及到了与后端的交互,而不是纯UI

核心代码(html)

	<el-form-item label="品牌图片">
		<el-upload
			class="avatar-uploader"
			action="/upload/native.do"
			:show-file-list="false"
			:on-success="handleAvatarSuccess"
			:before-upload="beforeAvatarUpload">
			<img v-if="imageUrl" :src="imageUrl" class="avatar">
			<i v-else class="el-icon-plus avatar-uploader-icon"></i>
		</el-upload>
	</el-form-item>	

参数: imageUrl:’’
样式:

	<style>
			.avatar-uploader .el-upload {
				border: 1px dashed #d9d9d9;
				border-radius: 6px;
				cursor: pointer;
				position: relative;
				overflow: hidden;
			}
			.avatar-uploader .el-upload:hover {
				border-color: #409EFF;
			}
			.avatar-uploader-icon {
				font-size: 28px;
				color: #8c939d;
				width: 178px;
				height: 178px;
				line-height: 178px;
				text-align: center;
			}
			.avatar {
				width: 178px;
				height: 178px;
				display: block;
			}
		</style>

核心部分(与后端交互)

	handleAvatarSuccess(res, file) {
						this.imageUrl = file.response; //返回文件的具体物理地址
				},
				beforeAvatarUpload(file) {
						const isJPG = file.type === 'image/jpeg';
						const isLt2M = file.size / 1024 / 1024 < 2;

						if (!isJPG) {
							this.$message.error('上传头像图片只能是 JPG 格式!');
						}
						if (!isLt2M) {
							this.$message.error('上传头像图片大小不能超过 2MB!');
						}
						return isJPG && isLt2M;
				}
			}

后端部分

SpringMVC接收图片上传

SpringMVC中,文件的上传,是通过MultipartResolver实现的。所以,如果要实现文件的上传,只要在spring-mvc.xml中注册相应的MultipartResolver即可。
MultipartResolver的实现类有两个:

  1. CommonsMultipartResolver
  2. StandardServletMultipartResolver

两个的区别:

  1. 第一个需要使用Apache的commons-fileupload等jar包支持,但它能在比较旧的servlet版本中使用。
  2. 第二个不需要第三方jar包支持,它使用servlet内置的上传功能,但是只能在Servlet3以上的版本使用。

目前第一种方式使用的是比较多。

相关依赖
application-json.xml (配置fastjson等信息)

<!-- 多部分文件上传 -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="maxUploadSize" value="104857600" />
		<property name="maxInMemorySize" value="4096" />
		<property name="defaultEncoding" value="UTF-8"></property>
	</bean>

pom.xml

    <!--文件上传-->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
        </dependency>

maxUploadSize:设置允许上传的最大文件大小,以字节为单位计算。当设为-1时表示无限制,默认是-1。

defaultEncoding:表示用来解析request请求的默认编码格式,当没有指定的时候根据Servlet规范会使用默认值ISO-8859-1。当request自己指明了它的编码格式的时候就会忽略这里指定的defaultEncoding。

后端代码

package com.qingcheng.controller.file;

import org.springframework.beans.factory.annotation.Autowired;
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 {
    @Autowired
    private HttpServletRequest request;  //获取servlet的路径 直接无法获取

    //MultipartFile文件的二进制内容
    @PostMapping("/native")
    public String nativeUpload(@RequestParam("file") MultipartFile file){
        String path = request.getSession().getServletContext().getRealPath("img"); //获取路径下的img目录
        String filePath = path+"/"+file.getOriginalFilename();  //目录加文件名
        File desFile = new File(filePath);
        if(!desFile.getParentFile().exists()){ //上级目录是否存在
            desFile.mkdirs();
        }
        try {
            file.transferTo(desFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "http://localhost:9101/img/"+file.getOriginalFilename();
    }
}

效果:
在这里插入图片描述
在这里插入图片描述

记录

长见识的地方在这里,就是 云存储解决方案-阿里云OSS

阿里云对象存储服务(Object Storage Service,简称OSS)提供基于网络的数据存取服务。使用OSS,可以通过网络随时存储和调用包括文本、图片、音频和视频等在内的各种非结构化数据文件。

阿里云OSS将数据文件以对象(object)的形式上传到存储空间(bucket)中。

可以进行以下操作:

  • 创建一个或者多个存储空间,向每个存储空间中添加一个或多个文件。
  • 通过获取已上传文件的地址进行文件的分享和下载。
  • 通过修改存储空间或文件的属性或元信息来设置相应的访问权限。
  • 在阿里云管理控制台执行基本和高级OSS任务。
  • 使用阿里云开发工具包或直接在应用程序中进行RESTfulAPI调用执行基本和高级OSS任务

重要的来说,虽然没有学生优惠!!!但是对于我这种用户还是非常非常非常便宜的:
https://www.aliyun.com/product/oss?spm=5176.12825654.eofdhaal5.81.247b2c4atp1TcJ

感觉一块钱就够我用很久很久了
在这里插入图片描述
后台还是非常友好的
在这里插入图片描述
文档也是很OK https://help.aliyun.com/document_detail/31817.html?spm=a2c4g.11174283.2.2.494c7da2dX9ytJ

提供了非常完备的方案,这或许就是大厂吧
在这里插入图片描述
官网提供的依赖

<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.5.0</version>
</dependency>

在文档中的“简单上传”区域有详细的上传操作的描述 我这里复制的是上传文件流

// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";

// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

// 上传文件流。
InputStream inputStream = new FileInputStream("<yourlocalFile>");
ossClient.putObject("<yourBucketName>", "<yourObjectName>", inputStream);


// 关闭OSSClient。
ossClient.shutdown();				

endpoint 可以在管理后台 找到
在这里插入图片描述
accessKeyId 和 accessKeySecret的获取:

因为我是注册没多久 需要自己创建一下
在这里插入图片描述
在这里插入图片描述
yourBucketName 就是刚才创建的Bucket
yourObjectName 就是上传文件名

如果和spring结合一起的话 这么大的一段代码可以配置成spring的bean

application-json.xml

	<!--阿里云OSS  -->
	<bean id="ossClient" class="com.aliyun.oss.OSSClient">
		<constructor-arg index="0" value="oss-cn-qingdao.aliyuncs.com"></constructor-arg>
		<constructor-arg index="1" value="AccessKeyID"></constructor-arg>
		<constructor-arg index="2" value="AccessKeySecret"></constructor-arg>
	</bean>

需要的时候直接使用即可 类似这样

   @Autowired
    private OSSClient ossClient;
    @PostMapping("/oss")
    public String ossUpload(@RequestParam("file") MultipartFile file){
        String bucketName = "qingcheng-ecp";
        String fileName = file.getOriginalFilename();
        try {
            ossClient.putObject(bucketName,fileName,file.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "https://"+bucketName+".oss-cn-qingdao.aliyuncs.com/"+fileName;
    }

注意这段代码是有问题的,如果上传的文件重名的话 会引起冲突的
改进很简单,可以用时间啥的,我这里使用了UUID

     String fileName = UUID.randomUUID()+file.getOriginalFilename();

另外的一个问题就是 分类管理,所有的东西都放在一起,那东西多了很难进行管理 所以可以现在阿里云OSS管理后台创建一个目录,在自己的后端代码加上即可

floder是由前端传递过来的哈 这样更灵活些

@Autowired
    private OSSClient ossClient;
    @PostMapping("/oss")
    public String ossUpload(@RequestParam("file") MultipartFile file,String folder){
        String bucketName = "qingcheng-ecp";
        String fileName = folder+"/"+UUID.randomUUID()+file.getOriginalFilename();
        try {
            ossClient.putObject(bucketName,fileName,file.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "https://"+bucketName+".oss-cn-qingdao.aliyuncs.com/"+fileName;
    }

在这里插入图片描述
阿里云OSS后台
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42322103/article/details/98170833
今日推荐