oss
这里介绍一下 oss 的使用。
功能介绍
主要包含在 wmeimob-spring-boot-starter-oss
jar 中。
支持的平台有:
引入公共依赖:
xml
<dependency>
<groupId>com.wmeimob.fastboot</groupId>
<artifactId>wmeimob-spring-boot-starter-oss</artifactId>
</dependency>
公共配置项:
yml
oss:
ossType: xxx # OSS 平台类型
ossAccessKey: xxx # OSS AccessKey
ossSecretKey: xxxx # OSS SecretKey
ossBucketName: xxx # OSS BucketName
ossEndPoint: oss-xxx.com # OSS EndPoint
阿里云
再引入阿里云依赖:
xml
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
</dependency>
填写好公共配置项即可。
腾讯云
再引入腾讯云依赖:
xml
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>cos-sts-java</artifactId>
</dependency>
除了填写公共配置项外,还需要再填写:
yml
oss-region: xxx # OSS region
oss-app-id: xxx # OSS app-id
华为云
再引入华为云依赖:
xml
<dependency>
<groupId>com.huaweicloud</groupId>
<artifactId>esdk-obs-java-bundle</artifactId>
</dependency>
七牛云
暂未遇到有项目在使用,暂时不补充
minio
再引入minio依赖:
xml
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
</dependency>
本地云存储
如果使用本地云存储,无需引入任何依赖,除了调整公共配置外,还需要再调写:
yml
localDir: #本地根目录路径
picFileType: #本地OSS支持的文件类型,默认支持 png|jpg|jpeg|gif|bmp|svg|ico|mp4|webm|ogg|pdf
自定义 spi 扩展
如果使用自定义 spi 扩展,无需引入任何依赖,只需要更改公共配置的 ossType 为自定义 spi 扩展即可。如果上述提供的几种方式不满足的话,可以通过 spi 方式来扩展。此处基于 spring spi 扩展机制来实现。
常见问题
- 阿里云签名
默认为 V1 签名。由于 V1 签名会被废弃,因而无法使用。现支持 V1,V4 签名切换,参见所有配置属性。
- 文件大小限制
默认 20M。如若不够,可更改。
yml
oss:
maxFileSize: 20 #最大文件限制(M)
- 文件后缀限制
文件后缀限制目前只针对阿里云,如果需要上传其他格式,需要添加对应的配置。
默认支持如下格式:
yml
oss:
content-type:
- image/png
- image/bmp
- image/jpeg
- image/jpg
- image/gif
- video/mp4
- application/json
- image/tiff
- image/webp
- font/ttf
- font/otf
- Handler dispatch failed; nested exception is java.lang.NoSuchMethodError: org.json.JSONObject.toMap()Ljava/util/Map
解决方法如下:
yml
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>cos-sts-java</artifactId>
<exclusions>
<exclusion>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</dependency>
主 pom 文件引入如下依赖:
yml
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180130</version>
</dependency>
- 华为云栈溢出
错误如下:
java
Caused by: java.lang.IllegalStateException: Failed to introspect Class [com.wmeimob.spring.boot.oss.service.impl.OssServiceHuaweiyunImpl] from ClassLoader [sun.misc.Launcher$AppClassLoader@42a57993]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:485)
at org.springframework.util.ReflectionUtils.doWithLocalMethods(ReflectionUtils.java:321)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.buildLifecycleMetadata(InitDestroyAnnotationBeanPostProcessor.java:232)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.findLifecycleMetadata(InitDestroyAnnotationBeanPostProcessor.java:210)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(InitDestroyAnnotationBeanPostProcessor.java:149)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(CommonAnnotationBeanPostProcessor.java:305)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:1116)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
... 72 common frames omitted
Caused by: java.lang.StackOverflowError: null
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
解决方法如下:
java
jvm 启动参数增大栈空间
-Xss512K
所有配置属性
txt
/**
* OSS类型 (pic:本地OSS qiniu:七牛 aliyun:阿里云 qcloud:腾讯云, huawei:华为云)
*/
ossType;
/**
* 是否开启自定义 cdn 域名
*/
enableCustomCdn;
/**
* CDN域名
*/
cdnDomain;
/**
* OSS绑定的域名
*/
ossDomain;
/**
* OSS AccessKey
*/
ossAccessKey;
/**
* OSS SecretKey
*/
ossSecretKey;
/**
* OSS BucketName
*/
ossBucketName;
/**
* EndPoint (EndPoint)
*/
ossEndPoint;
/**
* AppId (腾讯云AppId)
*/
ossAppId;
/**
* 所属地区 (阿里云/腾讯云)
*/
ossRegion;
/**
* Url有效时间
*/
expire;
/**
* 上传目录(OSS服务的上传路径)
*/
dir;
/**
* 最大文件限制(M)
*/
maxFileSize;
/**
* 是否为https(已过期,使用 enableHttps 代替)
*/
isHttps;
/**
* 是否为https
*/
enabledHttps;
/**
* 本地根目录路径(临时文件|服务器图片上传路径)
*/
localDir;
/**
* 本地OSS支持的文件类型(png|jpg|jpeg|gif|bmp|svg|ico|mp4|webm|ogg|pdf)
*/
picFileType = "png|jpg|jpeg|gif|bmp|svg|ico|mp4|webm|ogg|pdf";
/**
* 上传支持的 contentType 列表
*/
contentType;
/**
* 签名版本(适用于阿里云,默认 V1。支持 V1,V4。当使用 V4 时,ossRegion 属性必填。)
*/
signVersion = "V1";
与标品的集成
java
@Api(tags = {"云存储"})
@RestController
@RequestMapping("/api/oss")
public class OssController {
@Resource
private OssService ossService;
@ApiOperation(value = "云存储信息")
@GetMapping("/info")
public JsonResult<Map<String, Object>> info() {
return JsonResult.ok(this.ossService.ossPolicy());
}
}
java
public enum OssType {
Aliyun,
Qcloud,
Qiniu,
Pic,
Huawei,
Custom;
}
前端直接通过该接口便可以获取到具体的云存储通道。如下是各个渠道 map 参数说明:
txt
accessid=xx #访问id
policy=xx #policy
signature=xx #签名
dir=xx/ #上传目录
host=xx #host
expire=xx #过期时间毫秒
cdnDomain=xx #cdn域名
type=xx #类型
txt
credentials: {
"tmpSecretId": "xxx",
"tmpSecretKey": "xx=",
"sessionToken": "xxx"
} #凭证对象
dir=xx/ #上传目录
expiration=xx #过期时间,例如:2024-02-29T09:15:53Z
startTime=xx #开始时间,整形
expiredTime=xx #过期时间,整形
bucket=xx #桶名称
region=xx #区域
cdnDomain=xx #cdn域名
type=xx #类型
txt
access_key_id=xx #访问id
policy=xx #policy
signature=xx #签名
server=xx #host
dir=xx/ #上传目录
cdnDomain=xx #cdn域名
type=xx #类型
txt
暂未提供
安全
跨域
当作为静态资源存储时,我们需要为其设置跨域规则,例如:
yaml
http://localhost:* #本地开发
https://xxx #部署后的域名
防盗链
而防盗链设置则可以不让 oss 流量外泄,我们可以这样去设置,例如:
yaml
*.console.aliyun.com # 阿里云域名
*servicewechat.com # 微信小程序域名
*.xxx # 业务部署后的域名
http://localhost:* # 本地开发