投票小程序之使用OSS上传图片、视频、文档实现过程

wuchangjian2021-11-05 17:04:10编程学习

SpringBoot框架中各层解释如下

View层:Controller层(响应用户请求)

Service层:接口及接口实现类 

DAO层:Mapper层(抽象类:xxxMapper.java文件,具体实现在xxxMapper.xml)

Model层:实体类:xxx.java

VO:View Object,视图层,其作用是将指定页面的展示数据封装起来

DTO:Data Transfer Object,数据传输对象

DO:Domain Object,领域对象

PO:Persistent Object,持久化对象

注册阿里云账号,开通OSS存储

OSS存储流程介绍

 官方文档地址:概述 - 对象存储 OSS - 阿里云

oss存储管理服务端实现

在vote-manage工程的pom.xml文件中,添加依赖

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

在vote-manage工程的vote-web模块中的application.yaml文件中 添加如下配置

oss:
  endpoint: https://oss-cn-hangzhou.aliyuncs.com # oss对外服务的访问域名,实际根据你选择的地区域名
  accessKeyId: 用户标识 # 访问身份验证中用到用户标识
  accessKeySecret: 字符串的密钥 # 用户用于加密签名字符串和oss用来验证签名字符串的密钥
  bucketName: mtbox # oss的存储空间
  policy:
    expire: 300 # 签名有效期(S)
  maxSize: 10 # 上传文件大小(M)
  callback: http://域名:8080/aliyun/oss/callback # 文件上传成功后的回调地址
  dir:
    prefix: vote/images/ # 上传文件夹路径前缀

在vote-manage工程的vote-common模块中的src\main\java\com\dliberty\vote\common\config类文件中添加,用于配置OSS的连接客户端OSSClient 

/**
 * oss配置文件
 */
@Configuration
public class OssConfig {
    @Value("${oss.endpoint}")
    private String ALIYUN_OSS_ENDPOINT;
    @Value("${oss.accessKeyId}")
    private String ALIYUN_OSS_ACCESSKEYID;
    @Value("${oss.accessKeySecret}")
    private String ALIYUN_OSS_ACCESSKEYSECRET;
    @Bean
    public OSSClient ossClient(){
        return new OSSClient(ALIYUN_OSS_ENDPOINT,ALIYUN_OSS_ACCESSKEYID,ALIYUN_OSS_ACCESSKEYSECRET);
    }
}

在vote-manage工程的vote-api模块中的src\main\java\com\dliberty\vote\api\dto\目录下 添加OSS上传策略封装对象OssPolicyResult类

/**
 * 获取OSS上传文件授权返回结果 
 */
public class OssPolicyResult {
	@ApiModelProperty("访问身份验证中用到用户标识")
	private String accessKeyId;
	@ApiModelProperty("用户表单上传的策略,经过base64编码过的字符串")
	private String policy;
	@ApiModelProperty("对policy签名后的字符串")
	private String signature;
	@ApiModelProperty("上传文件夹路径前缀")
	private String dir;
	@ApiModelProperty("oss对外服务的访问域名")
	private String host;
	@ApiModelProperty("上传成功后的回调设置")
	private String callback;
	@ApiModelProperty("上传文件名")
	private String fileName;

	public String getAccessKeyId() {
		return accessKeyId;
	}

	public void setAccessKeyId(String accessKeyId) {
		this.accessKeyId = accessKeyId;
	}

	public String getPolicy() {
		return policy;
	}

	public void setPolicy(String policy) {
		this.policy = policy;
	}

	public String getSignature() {
		return signature;
	}

	public void setSignature(String signature) {
		this.signature = signature;
	}

	public String getDir() {
		return dir;
	}

	public void setDir(String dir) {
		this.dir = dir;
	}

	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public String getCallback() {
		return callback;
	}

	public void setCallback(String callback) {
		this.callback = callback;
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	
}	

在vote-manage工程的vote-api模块中的src\main\java\com\dliberty\vote\api\service目录下 添加OSS业务层接口OssService类

/**
 * oss上传管理Service
 */
public interface OssService {
	/**
	 * oss上传策略生成
	 */
	OssPolicyResult policy();


}

在vote-manage工程的vote-app模块中的src\main\java\com\dliberty\vote\app\impl目录下 添加OSS业务层实现OssServiceImpl类

/**
 * oss上传管理Service实现类
 * 
 */
@Service
public class OssServiceImpl implements OssService {

