├── .gitignore
├── README.md
├── pom.xml
└── src
├── main
├── java
│ └── org
│ │ └── mvnsearch
│ │ └── boot
│ │ └── oss
│ │ ├── AliyunOssAutoConfiguration.java
│ │ ├── AliyunOssEndpoint.java
│ │ ├── AliyunOssHealthIndicator.java
│ │ ├── AliyunOssMetrics.java
│ │ ├── AliyunOssProperties.java
│ │ ├── ByteArrayDataSource.java
│ │ ├── FileStorageService.java
│ │ └── impl
│ │ └── FileStorageServiceOssImpl.java
└── resources
│ └── META-INF
│ ├── spring.factories
│ └── spring.provides
└── test
├── java
└── org
│ └── mvnsearch
│ └── boot
│ ├── AliyunOssAutoConfigurationTest.java
│ └── OssTestApplication.java
└── resources
├── 1.jpg
├── application.properties
└── demo-context.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Java template
3 | *.class
4 |
5 | # Mobile Tools for Java (J2ME)
6 | .mtj.tmp/
7 |
8 | # Package Files #
9 | *.jar
10 | *.war
11 | *.ear
12 |
13 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
14 | hs_err_pid*
15 |
16 |
17 | ### JetBrains template
18 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
19 |
20 | *.iml
21 |
22 | ## Directory-based project format:
23 | .idea/
24 | # if you remove the above rule, at least ignore the following:
25 |
26 | # User-specific stuff:
27 | # .idea/workspace.xml
28 | # .idea/tasks.xml
29 | # .idea/dictionaries
30 |
31 | # Sensitive or high-churn files:
32 | # .idea/dataSources.ids
33 | # .idea/dataSources.xml
34 | # .idea/sqlDataSources.xml
35 | # .idea/dynamic.xml
36 | # .idea/uiDesigner.xml
37 |
38 | # Gradle:
39 | # .idea/gradle.xml
40 | # .idea/libraries
41 |
42 | # Mongo Explorer plugin:
43 | # .idea/mongoSettings.xml
44 |
45 | ## File-based project format:
46 | *.ipr
47 | *.iws
48 |
49 | ## Plugin-specific files:
50 |
51 | # IntelliJ
52 | out/
53 |
54 | # mpeltonen/sbt-idea plugin
55 | .idea_modules/
56 |
57 | # JIRA plugin
58 | atlassian-ide-plugin.xml
59 |
60 | # Crashlytics plugin (for Android Studio and IntelliJ)
61 | com_crashlytics_export_strings.xml
62 | crashlytics.properties
63 | crashlytics-build.properties
64 |
65 |
66 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | spring-boot-start-oss
2 | ===================================
3 | Spring boot with aliyun oss support
4 |
5 | ### usage
6 | in pom.xml add following dependency:
7 |
8 |
9 | org.mvnsearch.boot
10 | spring-boot-starter-oss
11 | 1.0.0-SNAPSHOT
12 |
13 |
14 | in application.properties file, please add following keys:
15 |
16 | spring.oss.key=xxxx
17 | spring.oss.secret=yyyy
18 | spring.oss.bucket=xxx-dev
19 |
20 | in your code you can use OssClient directly:
21 |
22 | @Autowired
23 | OSSClient ossClient;
24 |
25 | you can use FileStorageService API to operate file:
26 |
27 | @Autowired
28 | FileStorageService fileStorageService;
29 |
30 | ### Spring XML Configuration
31 | If you want to setup bean in Spring xml file, please use following code:
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | ### spring-boot-start-oss service List
45 |
46 | * org.mvnsearch.boot.oss.FileStorageService: API to operate the file
47 | * com.aliyun.oss.OSSClient: aliyun OSSClient
48 |
49 | Please use FileStorageService as usual, not OSSClient.
50 |
51 | ### Aliyun OSS endpoint
52 |
53 | Please visit http://localhost:8080/oss to view detail information.
54 |
55 |
56 | ### FaQ
57 |
58 | * Please upload a "ok.txt" under your buket for health indicator.
59 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.mvnsearch.boot
7 | spring-boot-starter-oss
8 | 1.0.0-SNAPSHOT
9 | jar
10 | spring-boot-starter-oss
11 | https://github.com/linux-china/spring-boot-starter-oss
12 |
13 |
14 | UTF-8
15 | 1.3.3.RELEASE
16 | 2.5
17 | 2.2.1
18 |
19 |
20 |
21 |
22 | linux_china
23 | Jacky Chan
24 | libing.chen@gmail.com
25 | https://twitter.com/linux_china
26 |
27 | Developer
28 |
29 |
30 |
31 |
32 |
33 | scm:git:git@github.com:linux-china/spring-boot-starter-oss.git
34 | scm:git:git@github.com:linux-china/spring-boot-starter-oss.git
35 | https://github.com/linux-china/spring-boot-starter-oss
36 |
37 |
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-actuator
42 |
43 |
44 | org.springframework.boot
45 | spring-boot-configuration-processor
46 | true
47 |
48 |
49 | commons-io
50 | commons-io
51 | ${commons-io.version}
52 |
53 |
54 | com.aliyun.oss
55 | aliyun-sdk-oss
56 | ${aliyun-oss.version}
57 |
58 |
59 | org.springframework.boot
60 | spring-boot-starter-test
61 | test
62 |
63 |
64 | junit
65 | junit
66 | test
67 |
68 |
69 |
70 |
71 |
72 |
73 | org.springframework.boot
74 | spring-boot-dependencies
75 | ${spring-boot.version}
76 | pom
77 | import
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | maven-compiler-plugin
86 | 3.3
87 |
88 | 1.8
89 | 1.8
90 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/src/main/java/org/mvnsearch/boot/oss/AliyunOssAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | package org.mvnsearch.boot.oss;
2 |
3 | import com.aliyun.oss.OSSClient;
4 | import org.mvnsearch.boot.oss.impl.FileStorageServiceOssImpl;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
8 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
9 | import org.springframework.context.annotation.Bean;
10 | import org.springframework.context.annotation.Configuration;
11 |
12 | /**
13 | * aliyun oss auto configuration
14 | *
15 | * @author linux_china
16 | */
17 | @Configuration
18 | @ConditionalOnClass(OSSClient.class)
19 | @EnableConfigurationProperties(AliyunOssProperties.class)
20 | public class AliyunOssAutoConfiguration {
21 | @SuppressWarnings("SpringJavaAutowiringInspection")
22 | @Autowired
23 | private AliyunOssProperties properties;
24 |
25 | @Bean
26 | @ConditionalOnMissingBean
27 | public OSSClient ossClient() {
28 | return new OSSClient(properties.getEndpoint(), properties.getKey(), properties.getSecret());
29 | }
30 |
31 | @Bean
32 | @ConditionalOnMissingBean
33 | public FileStorageService fileStorageService() {
34 | FileStorageServiceOssImpl fileStorageServiceOss = new FileStorageServiceOssImpl();
35 | fileStorageServiceOss.setAccessKey(properties.getKey());
36 | fileStorageServiceOss.setAccessSecret(properties.getSecret());
37 | fileStorageServiceOss.setBucketName(properties.getBucket());
38 | return fileStorageServiceOss;
39 | }
40 |
41 | @Bean
42 | public AliyunOssHealthIndicator aliyunOssHealthIndicator() {
43 | return new AliyunOssHealthIndicator();
44 | }
45 |
46 | @Bean
47 | public AliyunOssMetrics aliyunOssMetrics() {
48 | return new AliyunOssMetrics();
49 | }
50 |
51 | @Bean
52 | public AliyunOssEndpoint aliyunOssEndpoint() {
53 | return new AliyunOssEndpoint();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/org/mvnsearch/boot/oss/AliyunOssEndpoint.java:
--------------------------------------------------------------------------------
1 | package org.mvnsearch.boot.oss;
2 |
3 | import org.mvnsearch.boot.oss.impl.FileStorageServiceOssImpl;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
6 | import org.springframework.boot.context.properties.ConfigurationProperties;
7 |
8 | import java.util.HashMap;
9 | import java.util.Map;
10 |
11 | /**
12 | * aliyun OSS endpoint
13 | *
14 | * @author linux_china
15 | */
16 | @ConfigurationProperties(prefix = "endpoints.aliyunoss", ignoreUnknownFields = false)
17 | public class AliyunOssEndpoint extends AbstractEndpoint {
18 | private AliyunOssProperties properties;
19 |
20 | public AliyunOssEndpoint() {
21 | super("oss", false, true);
22 | }
23 |
24 | @Autowired
25 | public void setTairProperties(AliyunOssProperties properties) {
26 | this.properties = properties;
27 | }
28 |
29 | public Object invoke() {
30 | Map info = new HashMap();
31 | info.put("version", "2.2.1");
32 | info.put("vendor", "http://www.aliyun.com/");
33 | info.put("bucket", properties.getBucket());
34 | info.put("upload.success", FileStorageServiceOssImpl.fileUploadSuccess.get());
35 | info.put("upload.fail", FileStorageServiceOssImpl.fileUploadFail.get());
36 | info.put("get.count", FileStorageServiceOssImpl.fileGetCounts.get());
37 | info.put("delete.count", FileStorageServiceOssImpl.fileDeleteCounts.get());
38 | return info;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/org/mvnsearch/boot/oss/AliyunOssHealthIndicator.java:
--------------------------------------------------------------------------------
1 | package org.mvnsearch.boot.oss;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.boot.actuate.health.AbstractHealthIndicator;
5 | import org.springframework.boot.actuate.health.Health;
6 | import org.springframework.boot.actuate.health.HealthIndicator;
7 | import org.springframework.stereotype.Component;
8 |
9 | import javax.activation.DataSource;
10 |
11 | /**
12 | * aliyun oss health indicator
13 | *
14 | * @author linux_china
15 | */
16 | @Component
17 | public class AliyunOssHealthIndicator extends AbstractHealthIndicator {
18 | @Autowired
19 | private FileStorageService fileStorageService;
20 |
21 | protected void doHealthCheck(Health.Builder builder) throws Exception {
22 | DataSource ds = fileStorageService.get("ok.txt");
23 | if (ds != null) {
24 | builder.up().withDetail("ok.txt", "Found");
25 | } else {
26 | builder.down().withDetail("ok.txt", "Not found");
27 | }
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/org/mvnsearch/boot/oss/AliyunOssMetrics.java:
--------------------------------------------------------------------------------
1 | package org.mvnsearch.boot.oss;
2 |
3 | import org.mvnsearch.boot.oss.impl.FileStorageServiceOssImpl;
4 | import org.springframework.boot.actuate.endpoint.PublicMetrics;
5 | import org.springframework.boot.actuate.metrics.Metric;
6 | import org.springframework.stereotype.Component;
7 |
8 | import java.util.Collection;
9 | import java.util.LinkedList;
10 | import java.util.List;
11 |
12 | /**
13 | * aliyun OSS metrics
14 | *
15 | * @author linux_china
16 | */
17 | @Component
18 | public class AliyunOssMetrics implements PublicMetrics {
19 |
20 | public Collection> metrics() {
21 | List> metrics = new LinkedList>();
22 | metrics.add(new Metric("oss.upload.success", FileStorageServiceOssImpl.fileUploadSuccess.get()));
23 | metrics.add(new Metric("oss.upload.fail", FileStorageServiceOssImpl.fileUploadFail.get()));
24 | metrics.add(new Metric("oss.get.count", FileStorageServiceOssImpl.fileGetCounts.get()));
25 | metrics.add(new Metric("oss.delete.count", FileStorageServiceOssImpl.fileDeleteCounts.get()));
26 | return metrics;
27 | }
28 |
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/org/mvnsearch/boot/oss/AliyunOssProperties.java:
--------------------------------------------------------------------------------
1 | package org.mvnsearch.boot.oss;
2 |
3 | import org.springframework.boot.context.properties.ConfigurationProperties;
4 |
5 | /**
6 | * aliyun oss properties
7 | *
8 | * @author linux_china
9 | */
10 | @ConfigurationProperties(
11 | prefix = "spring.oss"
12 | )
13 | public class AliyunOssProperties {
14 | /**
15 | * aliyun access key
16 | */
17 | private String key;
18 | /**
19 | * aliyun access secret
20 | */
21 | private String secret;
22 | /**
23 | * default bucket
24 | */
25 | private String bucket;
26 | /**
27 | * endpoint
28 | */
29 | private String endpoint = "http://oss.aliyuncs.com";
30 |
31 | public String getKey() {
32 | return key;
33 | }
34 |
35 | public void setKey(String key) {
36 | this.key = key;
37 | }
38 |
39 | public String getSecret() {
40 | return secret;
41 | }
42 |
43 | public void setSecret(String secret) {
44 | this.secret = secret;
45 | }
46 |
47 | public String getBucket() {
48 | return bucket;
49 | }
50 |
51 | public void setBucket(String bucket) {
52 | this.bucket = bucket;
53 | }
54 |
55 | public String getEndpoint() {
56 | return endpoint;
57 | }
58 |
59 | public void setEndpoint(String endpoint) {
60 | this.endpoint = endpoint;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/org/mvnsearch/boot/oss/ByteArrayDataSource.java:
--------------------------------------------------------------------------------
1 | package org.mvnsearch.boot.oss;
2 |
3 |
4 | import java.io.*;
5 | import javax.activation.*;
6 |
7 | /**
8 | * A DataSource backed by a byte array. The byte array may be
9 | * passed in directly, or may be initialized from an InputStream
10 | * or a String.
11 | *
12 | * @author John Mani
13 | * @author Bill Shannon
14 | * @author Max Spivak
15 | * @since JavaMail 1.4
16 | */
17 | public class ByteArrayDataSource implements DataSource {
18 | private byte[] data; // data
19 | private int len = -1;
20 | private String type; // content-type
21 | private String name = "";
22 |
23 | static class DSByteArrayOutputStream extends ByteArrayOutputStream {
24 | public byte[] getBuf() {
25 | return buf;
26 | }
27 |
28 | public int getCount() {
29 | return count;
30 | }
31 | }
32 |
33 | /**
34 | * Create a ByteArrayDataSource with data from the
35 | * specified InputStream and with the specified MIME type.
36 | * The InputStream is read completely and the data is
37 | * stored in a byte array.
38 | *
39 | * @param is the InputStream
40 | * @param type the MIME type
41 | * @throws IOException errors reading the stream
42 | */
43 | public ByteArrayDataSource(InputStream is, String type) throws IOException {
44 | DSByteArrayOutputStream os = new DSByteArrayOutputStream();
45 | byte[] buf = new byte[8192];
46 | int len;
47 | while ((len = is.read(buf)) > 0)
48 | os.write(buf, 0, len);
49 | this.data = os.getBuf();
50 | this.len = os.getCount();
51 |
52 | /*
53 | * ByteArrayOutputStream doubles the size of the buffer every time
54 | * it needs to expand, which can waste a lot of memory in the worst
55 | * case with large buffers. Check how much is wasted here and if
56 | * it's too much, copy the data into a new buffer and allow the
57 | * old buffer to be garbage collected.
58 | */
59 | if (this.data.length - this.len > 256 * 1024) {
60 | this.data = os.toByteArray();
61 | this.len = this.data.length; // should be the same
62 | }
63 | this.type = type;
64 | }
65 |
66 | /**
67 | * Create a ByteArrayDataSource with data from the
68 | * specified byte array and with the specified MIME type.
69 | *
70 | * @param data the data
71 | * @param type the MIME type
72 | */
73 | public ByteArrayDataSource(byte[] data, String type) {
74 | this.data = data;
75 | this.type = type;
76 | }
77 |
78 | /**
79 | * Create a ByteArrayDataSource with data from the
80 | * specified String and with the specified MIME type.
81 | * The MIME type should include a charset
82 | * parameter specifying the charset to be used for the
83 | * string. If the parameter is not included, the
84 | * default charset is used.
85 | *
86 | * @param data the String
87 | * @param type the MIME type
88 | * @throws IOException errors reading the String
89 | */
90 | public ByteArrayDataSource(String data, String type) throws IOException {
91 | this.data = data.getBytes();
92 | this.type = type;
93 | }
94 |
95 | /**
96 | * Return an InputStream for the data.
97 | * Note that a new stream is returned each time
98 | * this method is called.
99 | *
100 | * @return the InputStream
101 | * @throws IOException if no data has been set
102 | */
103 | public InputStream getInputStream() throws IOException {
104 | if (data == null)
105 | throw new IOException("no data");
106 | if (len < 0)
107 | len = data.length;
108 | return new ByteArrayInputStream(data, 0, len);
109 | }
110 |
111 | /**
112 | * Return an OutputStream for the data.
113 | * Writing the data is not supported; an IOException
114 | * is always thrown.
115 | *
116 | * @throws IOException always
117 | */
118 | public OutputStream getOutputStream() throws IOException {
119 | throw new IOException("cannot do this");
120 | }
121 |
122 | /**
123 | * Get the MIME content type of the data.
124 | *
125 | * @return the MIME type
126 | */
127 | public String getContentType() {
128 | return type;
129 | }
130 |
131 | /**
132 | * Get the name of the data.
133 | * By default, an empty string ("") is returned.
134 | *
135 | * @return the name of this data
136 | */
137 | public String getName() {
138 | return name;
139 | }
140 |
141 | /**
142 | * Set the name of the data.
143 | *
144 | * @param name the name of this data
145 | */
146 | public void setName(String name) {
147 | this.name = name;
148 | }
149 | }
--------------------------------------------------------------------------------
/src/main/java/org/mvnsearch/boot/oss/FileStorageService.java:
--------------------------------------------------------------------------------
1 | package org.mvnsearch.boot.oss;
2 |
3 | import javax.activation.DataSource;
4 | import java.io.IOException;
5 |
6 | /**
7 | * file storage service
8 | *
9 | * @author linux_china
10 | */
11 | public interface FileStorageService {
12 |
13 | /**
14 | * save file
15 | *
16 | * @param ds data source
17 | * @return file name
18 | * @throws IOException IO Exception
19 | */
20 | public String save(DataSource ds) throws IOException;
21 |
22 | /**
23 | * save file to the directory
24 | *
25 | * @param directory directory
26 | * @param ds data source
27 | * @return file name with directory name
28 | * @throws IOException IO Exception
29 | */
30 | public String saveToDirectory(String directory, DataSource ds) throws IOException;
31 |
32 | /**
33 | * delete file
34 | *
35 | * @param fileName file name
36 | * @throws IOException IO Exception
37 | */
38 | public void delete(String fileName) throws IOException;
39 |
40 | /**
41 | * get file data source
42 | *
43 | * @param fileName file name
44 | * @return file data source
45 | * @throws IOException IO Exception
46 | */
47 | public DataSource get(String fileName) throws IOException;
48 |
49 | public void rename(String oldName, String newName) throws IOException;
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/org/mvnsearch/boot/oss/impl/FileStorageServiceOssImpl.java:
--------------------------------------------------------------------------------
1 | package org.mvnsearch.boot.oss.impl;
2 |
3 | import com.aliyun.oss.OSSClient;
4 | import com.aliyun.oss.model.OSSObject;
5 | import com.aliyun.oss.model.ObjectMetadata;
6 | import org.apache.commons.io.IOUtils;
7 | import org.mvnsearch.boot.oss.ByteArrayDataSource;
8 | import org.mvnsearch.boot.oss.FileStorageService;
9 | import org.springframework.beans.factory.InitializingBean;
10 |
11 | import javax.activation.DataSource;
12 | import javax.activation.MimetypesFileTypeMap;
13 | import java.io.ByteArrayInputStream;
14 | import java.io.IOException;
15 | import java.util.UUID;
16 | import java.util.concurrent.atomic.AtomicLong;
17 |
18 | /**
19 | * file storage service OSS implementation
20 | *
21 | * @author linux_china
22 | */
23 | public class FileStorageServiceOssImpl implements FileStorageService, InitializingBean {
24 | String accessKey;
25 | String accessSecret;
26 | String bucketName;
27 | public static MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
28 | public static String DEFAULT_CONTENT_TYPE = "application/octet-stream";
29 | public static final AtomicLong fileUploadSuccess = new AtomicLong();
30 | public static final AtomicLong fileUploadFail = new AtomicLong();
31 | public static final AtomicLong fileGetCounts = new AtomicLong();
32 | public static final AtomicLong fileDeleteCounts = new AtomicLong();
33 | /**
34 | * oss client
35 | */
36 | private OSSClient ossClient;
37 |
38 | public void setAccessKey(String accessKey) {
39 | this.accessKey = accessKey;
40 | }
41 |
42 | public void setAccessSecret(String accessSecret) {
43 | this.accessSecret = accessSecret;
44 | }
45 |
46 | public void setBucketName(String bucketName) {
47 | this.bucketName = bucketName;
48 | }
49 |
50 | @SuppressWarnings("deprecation")
51 | public void afterPropertiesSet() throws Exception {
52 | this.ossClient = new OSSClient(accessKey, accessSecret);
53 | }
54 |
55 | /**
56 | * save file
57 | *
58 | * @param ds data source
59 | * @return file name
60 | * @throws IOException IO Exception
61 | */
62 | public String save(DataSource ds) throws IOException {
63 | String newName;
64 | newName = getUuidName(ds.getName());
65 | byte[] content = IOUtils.toByteArray(ds.getInputStream());
66 | upload(bucketName, newName, content);
67 | return newName;
68 | }
69 |
70 | /**
71 | * save file to the directory
72 | *
73 | * @param directory directory
74 | * @param ds data source
75 | * @return file name with directory name
76 | * @throws IOException IO Exception
77 | */
78 | public String saveToDirectory(String directory, DataSource ds) throws IOException {
79 | String newName;
80 | newName = directory + "/" + getUuidName(ds.getName());
81 | byte[] content = IOUtils.toByteArray(ds.getInputStream());
82 | upload(bucketName, newName, content);
83 | return newName;
84 | }
85 |
86 | /**
87 | * delete file
88 | *
89 | * @param fileName file name
90 | * @throws IOException IO Exception
91 | */
92 | public void delete(String fileName) throws IOException {
93 | ossClient.deleteObject(bucketName, fileName);
94 | fileDeleteCounts.incrementAndGet();
95 | }
96 |
97 | /**
98 | * get file data source
99 | *
100 | * @param fileName file name
101 | * @return file data source
102 | * @throws IOException IO Exception
103 | */
104 | public DataSource get(String fileName) throws IOException {
105 | OSSObject ossObject = ossClient.getObject(bucketName, fileName);
106 | if (ossObject != null) {
107 | ByteArrayDataSource ds = new ByteArrayDataSource(IOUtils.toByteArray(ossObject.getObjectContent()), getContentType(fileName));
108 | ds.setName(fileName);
109 | fileGetCounts.incrementAndGet();
110 | return ds;
111 | }
112 | return null;
113 | }
114 |
115 |
116 | public void rename(String oldName, String newName) throws IOException {
117 | boolean keyExists = true;
118 | try {
119 | ossClient.getObjectMetadata(bucketName, oldName);
120 | } catch (Exception e) {
121 | keyExists = false;
122 | }
123 | if (keyExists) {
124 | ossClient.copyObject(bucketName, oldName, bucketName, newName);
125 | }
126 | }
127 |
128 | public static String getUuidName(String name) {
129 | String uuid = UUID.randomUUID().toString().replaceAll("\\-", "");
130 | String newName = uuid;
131 | if (name != null && name.contains(".")) {
132 | newName = uuid + name.substring(name.lastIndexOf(".")).toLowerCase();
133 | }
134 | return newName;
135 | }
136 |
137 | /**
138 | * upload to bucket
139 | *
140 | * @param bucketName bucket name
141 | * @param fileName file name
142 | * @param content content
143 | */
144 | private void upload(String bucketName, String fileName, byte[] content) throws IOException {
145 | ObjectMetadata metadata = new ObjectMetadata();
146 | ByteArrayInputStream bis = new ByteArrayInputStream(content);
147 | try {
148 | metadata.setContentType(getContentType(fileName));
149 | metadata.setContentLength(content.length);
150 | metadata.setCacheControl("public, max-age=31536000");
151 | ossClient.putObject(bucketName, fileName, bis, metadata);
152 | fileUploadSuccess.incrementAndGet();
153 | } catch (Exception ignore) {
154 | ossClient.putObject(bucketName, fileName, bis, metadata);
155 | fileUploadFail.incrementAndGet();
156 | }
157 | }
158 |
159 | /**
160 | * get content type according to name or ext, default is "application/octet-stream"
161 | *
162 | * @param fileNameOrExt file name or ext name
163 | * @return content type
164 | */
165 | public String getContentType(String fileNameOrExt) {
166 | if (fileNameOrExt == null || fileNameOrExt.isEmpty()) {
167 | return DEFAULT_CONTENT_TYPE;
168 | }
169 | return fileTypeMap.getContentType(fileNameOrExt.toLowerCase());
170 | }
171 |
172 |
173 | }
174 |
--------------------------------------------------------------------------------
/src/main/resources/META-INF/spring.factories:
--------------------------------------------------------------------------------
1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2 | org.mvnsearch.boot.oss.AliyunOssAutoConfiguration
3 |
--------------------------------------------------------------------------------
/src/main/resources/META-INF/spring.provides:
--------------------------------------------------------------------------------
1 | provides: spring-boot-starter-oss
--------------------------------------------------------------------------------
/src/test/java/org/mvnsearch/boot/AliyunOssAutoConfigurationTest.java:
--------------------------------------------------------------------------------
1 | package org.mvnsearch.boot;
2 |
3 | import com.aliyun.oss.OSSClient;
4 | import org.apache.commons.io.IOUtils;
5 | import org.junit.After;
6 | import org.junit.Assert;
7 | import org.junit.Before;
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 | import org.mvnsearch.boot.oss.AliyunOssAutoConfiguration;
11 | import org.mvnsearch.boot.oss.AliyunOssProperties;
12 | import org.mvnsearch.boot.oss.ByteArrayDataSource;
13 | import org.mvnsearch.boot.oss.FileStorageService;
14 | import org.springframework.beans.factory.annotation.Autowired;
15 | import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
16 | import org.springframework.boot.test.SpringApplicationConfiguration;
17 | import org.springframework.context.ApplicationContext;
18 | import org.springframework.context.annotation.AnnotationConfigApplicationContext;
19 | import org.springframework.context.annotation.Bean;
20 | import org.springframework.context.annotation.Configuration;
21 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
22 |
23 | import javax.activation.DataSource;
24 |
25 | /**
26 | * aliyun oss auto configuration test
27 | *
28 | * @author linux_china
29 | */
30 | @RunWith(SpringJUnit4ClassRunner.class)
31 | @SpringApplicationConfiguration(classes = OssTestApplication.class)
32 | public class AliyunOssAutoConfigurationTest {
33 | @Autowired
34 | private ApplicationContext context;
35 |
36 | @Test
37 | public void clientExists() {
38 | Assert.assertEquals(1, this.context.getBeanNamesForType(OSSClient.class).length);
39 | Assert.assertEquals(1, this.context.getBeanNamesForType(FileStorageService.class).length);
40 | }
41 |
42 | @Test
43 | public void testSave() throws Exception {
44 | byte[] content = IOUtils.toByteArray(this.getClass().getResourceAsStream("/1.jpg"));
45 | ByteArrayDataSource bads = new ByteArrayDataSource(content, "image/jpeg");
46 | bads.setName("1.jpg");
47 | FileStorageService fileStorageService = context.getBean(FileStorageService.class);
48 | String newFileName = fileStorageService.save(bads);
49 | DataSource fileDS = fileStorageService.get(newFileName);
50 | Assert.assertNotNull(fileDS);
51 | fileStorageService.delete(newFileName);
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/test/java/org/mvnsearch/boot/OssTestApplication.java:
--------------------------------------------------------------------------------
1 | package org.mvnsearch.boot;
2 |
3 | import org.springframework.boot.autoconfigure.SpringBootApplication;
4 | import org.springframework.context.annotation.ImportResource;
5 | import org.springframework.context.annotation.PropertySource;
6 |
7 | /**
8 | * oss test application
9 | *
10 | * @author linux_china
11 | */
12 | @SpringBootApplication
13 | @PropertySource("/application.properties")
14 | public class OssTestApplication {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/test/resources/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linux-china/spring-boot-starter-oss/58120c5aeef82c56f90fe69959b5aa3c6ff8edca/src/test/resources/1.jpg
--------------------------------------------------------------------------------
/src/test/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.oss.key=xxxx
2 | spring.oss.secret=yyyy
3 | spring.oss.bucket=zzzz-dev
--------------------------------------------------------------------------------
/src/test/resources/demo-context.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------