java springboot+vue实现图片上传阿里云OSS

记录springboot+vue实现图片上传OSS功能

  • 阿里云OSS

  • springboot实现图片上传

  • vue实现程序头像上传的功能

阿里云OSS

开通

登录注册

阿里云-上云就上阿里云阿里云——阿里巴巴集团旗下公司,是全球领先的云计算及人工智能科技公司。提供免费试用、云服务器、云数据库、云安全、云企业应用等云计算服务,以及大数据、人工智能服务、精准定制基于场景的行业解决方案。免费备案,7x24小时售后支持,助企业无忧上云。https://www.aliyun.com/搜索OSS 选择对象存储OSS

选择开通 这个是按照流量计费的

 创建 Bucket

 

获取AccessKey ID 和 AccessKey Secret 备用

 

 创建springboot 工程项目 service-oss

 创建配置文件 application.properties

#服务端口
server.port=8002
#服务名
spring.application.name=service-oss

#环境设置:dev、test、prod
spring.profiles.active=dev

#阿里云 OSS
#不同的服务器,地址不同
aliyun.oss.file.endpoint=oss-cn-beijing.aliyuncs.com
aliyun.oss.file.keyid=LTAIXu4ab7KQym
aliyun.oss.file.keysecret=jTah9kfhqJcjVrJY1MCxJWMUgZK
#bucket可以在控制台创建,也可以使用java代码创建
aliyun.oss.file.bucketname=在阿里云创建的Bucket 名称

 pom.xml文件引入依赖


        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.10.2</version>
        </dependency>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
        </dependency>

 创建启动类 OssApplication

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@ComponentScan(basePackages = {"com.education"})
public class OssApplication {
    public static void main(String[] args) {
        SpringApplication.run(OssApplication.class, args);
    }
}

创建util文件夹下创建常量类ConstantPropertiesUtil  读取配置文件

package com.education.oss.util;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * @Author: Gosin
 * @Date: 2022/2/16 14:47
 * 读取配置文件的值
 */
@Component
public class ConstantPropertiesUtil implements InitializingBean {

    //读取配置文件的内容
    @Value("${aliyun.oss.file.endpoint}")
    private String endpoint;
    @Value("${aliyun.oss.file.keyid}")
    private String keyId;
    @Value("${aliyun.oss.file.keysecret}")
    private String keySecret;
    @Value("${aliyun.oss.file.bucketname}")
    private String bucketname;

    //静态常量
    public static String END_POINT;
    public static String ACCESS_KEY_ID;
    public static String ACCESS_KEY_SECRET;
    public static String BUCKET_NAME;

    @Override
    public void afterPropertiesSet() throws Exception {
        END_POINT = endpoint;
        ACCESS_KEY_ID = keyId;
        ACCESS_KEY_SECRET = keySecret;
        BUCKET_NAME = bucketname;
    }
}

 创建controller文件夹 并创建OssController 类

@RestController//交给spring管理 返回数据
@RequestMapping("eduoss")
@CrossOrigin//跨域
public class OssController {

    @Autowired
    private OssService ossService;

    //上传头像的方法
    @ApiOperation(value = "文件上传")
    @PostMapping(("upload"))
    public R uploadOssFile(MultipartFile file){
        //获取上传文件 MultipartFile
        String url = ossService.upload(file);
        return R.ok().data("url",url);
    }
}

创建service文件夹 并创建OssService方法和impl文件夹

public interface OssService {
    String upload(MultipartFile file);
}

impl文件夹下创建OssServiceImpl 类

@Service
public class OssServiceImpl implements OssService {
    @Override
    public String upload(MultipartFile file) {
        String url = null;
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = ConstantPropertiesUtil.END_POINT;
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = ConstantPropertiesUtil.ACCESS_KEY_ID;
        String accessKeySecret = ConstantPropertiesUtil.ACCESS_KEY_SECRET;
        // 填写Bucket名称,例如examplebucket。
        String bucketName = ConstantPropertiesUtil.BUCKET_NAME;
        // 填写Object完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
//        String objectName = "exampledir/exampleobject.txt";
        // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
        // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
//        String filePath= "D:\\localpath\\examplefile.txt";

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            InputStream inputStream = file.getInputStream();
            String fileName = file.getOriginalFilename();


            //1.随机唯一值 防止文件名重复
            String uuid = UUID.randomUUID().toString().replaceAll("-","");
            fileName = uuid+fileName;

            //2.通过时间格式创建文件路径 保存文件
            String datapath = new DateTime().toString("yyyy/MM/dd");
            fileName = datapath+"/"+fileName;
            // 创建PutObject请求。
            ossClient.putObject(bucketName, fileName, inputStream);
            url = "http://"+bucketName+"."+endpoint+"/"+fileName;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        return url;
    }
}

前端整合图片上传组件 只提供上传图片部分代码片段

从模板中复制组件ImageCropper文件夹和PanThumb文件夹到components文件夹下

添加文件上传组件

     <!-- 讲师头像 -->
<el-form-item label="讲师头像">

    <!-- 头衔缩略图 -->
    <pan-thumb :image="teacher.avatar"/>
    <!-- 文件上传按钮 -->
    <el-button type="primary" icon="el-icon-upload" @click="imagecropperShow=true">更换头像
    </el-button>

    <!--
v-show:是否显示上传组件
:key:类似于id,如果一个页面多个图片上传控件,可以做区分
:url:后台上传的url地址
@close:关闭上传组件
@crop-upload-success:上传成功后的回调 -->
    <image-cropper
                   v-show="imagecropperShow"
                   :width="300"
                   :height="300"
                   :key="imagecropperKey"
                   :url="BASE_API+'/eduoss/upload/'"//java程序中上传图片的方法路径
                   field="file"
                   @close="close"
                   @crop-upload-success="cropSuccess"/>

