在SpringBoot中使用【阿里云OSS对象存储】存取图片

一、前言

在SpringBoot中使用【阿里云OSS对象存储】存取图片_第1张图片
1、用户文件存储在项目中,项目体积会日益增大,给日后项目代码更新、部署上传时间增长。
此外 linux、windows 的路径不一致,保存文件的路径只能使用相对路径,前端展示文件时 src 需要 + http://port/xxx 补全路径,增加了点业务逻辑。

等等。

2、OSS云存储技术优点:

1.OSS 内存省钱
2.可以使用了第三方cdn,访问速度快

3、使用了阿里云OSS技术其他优点:

1.浏览器访问图片(png、jpg…)url,显示图片;
2.浏览器访问文件(doc、pdf…)url,自动下载文件;

二、思路

1、前台上传图片给后台
在SpringBoot中使用【阿里云OSS对象存储】存取图片_第2张图片

2、后台把图片上传到阿里云服务器的OSS中
在SpringBoot中使用【阿里云OSS对象存储】存取图片_第3张图片

3、同时生成图片访问的 url,保存到数据库中
这里写图片描述

4、显示图片的时候,使用 url,如下的使用方式

<img src="url" />

在SpringBoot中使用【阿里云OSS对象存储】存取图片_第4张图片

二、代码

2017.7.14 更新,代码已经放在 github 上了:https://github.com/larger5/oss_aliyun_springboot.git

1、代码目录

在SpringBoot中使用【阿里云OSS对象存储】存取图片_第5张图片

2、entity 实体

package com.cun.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="t_picture")
public class Picture {
	
	@Id
	@GeneratedValue
	private Integer id;
	
	@Column(length=50)
	private String picName;

	@Column(length=200)
	private String url;
	
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getPicName() {
		return picName;
	}

	public void setPicName(String picName) {
		this.picName = picName;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}


}

2、dao 接口

package com.cun.dao;

import org.springframework.data.jpa.repository.JpaRepository;

import com.cun.entity.Picture;

public interface PictureDao extends JpaRepository<Picture, Integer>{

}

3、Service 接口

package com.cun.service;

import java.util.List;

import com.cun.entity.Picture;

public interface PictureService {

	/**
	 * 删
	 * @param id
	 */
	void deletePicture(Integer id);

	/**
	 * 改
	 * @param picture
	 */
	void updatePicture(Picture picture);

	/**
	 * 查
	 * @param id
	 * @return
	 */
	Picture getPicture(Integer id);

	/**
	 * 增
	 * @param picture
	 */
	void insertPicture(Picture picture);
	
	/**
	 * 全
	 * @return
	 */
	List<Picture> getAllPictures();

}

4、Service 实现类

package com.cun.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cun.dao.PictureDao;
import com.cun.entity.Picture;
import com.cun.service.PictureService;

@Service
public class PictureServiceImpl implements PictureService{
	
	@Autowired
	private PictureDao pictureDao;

	@Override
	public void deletePicture(Integer id) {
		pictureDao.delete(id);
	}

	@Override
	public void updatePicture(Picture picture) {
		pictureDao.save(picture);
	}

	@Override
	public Picture getPicture(Integer id) {
		return pictureDao.getOne(id);
	}

	@Override
	public void insertPicture(Picture picture) {
		pictureDao.save(picture);
	}

	@Override
	public List<Picture> getAllPictures() {
		return pictureDao.findAll();
	}
	

}

5、Controller 控制层

package com.cun.controller;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.cun.entity.Picture;
import com.cun.service.PictureService;

@Controller
@RequestMapping("/picture")
public class PictureController {

	@Autowired
	private PictureService pictureService;

	/**
	 * 主页
	 * @return
	 */
	@GetMapping("/")
	public String toIndex() {
		return "add";
	}
	
	/**
	 * 全
	 * @return
	 */
	@ResponseBody
	@GetMapping("/all")
	public List<Picture> getAllPictures() {
		return pictureService.getAllPictures();
		
	}

	/**
	 * 增
	 * @param picture
	 * @throws IOException 
	 * @throws ClientException 
	 * @throws OSSException 
	 */
	@PostMapping("/insert")
	public String insertPicture(@RequestParam("fileupload") MultipartFile fileupload, String picName,HttpServletRequest request) throws OSSException, ClientException, IOException {
		Picture picture=new Picture();
		picture.setPicName(picName);
		picture.setUrl(getUrl(fileupload));//虽然传来的是文件,但是保存到数据库的是路径
		pictureService.insertPicture(picture);
		return "show";
	}

	/**
	 * 改
	 * @param picture
	 */
	@ResponseBody
	@PutMapping("/update")
	public void updatePicture(Picture picture) {
		pictureService.updatePicture(picture);
	}

	/**
	 * 删
	 * @param id
	 */
	@ResponseBody
	@DeleteMapping("/delete/{id}")
	public void deletePicture(@PathVariable("id") Integer id) {
		pictureService.deletePicture(id);
	}
	
