【全栈】SprintBoot+vue3迷你商城(12)
往期的文章都在这里啦,大家有兴趣可以看一下
后端部分:
【全栈】SprintBoot+vue3迷你商城(1)
【全栈】SprintBoot+vue3迷你商城(2)
【全栈】SprintBoot+vue3迷你商城-扩展:利用python爬虫爬取商品数据
【全栈】SprintBoot+vue3迷你商城(3)
【全栈】SprintBoot+vue3迷你商城(4)
【全栈】SprintBoot+vue3迷你商城(5)
【全栈】SprintBoot+vue3迷你商城(6)
前端部分:
【全栈】SprintBoot+vue3迷你商城-扩展:vue的基本用法
【全栈】SprintBoot+vue3迷你商城-扩展:vue3项目创建及目录介绍
细节解析部分:
【全栈】SprintBoot+vue3迷你商城-细节解析(1):Token、Jwt令牌、Redis、ThreadLocal变量
【全栈】SprintBoot+vue3迷你商城-细节解析(2):分页
补充部分:
上期我们完善了分页相关的内容,本期我们将完善商家添加商品的内容,因为我们之前开发的这个接口商品图片传的只是URL,本期我们将通过上传图片的方式直接来上传商品图片并利用阿里云的对象储存OSS来储存上传的商品图片。
1.完善连接阿里云OSS的工具类
这一步可以参考官方文档:OSS Java SDK
首先得安装依赖:
xml
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.17.4</version>
</dependency>
<!-- 以下是Java9以上需要添加的额外依赖-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
</dependency>
以下是官网代码,可以根据其进行修改,完善自身的工具类
java
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.CreateBucketRequest;
import com.aliyun.oss.model.DataRedundancyType;
import com.aliyun.oss.model.StorageClass;
public class CreateBucket {
public static void main(String[] args) throws Exception {
// yourEndpoint填写Bucket所在地域对应的Endpoint。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填写Bucket名称。
String bucketName = "examplebucket";
// 填写资源组ID。如果不填写资源组ID,则创建的Bucket属于默认资源组。
//String rsId = "rg-aek27tc****";
// 填写Bucket所在地域。以华东1(杭州)为例,Region填写为cn-hangzhou。
String region = "cn-hangzhou";
// 创建OSSClient实例。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
// 创建CreateBucketRequest对象。
CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
// 如果创建存储空间的同时需要指定存储类型、存储空间的读写权限、数据容灾类型, 请参考如下代码。
// 此处以设置存储空间的存储类型为标准存储为例介绍。
//createBucketRequest.setStorageClass(StorageClass.Standard);
// 数据容灾类型默认为本地冗余存储,即DataRedundancyType.LRS。如果需要设置数据容灾类型为同城冗余存储,请设置为DataRedundancyType.ZRS。
//createBucketRequest.setDataRedundancyType(DataRedundancyType.ZRS);
// 设置存储空间读写权限为公共读,默认为私有。
//createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
// 在支持资源组的地域创建Bucket时,您可以为Bucket配置资源组。
//createBucketRequest.setResourceGroupId(rsId);
// 创建存储空间。
ossClient.createBucket(createBucketRequest);
} 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();
}
}
}
}
2.写后端接口
我们上传的图片属于文件,所以我们搞一个post请求的接口来接收文件,然后利用完善好的工具类上传到阿里云OSS中去就行了
java
package com.janium.minimallbe.controller;
import com.janium.minimallbe.pojo.Result;
import com.janium.minimallbe.utils.AliOssUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.util.UUID;
@RestController
public class FileUploadController {
@PostMapping("/upload")
public Result upload(@RequestParam("file") MultipartFile file) throws Exception {
String filename = UUID.randomUUID().toString()+file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
String url= AliOssUtil.uploadFile(filename,file.getInputStream());
return Result.success(url);
}
}
3.前端页面搭建与函数绑定
我们首先需要从Element Plus中找到上传图片的组件:
vue
<template>
<el-upload
class="avatar-uploader"
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
>
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
</el-upload>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import type { UploadProps } from 'element-plus'
const imageUrl = ref('')
const handleAvatarSuccess: UploadProps['onSuccess'] = (
response,
uploadFile
) => {
imageUrl.value = URL.createObjectURL(uploadFile.raw!)
}
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
if (rawFile.type !== 'image/jpeg') {
ElMessage.error('Avatar picture must be JPG format!')
return false
} else if (rawFile.size / 1024 / 1024 > 2) {
ElMessage.error('Avatar picture size can not exceed 2MB!')
return false
}
return true
}
</script>
<style scoped>
.avatar-uploader .avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
<style>
.avatar-uploader .el-upload {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: var(--el-transition-duration-fast);
}
.avatar-uploader .el-upload:hover {
border-color: var(--el-color-primary);
}
.el-icon.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
text-align: center;
}
</style>
然后略作修改,绑定自己定的函数与后端的接口:
vue
<script>
import { useUserInfoStore } from '@/stores/userInfo';
const userInfoStore = useUserInfoStore();
const userInfoModel = ref(userInfoStore.info)
const goodsAddModel = ref({
goodsName: '',
goodsImgUrl: '',
goodsPrice: ''
})
const uploadSuccess=(result)=>{
goodsAddModel.value.goodsImgUrl=result.data;
}
</script>
<template>
<el-upload class="avatar-uploader" :auto-upload="true" :show-file-list="false"
action="/api/upload"
name="file"
:headers="{'authorization':tokenStore.token}"
:on-success="uploadSuccess"
>
<img v-if="goodsAddModel.goodsImgUrl" :src="goodsAddModel.goodsImgUrl" class="avatar" />
<el-icon v-else class="avatar-uploader-icon">
<Plus />
</el-icon>
</el-upload>
</template>
这样,后端部分也便完成了。
4.效果

5.总结
本期我们对添加商品的接口进行了完善,我们可以通过上传图片的方式直接添加商品图片,并存储在阿里云OSS中。