对象存储OSS之创建OSS微服务
2020-10-23 本文已影响0人
勿念及时雨
之前已经学习了OSS的一些基本API,接下来可以在微服务中使用它了。
创建OSS微服务
1、创建SpringBoot微服务wunian-edu-oss,然后在pom.xml中导入相关依赖。
<!-- 配置OSS依赖 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<!-- 如果你要使用oss,就导入这个依赖即可! -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
</dependency>
<!--日期时间工具-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.1</version>
</dependency>
<!--热部署工具-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
2、在application.properties中添加相关配置。
# server
server.port=8130
# 服务名
spring.application.name=wunian-aliyunoss
# 环境
spring.profiles.active=dev
# 配置OSS的参数,自定义参数进行加载,以下参数从阿里云OSS账户中获取
aliyun.oss.file.endpoint=oss-cn-beijing.aliyuncs.com
aliyun.oss.file.accessKeyId=LTAI4FfEx3TmDfjemSd2Y7Q2
aliyun.oss.file.accessKeySecret=zopf47hTj40JsFb8PTxoGHKEMRaAvi
# 可以在控制台创建,也可以在代码中创建
aliyun.oss.file.bucketName=wunian-edu
aliyun.oss.file.filehost=avatar
3、在日志配置文件logback-spring.xml中配置日志相关参数。
<?xml version="1.0" encoding="UTF-8"?>
<!-- 以后这个文件只需要改几个地方! -->
<configuration scan="true" scanPeriod="10 seconds">
<!-- 日志级别从低到高分为TRACE < DEBUG(开发) < INFO(SpringBoot默认的!) < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<contextName>logback</contextName>
<!--输出文件的位置!-->
<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
<property name="log.path" value="D:/Files/Project/代码/wunian_edu_api/log/oss/" />
<!-- 彩色日志 -->
<!-- 配置格式变量:CONSOLE_LOG_PATTERN 彩色日志格式 -->
<!-- magenta:洋红 -->
<!-- boldMagenta:粗红-->
<!-- cyan:青色 -->
<!-- white:白色 -->
<!-- magenta:洋红 -->
<property name="CONSOLE_LOG_PATTERN"
value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) |%highlight(%-5level) |%blue(%thread) |%blue(%file:%line) |%green(%logger) |%cyan(%msg%n)"/>
<!--输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<!-- 例如:如果此处配置了INFO级别,则后面其他位置即使配置了DEBUG级别的日志,也不会被输出 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!--输出到文件-->
<!-- 时间滚动输出 level为 INFO 日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_info.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 WARN 日志 -->
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_warn.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 ERROR 日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_error.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录ERROR级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--
<logger>用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>。
<logger>仅有一个name属性,
一个可选的level和一个可选的addtivity属性。
name:用来指定受此logger约束的某一个包或者具体的某一个类。
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
如果未设置此属性,那么当前logger将会继承上级的级别。
-->
<!--
使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
第一种把<root level="INFO">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
第二种就是单独给mapper下目录配置DEBUG模式,代码如下,这样配置sql语句会打印,其他还是正常DEBUG级别:
-->
<!--开发环境:打印控制台-->
<!-- 和我们项目的环境对应一定要! -->
<springProfile name="dev">
<!--可以输出项目中的debug日志,包括mybatis的sql日志-->
<logger name="com.coding" level="INFO" />
<!--
root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,默认是DEBUG
可以包含零个或多个appender元素。
-->
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
</springProfile>
<!-- 日志在生成环境中的级别一定要提高,保证效率! -->
<!--生产环境:输出到文件-->
<springProfile name="pro">
<!--可以输出项目中的debug日志,包括mybatis的sql日志-->
<logger name="com.coding" level="WARN" />
<root level="INFO">
<appender-ref ref="ERROR_FILE" />
<appender-ref ref="WARN_FILE" />
</root>
</springProfile>
</configuration>
4、创建读取配置文件的工具类,实现InitializingBean接口。重写afterPropertiesSet()方法,该方法将在所有属性配置被初始化的时候调用。
@Component //读取配置文件
public class ConstantProperties implements InitializingBean {
@Value("${aliyun.oss.file.endpoint}")
private String endpoint;
@Value("${aliyun.oss.file.accessKeyId}")
private String accessKeyId;
@Value("${aliyun.oss.file.accessKeySecret}")
private String accessKeySecret;
@Value("${aliyun.oss.file.bucketName}")
private String bucketName;
@Value("${aliyun.oss.file.filehost}")
private String fileHost;
//方便未来使用
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 = accessKeyId;
ACCESS_KEY_SECRET = accessKeySecret;
BUCKET_NAME = bucketName;
FILE_HOST = fileHost;
}
}
5、编写文件上传服务接口和实现类,实现文件上传阿里云服务器方法。
FileService.java
public interface FileService{
String upload(MultipartFile file);//文件上传到阿里云服务器
}
FileServiceImpl.java
@Service
public class FileServiceImpl implements FileService{
@Override
public String upload(MultipartFile file){
// 基本配置,可以变化的,通过配置文件变化,不需要改代码(降低耦合性)
String endpoint = ConstantProperties.END_POINT;
String accessKeyId = ConstantProperties.ACCESS_KEY_ID;
String accessKeySecret = ConstantProperties.ACCESS_KEY_SECRET;
String bucketName = ConstantProperties.BUCKET_NAME;
String fileHost = ConstantProperties.FILE_HOST;
String uploadUrl = null;
try {
// 判断oss 是否存在
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 不存在就创建
if (!ossClient.doesBucketExist(bucketName)){
ossClient.createBucket(bucketName);
ossClient.setBucketAcl(bucketName,CannedAccessControlList.PublicRead);
}
// 获取文件上传流
InputStream inputStream = file.getInputStream();
// 保存到oss路径(重写文件名称,文件分类:上传文件的核心思想)
String filePath = new DateTime().toString("yyyy/MM/dd");
// 文件名 uuid
String original = file.getOriginalFilename(); // a.jpg
String fileName = UUID.randomUUID().toString();
String fileType = original.substring(original.lastIndexOf("."));
String newName = fileName + fileType; // 我们处理完毕的思想
// 构建完成路径
String fileUrl = fileHost + "/" + filePath + "/" + newName;
// 文件上传到阿里云
ossClient.putObject(bucketName,fileUrl,inputStream);
// 关闭连接
ossClient.shutdown();
// 获取上传后的文件地址
uploadUrl = "https://" + bucketName + "." + endpoint + "/" + fileUrl;
} catch (IOException e) {
e.printStackTrace();
}
return uploadUrl;
}
}
6、编写文件上传控制类,添加文件上传请求方法。
@Api(description = "阿里云文件管理")
@RestController
@CrossOrigin // 跨域
@RequestMapping("/admin/oss/file")
public class FileController {
@Autowired
private FileService fileService;
@ApiOperation(value = "文件上传")
@PostMapping("upload")
public R upload(
@ApiParam(name = "file",value = "文件",required = true)
@RequestParam MultipartFile file){
String uploadUrl = fileService.upload(file);
return R.ok().message("文件上传成功").data("url",uploadUrl);
}
}
7、编写Swagger配置类,添加Swagger配置方法。
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket webApiConfig(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(webApiInfo())
.select()
.paths(Predicates.not(PathSelectors.regex("/error.*")))
.build();
}
private ApiInfo webApiInfo(){
return new ApiInfoBuilder()
.title("文件上传微服务")
.description("本文档描述了文件上传微服务接口定义")
.version("1.0")
.contact(new Contact("wunian", "http://wunianedu.com", "XXXXXX@qq.com"))
.build();
}
}
8、启动微服务,访问http://localhost:8130/swagger-ui.html 查看Swagger文档,可以直接在Swagger文档页面对接口进行测试。