一、环境准备

  • idea 2020 版本
  • JDK 8
  • Maven
  • 阿里OSS 对象储存
  • Springboot 2.1.18

参考: 阿里OSS 对象储存 :OSS文档:https://help.aliyun.com/product/31815.html

二、项目搭建

1、创建SprinBoot 项目

使用 Spring Initilizr 项目向导

image-20210306230632448

Choose starter service URL 建议使用阿里的镜像源: https://start.aliyun.com , spring官方的镜像源容易无法加载。

image-20210306231011636

image-20210306231130212

2、POM依赖

添加依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<dependencies>
<!--aliyunOSS-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.3</version>
</dependency>

<!--日期时间工具-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.1</version>
</dependency>

<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>

<!--lombok用来简化实体类:需要安装lombok插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>

3、application.properties 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 应用名称
spring.application.name=alioss
# 应用服务 WEB 访问端口
server.port=8080

#阿里云 OSS
#不同的服务器,地址不同,其它Region请按实际情况填写。
aliyun.oss.file.endpoint=oss-cn-shenzhen.aliyuncs.com
# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。
aliyun.oss.file.keyid=<yourAccessKeyId>
aliyun.oss.file.keysecret=<yourAccessKeySecret>
#bucket可以在控制台创建,也可以使用java代码创建
aliyun.oss.file.bucketname=oypicbed
aliyun.oss.file.filehost=ossTest

注意:aliyun.oss.file.endpointaliyun.oss.file.keyidaliyun.oss.file.keysecret 需要自己配置

4、启动类

1
2
3
4
5
6
7
8
9
10
11
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AliossApplication {

public static void main(String[] args) {
SpringApplication.run(AliossApplication.class, args);
}

}

5、结构代码编写

utils

InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class ConstantPropertiesUtil implements InitializingBean {
@Value("${aliyun.oss.file.endpoint}")
private String endpoint;

@Value("${aliyun.oss.file.keyid}")
private String keyId;

@Value("${aliyun.oss.file.keysecret}")
private String keySecret;

@Value("${aliyun.oss.file.filehost}")
private String fileHost;

@Value("${aliyun.oss.file.bucketname}")
private String bucketName;

public static String END_POINT;
public static String ACCESS_KEY_ID;
public static String ACCESS_KEY_SECRET;
public static String BUCKET_NAME;
public static String FILE_HOST ;

@Override
public void afterPropertiesSet() throws Exception {
END_POINT = endpoint;
ACCESS_KEY_ID = keyId;
ACCESS_KEY_SECRET = keySecret;
BUCKET_NAME = bucketName;
FILE_HOST = fileHost;
}
}

result

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.HashMap;
import java.util.Map;

@Data
@ApiModel(value = "全局统一返回结果")
public class Result {

@ApiModelProperty(value = "是否成功")
private boolean success;

@ApiModelProperty(value = "返回码")
private Integer code;

@ApiModelProperty(value = "返回消息")
private String message;

@ApiModelProperty(value = "返回数据")
private Map<String, Object> data = new HashMap<String, Object>();

private Result(){}

public static Result ok(){
Result r = new Result();
r.setSuccess(true);
r.setCode(ResultCode.OK);
r.setMessage("成功");
return r;
}

public static Result error(){
Result r = new Result();
r.setSuccess(false);
r.setCode(ResultCode.ERROR);
r.setMessage("失败");
return r;
}

public Result message(String message){
this.setMessage(message);
return this;
}

public Result code(Integer code){
this.setCode(code);
return this;
}

public Result data(String key, Object value){
this.data.put(key, value);
return this;
}

public Result data(Map<String, Object> map){
this.setData(map);
return this;
}

}
1
2
3
4
5
6
7
8
9
public interface ResultCode {

int OK = 20000; // 成功

int ERROR = 20001; // 失败

int EDU_ID_ERROR = 20002;

}

controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import com.oy.oss.result.Result;
import com.oy.oss.service.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequestMapping("oss")
@CrossOrigin
public class FileController {

@Autowired
FileService fileService;

/**
* 上传文件、接收请求、返回响应
* @param file
* @return
*/
@PostMapping("file/upload")
public Result upload(MultipartFile file){
String url = fileService.upload(file);
if(!StringUtils.isEmpty(url)){
return Result.ok().data("url",url);
}
return Result.error().message("上次失败");
}
}

service

1
2
3
public interface FileService {
String upload(MultipartFile file);
}

service 实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import com.aliyun.oss.OSSClient;
import com.oy.oss.service.FileService;
import com.oy.oss.utils.ConstantPropertiesUtil;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.util.UUID;

@Service
public class FileServiceImpl implements FileService {

// 图片类型
private static String TYPESTR[] = {".png",".jpg",".bmp",".gif",".jpeg"};

@Override
public String upload(MultipartFile file) {


OSSClient ossClient = null;
String url = null;

try {
// 创建OSSClient 实例
ossClient = new OSSClient(ConstantPropertiesUtil.END_POINT,
ConstantPropertiesUtil.ACCESS_KEY_ID ,
ConstantPropertiesUtil.ACCESS_KEY_SECRET );

boolean flag = false;
// 判断 文件格式
for(String type : TYPESTR){
if(StringUtils.endsWithIgnoreCase(file.getOriginalFilename(),type)){
flag = true;
break;
}
}

if(!flag){
return "图片格式不正确";
}
// 判断文件内容
BufferedImage image = ImageIO.read(file.getInputStream());
if(image != null){
System.err.println(String.valueOf(image.getHeight()));
System.err.println(String.valueOf(image.getWidth()));
}else{
return "文件内容不正确";
}

// 获取文件名称
String filename = file.getOriginalFilename();
// 文件名字: oy.01.jpg
String ext = filename.substring(filename.lastIndexOf("."));
String newName = UUID.randomUUID().toString() +ext;
String dataPath = new DateTime().toString("yyyy/MM/dd");
String urlPath = ConstantPropertiesUtil.FILE_HOST+"/"+dataPath+"/"+newName;

// 上传文件流
InputStream inputStream = file.getInputStream();
ossClient.putObject(ConstantPropertiesUtil.BUCKET_NAME,urlPath,inputStream);
url = "https://"+ConstantPropertiesUtil.BUCKET_NAME +"."+ConstantPropertiesUtil.END_POINT+"/"+urlPath;

} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭OSSClient.
ossClient.shutdown();
}
return url;
}
}

config

  • 项目使用swagger 来测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class Swagger2Config {

@Bean
public Docket webApiConfig(){

return new Docket(DocumentationType.SWAGGER_2)
.groupName("webApi")
.apiInfo(webApiInfo())
.select()
.build();

}

private ApiInfo webApiInfo(){

return new ApiInfoBuilder()
.title("网站-OSSAPI文档")
.description("本文档描述了OSS服务接口定义")
.version("1.0")
.contact(new Contact("OY", "http://oy6090.com", "2097291754@qq.com"))
.build();
}

}

三、测试

image-20210306234029377

  • 测试成功

image-20210306234118494