	private static final Logger LOGGER = LoggerFactory.getLogger(OssServiceImpl.class);
	@Value("${oss.policy.expire}")
	private int ALIYUN_OSS_EXPIRE;
	@Value("${oss.maxSize}")
	private int ALIYUN_OSS_MAX_SIZE;
	@Value("${oss.callback}")
	private String ALIYUN_OSS_CALLBACK;
	@Value("${oss.bucketName}")
	private String ALIYUN_OSS_BUCKET_NAME;
	@Value("${oss.endpoint}")
	private String ALIYUN_OSS_ENDPOINT;
	@Value("${oss.dir.prefix}")
	private String ALIYUN_OSS_DIR_PREFIX;

	@Autowired
	private OSSClient ossClient;

 /**
	 * 签名生成
	 */
	@Override
	public OssPolicyResult policy() {
		OssPolicyResult result = new OssPolicyResult();
		// 存储目录
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String dir = ALIYUN_OSS_DIR_PREFIX+sdf.format(new Date());
		// 签名有效期
		long expireEndTime = System.currentTimeMillis() + ALIYUN_OSS_EXPIRE * 1000;
		Date expiration = new Date(expireEndTime);
		// 文件大小
		long maxSize = ALIYUN_OSS_MAX_SIZE * 1024 * 1024;

		// 提交节点
		String action = "http://" + ALIYUN_OSS_BUCKET_NAME + "." + ALIYUN_OSS_ENDPOINT;
		try {
			PolicyConditions policyConds = new PolicyConditions();
			policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, maxSize);
			policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
			String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
			byte[] binaryData = postPolicy.getBytes("utf-8");
			String policy = BinaryUtil.toBase64String(binaryData);
			String signature = ossClient.calculatePostSignature(postPolicy);
		result.setAccessKeyId(ossClient.getCredentialsProvider().getCredentials().getAccessKeyId());
			result.setPolicy(policy);
			result.setSignature(signature);
			result.setDir(dir);
			result.setHost(action);
		} catch (Exception e) {
			LOGGER.error("签名生成失败", e);
		}
		return result;
	}


}

在vote-manage工程的vote-web模块中的src\main\java\com\dliberty\vote\web\controller目录下 添加OssController定义接口类

/**
 * Oss相关操作接口 .
 */
@RestController
@Api(tags = "OssController", value = "Oss管理")
@RequestMapping("/aliyun/oss")
public class OssController {
	@Autowired
	private OssService ossService;

	@ApiOperation(value = "oss上传签名生成")
	@GetMapping("/policy")
	public Response<OssPolicyResult> policy() {
		OssPolicyResult result = ossService.policy();
		return Response.ofData(result);
	}

}

设置上传回调

在vote-manage工程的vote-web模块中的\src\main\resources的application.yaml文件中添加回调配置

callback: http://外网ip或域名:8080/aliyun/oss/callback # 文件上传成功后的回调地址

在vote-manage工程的vote-api模块中的src\main\java\com\dliberty\vote\api\dto\目录下对应OssPolicyResult类的回调设置方法

	@ApiModelProperty("上传成功后的回调设置")
	private String callback;

在vote-manage工程的vote-api模块中的src\main\java\com\dliberty\vote\api\dto\目录下添加OssCallbackParam类

作用:当OSS上传成功后,会根据该配置参数来回调对应接口

/**
 * oss上传成功后的回调参数
 */
public class OssCallbackParam {
	@ApiModelProperty("请求的回调地址")
	private String callbackUrl;
	@ApiModelProperty("回调是传入request中的参数")
	private String callbackBody;
	@ApiModelProperty("回调时传入参数的格式,比如表单提交形式")
	private String callbackBodyType;

	public String getCallbackUrl() {
		return callbackUrl;
	}

	public void setCallbackUrl(String callbackUrl) {
		this.callbackUrl = callbackUrl;
	}

	public String getCallbackBody() {
		return callbackBody;
	}

	public void setCallbackBody(String callbackBody) {
		this.callbackBody = callbackBody;
	}

	public String getCallbackBodyType() {
		return callbackBodyType;
	}

	public void setCallbackBodyType(String callbackBodyType) {
		this.callbackBodyType = callbackBodyType;
	}
}

在vote-manage工程的vote-api模块中的src\main\java\com\dliberty\vote\api\dto\目录下添加OssCallbackResult类

作用:回调接口中返回的数据对象

/**
 * oss上传文件的回调结果 
 */
public class OssCallbackResult {
	@ApiModelProperty("文件名称")
	private String filename;
	@ApiModelProperty("文件大小")
	private String size;
	@ApiModelProperty("文件的mimeType")
	private String mimeType;
	@ApiModelProperty("图片文件的宽")
	private String width;
	@ApiModelProperty("图片文件的高")
	private String height;
}

