Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jinli gu
Litemall
Commits
f24cd534
Commit
f24cd534
authored
Jul 16, 2018
by
Menethil
Browse files
添加腾讯对象存储的实现
parent
61f6b986
Changes
7
Hide whitespace changes
Inline
Side-by-side
litemall-os-api/pom.xml
View file @
f24cd534
...
...
@@ -22,6 +22,13 @@
<artifactId>
litemall-db
</artifactId>
</dependency>
<dependency>
<groupId>
com.qcloud
</groupId>
<artifactId>
cos_api
</artifactId>
<version>
5.4.4
</version>
</dependency>
</dependencies>
<build>
...
...
litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/FileSystemStorageService.java
View file @
f24cd534
...
...
@@ -7,14 +7,23 @@ import java.net.MalformedURLException;
import
java.nio.file.*
;
import
java.util.stream.Stream
;
import
org.linlinjava.litemall.os.config.ObjectStorageConfig
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.core.io.Resource
;
import
org.springframework.core.io.UrlResource
;
import
org.springframework.stereotype.Service
;
import
org.springframework.web.multipart.MultipartFile
;
@Service
/**
* 服务器本地文件存储
*/
@Service
(
"localStorage"
)
public
class
FileSystemStorageService
implements
StorageService
{
@Autowired
private
ObjectStorageConfig
osConfig
;
private
static
final
Path
rootLocation
=
Paths
.
get
(
"storage"
);
static
{
try
{
Files
.
createDirectories
(
rootLocation
);
...
...
@@ -24,12 +33,11 @@ public class FileSystemStorageService implements StorageService {
}
@Override
public
void
store
(
InputStream
inputStream
,
String
filen
ame
)
{
public
void
store
(
MultipartFile
file
,
String
keyN
ame
)
{
try
{
Files
.
copy
(
inputStream
,
this
.
rootLocation
.
resolve
(
filename
),
StandardCopyOption
.
REPLACE_EXISTING
);
}
catch
(
IOException
e
)
{
throw
new
RuntimeException
(
"Failed to store file "
+
filename
,
e
);
Files
.
copy
(
file
.
getInputStream
(),
this
.
rootLocation
.
resolve
(
keyName
),
StandardCopyOption
.
REPLACE_EXISTING
);
}
catch
(
IOException
e
)
{
throw
new
RuntimeException
(
"Failed to store file "
+
keyName
,
e
);
}
}
...
...
@@ -39,9 +47,8 @@ public class FileSystemStorageService implements StorageService {
return
Files
.
walk
(
this
.
rootLocation
,
1
)
.
filter
(
path
->
!
path
.
equals
(
this
.
rootLocation
))
.
map
(
path
->
this
.
rootLocation
.
relativize
(
path
));
}
catch
(
IOException
e
)
{
throw
new
RuntimeException
(
"Failed to read stored files"
,
e
);
}
catch
(
IOException
e
)
{
throw
new
RuntimeException
(
"Failed to read stored files"
,
e
);
}
}
...
...
@@ -58,12 +65,10 @@ public class FileSystemStorageService implements StorageService {
Resource
resource
=
new
UrlResource
(
file
.
toUri
());
if
(
resource
.
exists
()
||
resource
.
isReadable
())
{
return
resource
;
}
else
{
}
else
{
return
null
;
}
}
catch
(
MalformedURLException
e
)
{
}
catch
(
MalformedURLException
e
)
{
e
.
printStackTrace
();
return
null
;
}
...
...
@@ -79,4 +84,12 @@ public class FileSystemStorageService implements StorageService {
}
}
@Override
public
String
generateUrl
(
String
keyName
)
{
String
url
=
osConfig
.
getAddress
()
+
":"
+
osConfig
.
getPort
()
+
"/os/storage/fetch/"
+
keyName
;
if
(!
url
.
startsWith
(
"http"
))
{
url
=
"http://"
+
url
;
}
return
url
;
}
}
\ No newline at end of file
litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/StorageService.java
View file @
f24cd534
package
org.linlinjava.litemall.os.service
;
import
org.springframework.core.io.Resource
;
import
org.springframework.web.multipart.MultipartFile
;
import
java.io.InputStream
;
import
java.nio.file.Path
;
import
java.util.stream.Stream
;
/**
* 对象存储接口
*/
public
interface
StorageService
{
void
store
(
InputStream
inputStream
,
String
filename
);
/**
* 存储一个文件对象
* @param file SpringBoot MultipartFile文件对象
* @param keyName 文件索引名
*/
void
store
(
MultipartFile
file
,
String
keyName
);
Stream
<
Path
>
loadAll
();
Path
load
(
String
filename
);
Path
load
(
String
keyName
);
Resource
loadAsResource
(
String
keyName
);
Resource
loadAsResourc
e
(
String
filen
ame
);
void
delet
e
(
String
keyN
ame
);
void
delete
(
String
filen
ame
);
String
generateUrl
(
String
keyN
ame
);
}
\ No newline at end of file
litemall-os-api/src/main/java/org/linlinjava/litemall/os/tencent/TencentOSService.java
0 → 100644
View file @
f24cd534
package
org.linlinjava.litemall.os.tencent
;
import
com.qcloud.cos.COSClient
;
import
com.qcloud.cos.ClientConfig
;
import
com.qcloud.cos.auth.BasicCOSCredentials
;
import
com.qcloud.cos.auth.COSCredentials
;
import
com.qcloud.cos.model.ObjectMetadata
;
import
com.qcloud.cos.model.PutObjectRequest
;
import
com.qcloud.cos.model.PutObjectResult
;
import
com.qcloud.cos.region.Region
;
import
org.linlinjava.litemall.os.service.StorageService
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.PropertySource
;
import
org.springframework.core.io.Resource
;
import
org.springframework.core.io.UrlResource
;
import
org.springframework.stereotype.Service
;
import
org.springframework.web.multipart.MultipartFile
;
import
java.net.MalformedURLException
;
import
java.net.URL
;
import
java.nio.file.Path
;
import
java.util.stream.Stream
;
/**
* 腾讯对象存储服务类
*/
@PropertySource
(
value
=
"classpath:tencent.properties"
)
@Service
(
"tencent"
)
public
class
TencentOSService
implements
StorageService
{
@Value
(
"${tencent.os.secretId}"
)
private
String
accessKey
;
@Value
(
"${tencent.os.secretKey}"
)
private
String
secretKey
;
@Value
(
"${tencent.os.region}"
)
private
String
region
;
@Value
(
"${tencent.os.bucketName}"
)
private
String
bucketName
;
private
COSClient
cosClient
;
public
TencentOSService
()
{
}
private
COSClient
getCOSClient
()
{
if
(
cosClient
==
null
)
{
// 1 初始化用户身份信息(secretId, secretKey)
COSCredentials
cred
=
new
BasicCOSCredentials
(
accessKey
,
secretKey
);
// 2 设置bucket的区域, COS地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
ClientConfig
clientConfig
=
new
ClientConfig
(
new
Region
(
region
));
cosClient
=
new
COSClient
(
cred
,
clientConfig
);
}
return
cosClient
;
}
private
String
getBaseUrl
()
{
//https://litemall-1256968571.cos-website.ap-guangzhou.myqcloud.com
return
"https://"
+
bucketName
+
".cos-website."
+
region
+
".myqcloud.com/"
;
}
@Override
public
void
store
(
MultipartFile
file
,
String
keyName
)
{
try
{
// 简单文件上传, 最大支持 5 GB, 适用于小文件上传, 建议 20M以下的文件使用该接口
ObjectMetadata
objectMetadata
=
new
ObjectMetadata
();
objectMetadata
.
setContentLength
(
file
.
getSize
());
objectMetadata
.
setContentType
(
file
.
getContentType
());
// 对象键(Key)是对象在存储桶中的唯一标识。例如,在对象的访问域名 `bucket1-1250000000.cos.ap-guangzhou.myqcloud.com/doc1/pic1.jpg` 中,对象键为 doc1/pic1.jpg, 详情参考 [对象键](https://cloud.tencent.com/document/product/436/13324)
PutObjectRequest
putObjectRequest
=
new
PutObjectRequest
(
bucketName
,
keyName
,
file
.
getInputStream
(),
objectMetadata
);
PutObjectResult
putObjectResult
=
getCOSClient
().
putObject
(
putObjectRequest
);
}
catch
(
Exception
ex
)
{
System
.
console
().
printf
(
ex
.
getMessage
());
}
}
@Override
public
Stream
<
Path
>
loadAll
()
{
return
null
;
}
@Override
public
Path
load
(
String
keyName
)
{
return
null
;
}
@Override
public
Resource
loadAsResource
(
String
keyName
)
{
try
{
URL
url
=
new
URL
(
getBaseUrl
()
+
keyName
);
Resource
resource
=
new
UrlResource
(
url
);
if
(
resource
.
exists
()
||
resource
.
isReadable
())
{
return
resource
;
}
else
{
return
null
;
}
}
catch
(
MalformedURLException
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
@Override
public
void
delete
(
String
keyName
)
{
try
{
getCOSClient
().
deleteObject
(
bucketName
,
keyName
);
}
catch
(
Exception
e
){
e
.
printStackTrace
();
}
}
@Override
public
String
generateUrl
(
String
keyName
)
{
return
getBaseUrl
()
+
keyName
;
}
}
litemall-os-api/src/main/java/org/linlinjava/litemall/os/web/OsStorageController.java
View file @
f24cd534
...
...
@@ -5,7 +5,6 @@ import org.linlinjava.litemall.core.util.ResponseUtil;
import
org.linlinjava.litemall.db.domain.LitemallStorage
;
import
org.linlinjava.litemall.db.service.LitemallStorageService
;
import
org.linlinjava.litemall.os.service.StorageService
;
import
org.linlinjava.litemall.os.config.ObjectStorageConfig
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.core.io.Resource
;
import
org.springframework.http.HttpHeaders
;
...
...
@@ -25,22 +24,11 @@ import java.util.Map;
@RequestMapping
(
"/os/storage"
)
public
class
OsStorageController
{
@
Autowired
@
javax
.
annotation
.
Resource
(
name
=
"${activeStorage}"
)
private
StorageService
storageService
;
@Autowired
private
LitemallStorageService
litemallStorageService
;
@Autowired
private
ObjectStorageConfig
osConfig
;
private
String
generateUrl
(
String
key
){
String
url
=
osConfig
.
getAddress
()
+
":"
+
osConfig
.
getPort
()
+
"/os/storage/fetch/"
+
key
;
if
(!
url
.
startsWith
(
"http"
)){
url
=
"http://"
+
url
;
}
return
url
;
}
private
String
generateKey
(
String
originalFilename
){
int
index
=
originalFilename
.
lastIndexOf
(
'.'
);
String
suffix
=
originalFilename
.
substring
(
index
);
...
...
@@ -82,9 +70,9 @@ public class OsStorageController {
return
ResponseUtil
.
badArgumentValue
();
}
String
key
=
generateKey
(
originalFilename
);
storageService
.
store
(
inputStream
,
key
);
storageService
.
store
(
file
,
key
);
String
url
=
generateUrl
(
key
);
String
url
=
storageService
.
generateUrl
(
key
);
LitemallStorage
storageInfo
=
new
LitemallStorage
();
storageInfo
.
setName
(
originalFilename
);
storageInfo
.
setSize
((
int
)
file
.
getSize
());
...
...
litemall-os-api/src/main/resources/application.properties
View file @
f24cd534
spring.profiles.active
=
dev
server.port
=
8081
logging.level.org.linlinjava.litemall.os.Application
=
DEBUG
# \u5B58\u50A8\u5B9E\u73B0\uFF0C\u53EF\u9009\u62E9 localStorage \u6216\u8005 tencent \uFF0C\u5982\u679C\u9009\u62E9 tencent\uFF0C\u9700\u8981\u5F00\u901A\u817E\u8BAF\u5BF9\u8C61\u5B58\u50A8\u5E76\u914D\u7F6E tencent.properties
activeStorage
=
localStorage
#activeStorage=tencent
litemall-os-api/src/main/resources/tencent.properties
0 → 100644
View file @
f24cd534
# \u817E\u8BAF\u4E91\u5B58\u50A8\u76F8\u5173\u914D\u7F6E,\u817E\u8BAF\u4E91\u5FC5\u987B\u6253\u5F00 #\u9759\u6001\u7F51\u7AD9(https://cloud.tencent.com/document/product/436/6249) \u652F\u6301\uFF0C\u5426\u5219\u56FE\u7247\u4F1A\u76F4\u63A5\u4E0B\u8F7D\u800C\u4E0D\u662F\u663E\u793A
tencent.os.secretId
=
""
tencent.os.secretKey
=
""
tencent.os.region
=
""
tencent.os.bucketName
=
""
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment