【全栈】SprintBoot+vue3迷你商城(12)

【全栈】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迷你商城(7)

【全栈】SprintBoot+vue3迷你商城(8)

【全栈】SprintBoot+vue3迷你商城(9)

【全栈】SprintBoot+vue3迷你商城(10)

细节解析部分:

【全栈】SprintBoot+vue3迷你商城-细节解析(1):Token、Jwt令牌、Redis、ThreadLocal变量

【全栈】SprintBoot+vue3迷你商城-细节解析(2):分页

补充部分:

【全栈】SprintBoot+vue3迷你商城(11)

上期我们完善了分页相关的内容,本期我们将完善商家添加商品的内容,因为我们之前开发的这个接口商品图片传的只是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中。

相关推荐
萧瑟余晖11 小时前
JDK 26 新特性详解
java·开发语言
马优晨12 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
维天说14 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json
Zane199415 小时前
并发 vs 并行:别再傻傻分不清了,一文讲透 Java 并发编程的第一课
java·后端
sugar__salt16 小时前
Vue3 表单双向绑定与响应式核心 API 技术详解
前端·javascript·vue.js
噢,我明白了16 小时前
java中Excel的导入和导出(EasyExcel)
java·开发语言·excel
郝亚军16 小时前
使用Vue 3和Nginx打包和部署Vue.js项目的一般步骤
前端·vue.js·nginx
吠品16 小时前
Zabbix Web界面误报Server未运行的排查与解决
java·服务器·数据库
啊湘16 小时前
天气查询API接口 按月Token鉴权 实时天气 物联网可用 文档齐全
java·后端·struts
Java内核笔记16 小时前
告别十亿美元的错误 : Spring Boot 4 空安全 (JSpecify) 实战
java·spring boot·后端