在vote-manage工程的vote-api模块中的src\main\java\com\dliberty\vote\api\service目录下 OssService类添加回调接口

	/**
	 * oss上传成功回调
	 */
	OssCallbackResult callback(HttpServletRequest request);

在vote-manage工程的vote-app模块中的src\main\java\com\dliberty\vote\app\impl目录下 实现OssServiceImpl类添加回调实现

 实际类添加参数属性

	@Value("${oss.bucketName}")
	private String ALIYUN_OSS_BUCKET_NAME;
	@Value("${oss.endpoint}")
	private String ALIYUN_OSS_ENDPOINT;

添加实现方法

	@Override
	public OssCallbackResult callback(HttpServletRequest request) {
		OssCallbackResult result= new OssCallbackResult();
		String filename = request.getParameter("filename");
		filename = "http://".concat(ALIYUN_OSS_BUCKET_NAME).concat(".").concat(ALIYUN_OSS_ENDPOINT).concat("/").concat(filename);
		result.setFilename(filename);
		result.setSize(request.getParameter("size"));
		result.setMimeType(request.getParameter("mimeType"));
		result.setWidth(request.getParameter("width"));
		result.setHeight(request.getParameter("height"));
		return result;
	}

原有签名生成policy实现方法,添加回调处理相关代码

	/**
	 * 签名生成
	 */
	@Override
	public OssPolicyResult policy() {
		OssPolicyResult result = new OssPolicyResult();
		// 存储目录
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String dir = ALIYUN_OSS_DIR_PREFIX+sdf.format(new Date());
		// 签名有效期
		long expireEndTime = System.currentTimeMillis() + ALIYUN_OSS_EXPIRE * 1000;
		Date expiration = new Date(expireEndTime);
		// 文件大小
		long maxSize = ALIYUN_OSS_MAX_SIZE * 1024 * 1024;
		// 回调
		OssCallbackParam callback = new OssCallbackParam();
		callback.setCallbackUrl(ALIYUN_OSS_CALLBACK);
		callback.setCallbackBody("filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}");
		callback.setCallbackBodyType("application/x-www-form-urlencoded");
		// 提交节点
		//String action = "http://" + ALIYUN_OSS_BUCKET_NAME + "." + ALIYUN_OSS_ENDPOINT;
		String action = "http://image.dliberty.com";
		try {
			PolicyConditions policyConds = new PolicyConditions();
			policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, maxSize);
			policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
			String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
			byte[] binaryData = postPolicy.getBytes("utf-8");
			String policy = BinaryUtil.toBase64String(binaryData);
			String signature = ossClient.calculatePostSignature(postPolicy);
			
			String callbackData = BinaryUtil.toBase64String(JSONObject.toJSON(callback).toString().getBytes("utf-8"));
			// 返回结果
			result.setAccessKeyId(ossClient.getCredentialsProvider().getCredentials().getAccessKeyId());
			result.setPolicy(policy);
			result.setSignature(signature);
			result.setDir(dir);
			result.setCallback(callbackData);
			result.setHost(action);
			
			String key = "doc_file" + System.currentTimeMillis();
			String fileName = Base64Utils.encodeToString(key.getBytes());
			result.setFileName(fileName);
			
			
		} catch (Exception e) {
			LOGGER.error("签名生成失败", e);
		}
		return result;
	}

在vote-manage工程的vote-web模块中的src\main\java\com\dliberty\vote\web\controller目录下 OssController类添加回调接口

	@ApiOperation(value = "oss上传成功回调")
	@PostMapping("callback")
	public Response<OssCallbackResult> callback(HttpServletRequest request) {
		OssCallbackResult ossCallbackResult = ossService.callback(request);
		return Response.ofData(ossCallbackResult);
	}

oss上传管理前端实现

使用Vue构建上传页面

在项目如下几个文件使用到:

异步获取签名

在vote\src\api\oss.js文件中,添加如下方法:

import request from '@/utils/request'
export function policy() {
  return request({
    url:'/aliyun/oss/policy',
    method:'get',
  })
}

单文件上传singleUpload.vue组件使用

定义组件

 使用组件

其它几个应该场景:上传视频、图片、文档 使用方法同上,大同小异,详细查看源码。 

oss上传管理小程序端实现

在小程序前端工程中如下几个文件使用到:

异步获取签名

在\vote-weixin\vote-weixin\vote\api\oss.js文件中,添加如下方法:

export function policy() {
  return request.get("aliyun/oss/policy", {});
}

uploadVideo.js文件定义函数uploadDetailVideo

uploadDetailVideo.wxml文件,<view>uploadVideo.js.js中的uploadDetailVideo函数

 

 其它几个应该场景:图片、文档使用方法同上,大同小异,详细查看源码。 

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。