</el-form-item>


使用组件 在data(){}中定义变量和初始值

 // 保存按钮是否禁用,
      saveBtnDisabled: false,
      BASE_API: process.env.BASE_API, // 接口API地址
      imagecropperShow: false, // 是否显示上传组件
      imagecropperKey: 0 // 上传组件id

引入组件和组件声明

//引入组件
import ImageCropper from '@/components/ImageCropper'
import PanThumb from '@/components/PanThumb'


export default {
  components:{ImageCropper,PanThumb},//声明组件

编写close()方法和cropSuccess()方法

methods: {
    close(){//上传关闭弹框的方法
      this.imagecropperShow=false;
      this.imagecropperKey = this.imagecropperKey+1
    },
    cropSuccess(data){//上传成功的方法
    this.imagecropperShow=false;
    //上传完后返回图片地址
      this.teacher.avatar = data.url

      this.imagecropperKey = this.imagecropperKey+1
    },

完整的代码结构仅供参考

<template>
    <div class="app-container">
        讲师添加
        <el-form label-width="120px">
      <el-form-item label="讲师名称">
        <el-input v-model="teacher.name"/>
      </el-form-item>
      <el-form-item label="讲师排序">
        <el-input-number v-model="teacher.sort" controls-position="right" min="0"/>
      </el-form-item>
      <el-form-item label="讲师头衔">
        <el-select v-model="teacher.level" clearable placeholder="请选择">
          <!--
            数据类型一定要和取出的json中的一致,否则没法回填
            因此,这里value使用动态绑定的值,保证其数据类型是number
          -->
          <el-option :value="1" label="高级讲师"/>
          <el-option :value="2" label="首席讲师"/>
        </el-select>
      </el-form-item>
      <el-form-item label="讲师资历">
        <el-input v-model="teacher.career"/>
      </el-form-item>
      <el-form-item label="讲师简介">
        <el-input v-model="teacher.intro" :rows="10" type="textarea"/>
      </el-form-item>

      <!-- 讲师头像:TODO -->
      <!-- 讲师头像 -->
<el-form-item label="讲师头像">

    <!-- 头衔缩略图 -->
    <pan-thumb :image="teacher.avatar"/>
    <!-- 文件上传按钮 -->
    <el-button type="primary" icon="el-icon-upload" @click="imagecropperShow=true">更换头像
    </el-button>

    <!--
v-show:是否显示上传组件
:key:类似于id,如果一个页面多个图片上传控件,可以做区分
:url:后台上传的url地址
@close:关闭上传组件
@crop-upload-success:上传成功后的回调 -->
    <image-cropper
                   v-show="imagecropperShow"
                   :width="300"
                   :height="300"
                   :key="imagecropperKey"
                   :url="BASE_API+'/eduoss/upload/'"
                   field="file"
                   @close="close"
                   @crop-upload-success="cropSuccess"/>

</el-form-item>

      <el-form-item>
        <el-button :disabled="saveBtnDisabled" type="primary" @click="saveOrUpdate">保存</el-button>
      </el-form-item>
    </el-form>
    </div>
</template>
<script>
import teacherApi from '@/api/teacher/teacher'
//引入组件
import ImageCropper from '@/components/ImageCropper'
import PanThumb from '@/components/PanThumb'
export default {
  components:{ImageCropper,PanThumb},//声明组件
  data() {
    return {
      teacher: {
        name: '',
        sort: 0,
        level: 1,
        career: '',
        intro: '',
        avatar: ''
      },
      // 保存按钮是否禁用,
      saveBtnDisabled: false,
      BASE_API: process.env.BASE_API, // 接口API地址
      imagecropperShow: false, // 是否显示上传组件
      imagecropperKey: 0 // 上传组件id
    }
  },
  created(){//页面渲染前执行
      this.init()
  },
  watch: {
    $$route(to,from){//路由变化方式 路由发生变化 方法就会执行
      // this.init()
      this.teacher = {...defaultForm}
    }
  },
  methods: {
    close(){//上传关闭弹框的方法
      this.imagecropperShow=false;
      this.imagecropperKey = this.imagecropperKey+1
    },
    cropSuccess(data){//上传成功的方法
    this.imagecropperShow=false;
    //上传完后返回图片地址
      this.teacher.avatar = data.url

      this.imagecropperKey = this.imagecropperKey+1
    },
    init(){
      if (this.$route.params && this.$route.params.id) {//判断路径是否有id值
        const id = this.$route.params.id //从路径中获取id值
        this.getInfo(id) //调用根据id查询的方法
      }else{//路径中没有id值
      //清空表单
        this.teacher = {...defaultForm}
      }
    },
    getInfo(id){//根据讲师id查询的方法
      teacherApi. getTeacherInfo(id)
      .then(response=>{
        this.teacher = response.data.eduTeacher
      })
    },
    saveOrUpdate() {
      //根据teacher是都有id 判断修改还是添加
      if(!this.teacher.id){
        //添加
        this.saveBtnDisabled = true
        this.saveTeacher()
      }else{
        // 修改
        this.updateTeacher()
      }

    },
    updateTeacher(){
      teacherApi.updateTeacher(this.teacher)
      .then(response =>{//修改成功
                this.$message({
                    type: 'success',
                    message: '修改成功!'
            });
            this.$router.push({path:'/teacher/table'})
            })
    },
    // 保存 添加讲师的方法
    saveTeacher() {
        teacherApi.save(this.teacher)
            .then(response =>{//保存成功
                this.$message({
                    type: 'success',
                    message: '添加成功!'
            });
            this.$router.push({path:'/teacher/table'})
            })
    }
  }
  
}
</script>

启动java项目和前端项目 输入npm run dev

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值