	/**
	 * 查
	 * @param id
	 * @return
	 */
	@ResponseBody
	@GetMapping("/get/{id}")
	public Picture getPicture(@PathVariable("id") Integer id) {
		return pictureService.getPicture(id);
	}
	
	/**
	 * 把文件保存到阿里云OSS,返回路径保存到数据库
	 * @param fileupload
	 * @return
	 * @throws OSSException
	 * @throws ClientException
	 * @throws IOException
	 */
	public String getUrl(MultipartFile fileupload) throws OSSException, ClientException, IOException {
		//填写自己的帐号信息
		String endpoint = "xxxx";
		String accessKeyId = "xxxxxx";
		String accessKeySecret = "xxxxxx";

		// 创建OSSClient实例
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);

		// 文件桶
		String bucketName = "itaem";
		// 文件名格式
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
		// 该桶中的文件key
		String dateString = sdf.format(new Date()) + ".jpg";// 20180322010634.jpg
		// 上传文件
		ossClient.putObject("itaem", dateString, new ByteArrayInputStream(fileupload.getBytes()));

		// 设置URL过期时间为100年,默认这里是int型,转换为long型即可
		Date expiration = new Date(new Date().getTime() + 3600l * 1000 * 24 * 365 * 100);
		// 生成URL
		URL url = ossClient.generatePresignedUrl(bucketName, dateString, expiration);
		return url.toString();
	}

}

6、添加页 add.html


<html>
	<head>
		<meta charset="UTF-8">meta>
		<title>ITAEMtitle>
		<script type="text/jscript" src="../jquery-easyui-1.3.3/jquery.min.js">script>
	head>
	<body>
	
	<form action="http://localhost/picture/insert" method="post" enctype="multipart/form-data">
		name<input type="text" name="picName" id="picName">input><br /><br />
		<input type="file" name="fileupload" id="fileupload">input><br /><br />
		<input type="submit" value="上传" >input>
	form>
	body>
html>

7、展示页 show.html


<html>

	<head>
		<meta charset="UTF-8">meta>
		<title>ITAEMtitle>
		
		<script type="text/javascript" src="../js/jquery-1.7.2.js">script>
		<script type="text/javascript">
			$.ajax({
				type: "Get",
				url: "http://localhost/picture/all",
				success:function(result){
					$('#pic').empty()
					show(result)
				}
			});
			function show(result){
				var lists=result
				/* 遍历,省略了 for 循环 */
				$.each(lists, function(index,img) {
					/*必须独立出来再放进入*/
					var img=$("").attr("src",img.url)
					$('#pic').append("
"
).append(img) }); }
script> head> <body> <div id="pic">div> body> html>

8、pom 阿里云sdk依赖

<dependency>
    <groupId>com.aliyun.ossgroupId>
    <artifactId>aliyun-sdk-ossartifactId>
    <version>2.8.2version>
dependency>

其他
这里写图片描述

三、其他

1、阿里云 OSS API 文档:https://help.aliyun.com/document_detail/32008.html?spm=a2c4g.11186623.6.669.kWoPky
2、操作记录 gif 图
3、发布到 Linux 上的时,若要打成 war 包,会发现第三方 jar (本位为 ali oss)没有导入,可以参考如下文章:
https://www.sojson.com/blog/253.html
4、确保图片名称唯一,使用 uuid 比较好,不要使用时间字符串,应对不了高并发
String id = UUID.randomUUID().toString();
5、参考文章:[教程]如何解决Java sdk设置URL签名过期时间很长不生效
#四、2018.8.2 更新
做项目经常要用到,于是将 OSS 上传文件,下载访问文件 url,封装成一个 utils

package com.cun.app.utils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.web.multipart.MultipartFile;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;

/**
 * 把文件保存到阿里云OSS,返回文件访问路径
 * @author linhongcun
 *
 */
public class Oss {

    public static String getFileUrl(MultipartFile fileupload) throws OSSException, ClientException, IOException {
		// 获取文件后缀名
        String suffix =getSuffix(fileupload);
        // 填自己的帐号信息
        String endpoint = "oss-cn-shenzhen.aliyuncs.com";
        String accessKeyId = "LTAIATBxxxxxxxx4R";
        String accessKeySecret = "VuCGomJW0O5xxxxxxxxx9QKR";
        // 创建OSSClient实例
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 文件桶
        String bucketName = "itaem";
        // 文件名格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
        // 该桶中的文件key
        String dateString = sdf.format(new Date()) + "."+suffix; // 20180322010634.jpg
        // 上传文件
        ossClient.putObject("itaem", dateString, new ByteArrayInputStream(fileupload.getBytes()));
        // 设置URL过期时间为100年,默认这里是int型,转换为long型即可
        Date expiration = new Date(new Date().getTime() + 3600l * 1000 * 24 * 365 * 100);
        // 生成URL
        URL url = ossClient.generatePresignedUrl(bucketName, dateString, expiration);
        return url.toString();
    }

    // 获取文 MultipartFile 文件后缀名工具
    public static String getSuffix(MultipartFile fileupload){
        String originalFilename = fileupload.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        System.out.println(suffix);
        return suffix;
    }

}

你可能感兴趣的:(分布式,微服务,云计算)