> 文章列表 > 项目7:(aliyun)实现短信的发送和验证微服务和上传文件删除文件微服务

项目7:(aliyun)实现短信的发送和验证微服务和上传文件删除文件微服务

项目7:(aliyun)实现短信的发送和验证微服务和上传文件删除文件微服务

项目7:实现短信的发送和验证

1.对gulimall-common补充

2.短信验证的流程(aliyun的sms)

3.具体接口的编写(新建微服务service-sms)

4.上传和删除文件流程(aliyun的oss)

5.具体接口的编写(新建微服务service-oos)

未更新

项目7:实现短信的发送和验证

1.引入工具包

①gulimall-common和service-base放什么?

  • gulimall-common写全局用的工具包
    全局异常处理
    全局返回值
    工具包(生成随机数,校验手机号)
  • service-base写服务的配置
    redis配置类序列化的方式
    swagger文档生成分组

②生成四位或六位随机数

package com.atguigu.common.util;import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;/* 生成四位和六位的随机数字*/
public class RandomUtils {private static final Random random = new Random();private static final DecimalFormat fourdf = new DecimalFormat("0000");private static final DecimalFormat sixdf = new DecimalFormat("000000");public static String getFourBitRandom() {return fourdf.format(random.nextInt(10000));}public static String getSixBitRandom() {return sixdf.format(random.nextInt(1000000));}/* 给定数组,抽取n个数据* @param list* @param n* @return*/public static ArrayList getRandom(List list, int n) {Random random = new Random();HashMap<Object, Object> hashMap = new HashMap<Object, Object>();// 生成随机数字并存入HashMapfor (int i = 0; i < list.size(); i++) {int number = random.nextInt(100) + 1;hashMap.put(number, i);}// 从HashMap导入数组Object[] robjs = hashMap.values().toArray();ArrayList r = new ArrayList();// 遍历数组并打印数据for (int i = 0; i < n; i++) {r.add(list.get((int) robjs[i]));System.out.print(list.get((int) robjs[i]) + "\\t");}System.out.print("\\n");return r;}
}

③校验手机号码正确

package com.atguigu.common.util;import java.util.regex.Matcher;
import java.util.regex.Pattern;/* 使用正则表达式进行表单验证*/
public class RegexValidateUtils {static boolean flag = false;static String regex = "";public static boolean check(String str, String regex) {try {Pattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(str);flag = matcher.matches();} catch (Exception e) {flag = false;}return flag;}/* 验证邮箱 @param email* @return*/public static boolean checkEmail(String email) {String regex = "^\\\\w+[-+.]\\\\w+)*@\\\\w+([-.]\\\\w+)*\\\\.\\\\w+([-.]\\\\w+)*$ ";return check(email, regex);}/* 验证手机号码 移动号码段:139、138、137、136、135、134、150、151、152、157、158、159、182、183、187、188、147* 联通号码段:130、131、132、136、185、186、145* 电信号码段:133、153、180、189 @param cellphone* @return*/public static boolean checkCellphone(String cellphone) {String regex = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\\\d{8}$";return check(cellphone, regex);}/* 验证固话号码 @param telephone* @return*/public static boolean checkTelephone(String telephone) {String regex = "^(0\\\\d{2}-\\\\d{8}(-\\\\d{1,4})?)|(0\\\\d{3}-\\\\d{7,8}(-\\\\d{1,4})?)$";return  check(telephone, regex);}/* 验证传真号码 @param fax* @return*/public static boolean checkFax(String fax) {String regex = "^(0\\\\d{2}-\\\\d{8}(-\\\\d{1,4})?)|(0\\\\d{3}-\\\\d{7,8}(-\\\\d{1,4})?)$";return check(fax, regex);}/* 验证QQ号码 @param QQ* @return*/public static boolean checkQQ(String QQ) {String regex = "^[1-9][0-9]{4,} $";return check(QQ, regex);}
}

④补充错误代码-501阿里云响应失败

项目7:(aliyun)实现短信的发送和验证微服务和上传文件删除文件微服务

2.短信验证的流程(aliyun的sms)

注意:将每个微服务的日志写到改成其下面的包

<property name="log.path" value="F:/Project_shangrongbao/java/srb/srb-log/core" />
<property name="log.path" value="F:/Project_shangrongbao/java/srb/srb-log/oss" />
<property name="log.path" value="F:/Project_shangrongbao/java/srb/srb-log/sms" />

①申请aliyun短信服务

  • 需要申请签名
  • 需要申请模板
  • 需要有访问的key-id和key-secret(访问aliyun的api)

②短信验证流程

  • 前端写手机号码,单击发送验证码
  • 后端进行处理(接收手机号码参数)
    验证手机号码是否正确
    生成验证码
    通过aliyun发送验证码给手机号码
    将验证码存入redis
    返回结果
  • aliyun发送验证码
    利用账号密码签名模板
    利用手机号发送的验证码
    远程连接aliyun控制台并发送验证码
    返回响应结果
  • 注意:
    异常处理时,抛出自定义异常,在返回异常结果的同时也会打印异常跟踪栈

3.具体接口的编写(新建微服务service-sms)

①引入pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>srb</artifactId><groupId>com.atguigu</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>service-sms</artifactId><dependencies><dependency><groupId>com.atguigu</groupId><artifactId>service-base</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--lombok用来简化实体类:需要安装lombok插件--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--阿里云短信--><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId></dependency><!--  配置文件处理器  --><!--让自定义的配置在application.yaml进行自动提示--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency></dependencies>
</project>

主启动

package com.atguigu.srb.sms;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;@SpringBootApplication
//项目直接的互相调用,可以直接扫描到(不要写到具体包下,写到项目下即可)
@ComponentScan({"com.atguigu.srb","com.atguigu.common"})
public class ServiceSmsApplication {public static void main(String[] args) {SpringApplication.run(ServiceSmsApplication.class, args);}
}

②编写具体的配置application.yml

server:port: 8120 # 服务端口spring:profiles:active: dev # 环境设置application:name: service-sms # 服务名#spring:redis:host: localhostport: 6379database: 0timeout: 3000ms #最大等待时间,超时则抛出异常,否则请求一直等待#连接池的连接lettuce:pool:max-active: 20  #最大连接数,负值表示没有限制,默认8max-wait: -1    #最大阻塞等待时间,负值表示没限制,默认-1max-idle: 8     #最大空闲连接,默认8min-idle: 0     #最小空闲连接,默认0#阿里云短信
aliyun:sms:region-id: key-id: key-secret: template-code: sign-name: 

写日志配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration><!--标志位,区分不同的应用程序--><contextName>atguiguSrb</contextName><!-- 日志的输出目录 --><property name="log.path" value="F:/Project_shangrongbao/java/srb/srb-log" /><!--控制台日志格式:彩色日志--><!-- magenta:洋红 --><!-- boldMagenta:粗红--><!-- cyan:青色 --><!-- white:白色 --><!-- magenta:洋红 --><property name="CONSOLE_LOG_PATTERN"value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) %highlight([%-5level]) %green(%logger) %msg%n"/><!--文件日志格式--><property name="FILE_LOG_PATTERN"value="%date{yyyy-MM-dd HH:mm:ss} [%-5level] %thread %file:%line %logger %msg%n" /><!--编码--><property name="ENCODING"value="UTF-8" /><!-- 控制台日志 --><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${CONSOLE_LOG_PATTERN}</pattern><charset>${ENCODING}</charset></encoder></appender><!-- 文件日志 --><appender name="FILE" class="ch.qos.logback.core.FileAppender"><file>${log.path}/log.log</file><append>true</append><encoder><pattern>${FILE_LOG_PATTERN}</pattern><charset>${ENCODING}</charset></encoder></appender><!--名称即为包名了,其包下面的文件都会被日志记录器管理--><!--file和console都打印--><!--环境配置了此不用配置--><!-- 日志记录器  --><!--<logger name="com.atguigu" level="INFO">--><!--<appender-ref ref="CONSOLE" />--><!--<appender-ref ref="FILE" />--><!--</logger>--><!--设置滚动日志,时间的滚动策略--><appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!--  要区别于其他的appender中的文件名字  --><file>${log.path}/log-rolling.log</file><encoder><pattern>${FILE_LOG_PATTERN}</pattern><charset>${ENCODING}</charset></encoder><!-- 设置滚动日志记录的滚动策略 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 日志归档路径以及格式 --><fileNamePattern>${log.path}/info/log-rolling-%d{yyyy-MM-dd}.%i.log</fileNamePattern><!--归档日志文件保留的最大数量--><maxHistory>15</maxHistory><!--包含上size,防止一天的日志文件过大,超过下面的大小,再分--><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>1024kb</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy></appender><!--多环境配置--><!-- 开发环境和测试环境 --><!--name和application.yml配合使用--><springProfile name="dev,test"><logger name="com.atguigu" level="INFO"><appender-ref ref="CONSOLE" /><appender-ref ref="ROLLING_FILE" /></logger></springProfile><!-- 生产环境 --><springProfile name="prod"><logger name="com.atguigu" level="ERROR"><appender-ref ref="CONSOLE" /><appender-ref ref="ROLLING_FILE" /></logger></springProfile></configuration>

③创建能够读取配置文件的util

package com.atguigu.srb.sms.util;import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;//没有自动感知,即会发生上面的 spring boot configurtion annotation processor not found in classpath
//@Setter
@Getter //idea2020.2.3版配置文件自动提示需要这个
@Component
//InitializingBean接口里面的抽象方法为设置properties完成之后自动调用的方法
//注意prefix要写到最后一个 "." 符号之前
//调用setter为成员赋值
@ConfigurationProperties(prefix = "aliyun.sms")
public class SmsProperties implements InitializingBean {//spring自动根据application.yml赋值给下面值,即自动将_格式转换为驼峰private String regionId;private String keyId;private String keySecret;private String templateCode;private String signName;public static String REGION_Id;public static String KEY_ID;public static String KEY_SECRET;public static String TEMPLATE_CODE;public static String SIGN_NAME;//当私有成员被赋值后,此方法自动被调用,从而初始化常量@Overridepublic void afterPropertiesSet() throws Exception {REGION_Id = regionId;KEY_ID = keyId;KEY_SECRET = keySecret;TEMPLATE_CODE = templateCode;SIGN_NAME = signName;}
}

注意spring-boot-configuration-processor包即用来在xml中自动提示有前缀的配置,需要配合在idea中如下配置
项目7:(aliyun)实现短信的发送和验证微服务和上传文件删除文件微服务

④写controller

package com.atguigu.srb.sms.controller.api;import com.atguigu.common.exception.Assert;
import com.atguigu.common.result.R;
import com.atguigu.common.result.ResponseEnum;
import com.atguigu.common.util.RandomUtils;
import com.atguigu.common.util.RegexValidateUtils;
import com.atguigu.srb.sms.service.SmsService;
import com.atguigu.srb.sms.util.SmsProperties;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;@RestController
@RequestMapping("/api/sms")
@Api(tags = "短信管理")
@CrossOrigin //跨域
@Slf4j
public class ApiSmsController {@Resourceprivate SmsService smsService;@Resourceprivate RedisTemplate redisTemplate;@ApiOperation("获取验证码")@GetMapping("/send/{mobile}")public R send(@ApiParam(value = "手机号", required = true)@PathVariable String mobile){//MOBILE_NULL_ERROR(-202, "手机号不能为空"),Assert.notEmpty(mobile, ResponseEnum.MOBILE_NULL_ERROR);//MOBILE_ERROR(-203, "手机号不正确"),Assert.isTrue(RegexValidateUtils.checkCellphone(mobile), ResponseEnum.MOBILE_ERROR);//生成验证码String code = RandomUtils.getFourBitRandom();//组装短信模板参数Map<String,Object> param = new HashMap<>();param.put("code", code);//发送短信smsService.send(mobile, SmsProperties.TEMPLATE_CODE, param);//将验证码存入redisredisTemplate.opsForValue().set("srb:sms:code:" + mobile, code, 5, TimeUnit.MINUTES);return R.ok().message("短信发送成功");}
}

⑤service层

package com.atguigu.srb.sms.service;import java.util.Map;public interface SmsService {//手机号,模板的编号,模板的参数void send(String mobile, String templateCode, Map<String,Object> param);
}
package com.atguigu.srb.sms.service.impl;import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.atguigu.common.exception.Assert;
import com.atguigu.common.exception.BusinessException;
import com.atguigu.common.result.ResponseEnum;
import com.atguigu.srb.sms.service.SmsService;
import com.atguigu.srb.sms.util.SmsProperties;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;import java.util.HashMap;
import java.util.Map;@Service
@Slf4j
public class SmsServiceImpl implements SmsService {@Overridepublic void send(String mobile, String templateCode, Map<String,Object> param) {//创建远程连接客户端对象DefaultProfile profile = DefaultProfile.getProfile(SmsProperties.REGION_Id,SmsProperties.KEY_ID,SmsProperties.KEY_SECRET);IAcsClient client = new DefaultAcsClient(profile);//创建远程连接的请求参数CommonRequest request = new CommonRequest();request.setSysMethod(MethodType.POST);request.setSysDomain("dysmsapi.aliyuncs.com");request.setSysVersion("2017-05-25");request.setSysAction("SendSms");request.putQueryParameter("RegionId", SmsProperties.REGION_Id);request.putQueryParameter("PhoneNumbers", mobile);request.putQueryParameter("SignName", SmsProperties.SIGN_NAME);request.putQueryParameter("TemplateCode", templateCode);Gson gson = new Gson();String json = gson.toJson(param);request.putQueryParameter("TemplateParam", json);try {//使用客户端对象携带请求对象发送请求并得到响应结果CommonResponse response = client.getCommonResponse(request);boolean success = response.getHttpResponse().isSuccess();//通信失败//ALIYUN_RESPONSE_FAIL(-501, "阿里云响应失败"),Assert.isTrue(success, ResponseEnum.ALIYUN_RESPONSE_FAIL);//业务处理,已经成功连接阿里云String data = response.getData();HashMap<String, String> resultMap = gson.fromJson(data, HashMap.class);String code = resultMap.get("Code");String message = resultMap.get("Message");log.info("阿里云短信发送响应结果:");log.info("code:" + code);log.info("message:" + message);//ALIYUN_SMS_LIMIT_CONTROL_ERROR(-502, "短信发送过于频繁"),//业务限流Assert.notEquals("isv.BUSINESS_LIMIT_CONTROL", code, ResponseEnum.ALIYUN_SMS_LIMIT_CONTROL_ERROR);//ALIYUN_SMS_ERROR(-503, "短信发送失败"),//其他失败Assert.equals("OK", code, ResponseEnum.ALIYUN_SMS_ERROR);} catch (ServerException e) {log.error("阿里云短信发送SDK调用失败:");log.error("ErrorCode=" + e.getErrCode());log.error("ErrorMessage=" + e.getErrMsg());//返回错误信息,然后在统一异常处理时,会返回给前端数据,然后打印错误跟踪栈throw new BusinessException(ResponseEnum.ALIYUN_SMS_ERROR , e);} catch (ClientException e) {log.error("阿里云短信发送SDK调用失败:");log.error("ErrorCode=" + e.getErrCode());log.error("ErrorMessage=" + e.getErrMsg());throw new BusinessException(ResponseEnum.ALIYUN_SMS_ERROR , e);}}
}

4.上传和删除文件流程(aliyun的oss)

①申请oss服务

  • bucket名称
  • endpoint地域网址
    (读写权限为公共读)
  • 访问oss文件地址为
    http://buctet名称.endpoint/文件
  • 文件设计:module+日期+UUID.后缀名

②微服务远程调用

  • 利用id和密码
  • 利用bucketname和endpoint
  • 上传文件
    利用id和密码和endpoint获取到连接
    前端上传文件后后端获取文件然后根据文件获取到输入流,上传文件到bucketname,指明文件名和输入流

5.具体接口的编写(新建微服务service-oos)

①引入pom和主启动

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>srb</artifactId><groupId>com.atguigu</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>service-oss</artifactId><dependencies><dependency><groupId>com.atguigu</groupId><artifactId>service-base</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--lombok用来简化实体类:需要安装lombok插件--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--aliyunOSS--><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId></dependency><!-- 日期工具栏依赖,格式化日期 --><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId></dependency><!--让自定义的配置在application.yaml进行自动提示--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency></dependencies></project>
package com.atguigu.srb.oss;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;@SpringBootApplication
@ComponentScan({"com.atguigu.srb", "com.atguigu.common"})
public class ServiceOssApplication {public static void main(String[] args) {SpringApplication.run(ServiceOssApplication.class, args);}}

②编写yml和xml

server:port: 8130 # 服务端口spring:profiles:active: dev # 环境设置application:name: service-oss # 服务名aliyun:oss:endpoint: keyId: keySecret: bucketName: 
<?xml version="1.0" encoding="UTF-8"?>
<configuration><!--标志位,区分不同的应用程序--><contextName>atguiguSrb</contextName><!-- 日志的输出目录 --><property name="log.path" value="F:/Project_shangrongbao/java/srb/srb-log/oss" /><!--控制台日志格式:彩色日志--><!-- magenta:洋红 --><!-- boldMagenta:粗红--><!-- cyan:青色 --><!-- white:白色 --><!-- magenta:洋红 --><property name="CONSOLE_LOG_PATTERN"value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) %highlight([%-5level]) %green(%logger) %msg%n"/><!--文件日志格式--><property name="FILE_LOG_PATTERN"value="%date{yyyy-MM-dd HH:mm:ss} [%-5level] %thread %file:%line %logger %msg%n" /><!--编码--><property name="ENCODING"value="UTF-8" /><!-- 控制台日志 --><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${CONSOLE_LOG_PATTERN}</pattern><charset>${ENCODING}</charset></encoder></appender><!-- 文件日志 --><appender name="FILE" class="ch.qos.logback.core.FileAppender"><file>${log.path}/log.log</file><append>true</append><encoder><pattern>${FILE_LOG_PATTERN}</pattern><charset>${ENCODING}</charset></encoder></appender><!--名称即为包名了,其包下面的文件都会被日志记录器管理--><!--file和console都打印--><!--环境配置了此不用配置--><!-- 日志记录器  --><!--<logger name="com.atguigu" level="INFO">--><!--<appender-ref ref="CONSOLE" />--><!--<appender-ref ref="FILE" />--><!--</logger>--><!--设置滚动日志,时间的滚动策略--><appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!--  要区别于其他的appender中的文件名字  --><file>${log.path}/log-rolling.log</file><encoder><pattern>${FILE_LOG_PATTERN}</pattern><charset>${ENCODING}</charset></encoder><!-- 设置滚动日志记录的滚动策略 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 日志归档路径以及格式 --><fileNamePattern>${log.path}/info/log-rolling-%d{yyyy-MM-dd}.%i.log</fileNamePattern><!--归档日志文件保留的最大数量--><maxHistory>15</maxHistory><!--包含上size,防止一天的日志文件过大,超过下面的大小,再分--><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>1024kb</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy></appender><!--多环境配置--><!-- 开发环境和测试环境 --><!--name和application.yml配合使用--><springProfile name="dev,test"><logger name="com.atguigu" level="INFO"><appender-ref ref="CONSOLE" /><appender-ref ref="ROLLING_FILE" /></logger></springProfile><!-- 生产环境 --><springProfile name="prod"><logger name="com.atguigu" level="ERROR"><appender-ref ref="CONSOLE" /><appender-ref ref="ROLLING_FILE" /></logger></springProfile></configuration>

③编写util绑定属性

package com.atguigu.srb.oss.util;import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Setter
@Getter
@Component
@ConfigurationProperties(prefix = "aliyun.oss")
public class OssProperties implements InitializingBean {private String endpoint;private String keyId;private String keySecret;private String bucketName;public static String ENDPOINT;public static String KEY_ID;public static String KEY_SECRET;public static String BUCKET_NAME;//当私有成员被赋值后,此方法自动被调用,从而初始化常量@Overridepublic void afterPropertiesSet() throws Exception {ENDPOINT = endpoint;KEY_ID = keyId;KEY_SECRET = keySecret;BUCKET_NAME = bucketName;}
}

④编写controller层

package com.atguigu.srb.oss.controller.api;import com.atguigu.common.exception.BusinessException;
import com.atguigu.common.result.R;
import com.atguigu.common.result.ResponseEnum;
import com.atguigu.srb.oss.service.FileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;@Api(tags = "阿里云文件管理")
@CrossOrigin //跨域
@RestController
@RequestMapping("/api/oss/file")
public class FileController {@Resourceprivate FileService fileService;/* 文件上传*/@ApiOperation("文件上传")@PostMapping("/upload")public R upload(@ApiParam(value = "文件", required = true)@RequestParam("file") MultipartFile file,@ApiParam(value = "模块", required = true)@RequestParam("module") String module)  {try {InputStream inputStream = file.getInputStream();String originalFilename = file.getOriginalFilename();//返回的为上传的url地址String uploadUrl = fileService.upload(inputStream, module, originalFilename);//返回r对象return R.ok().message("文件上传成功").data("url", uploadUrl);} catch (IOException e) {throw new BusinessException(ResponseEnum.UPLOAD_ERROR, e);}}@ApiOperation("删除OSS文件")@DeleteMapping("/remove")public R remove(@ApiParam(value = "要删除的文件路径", required = true)@RequestParam("url") String url) {fileService.removeFile(url);return R.ok().message("删除成功");}
}

⑤编写service层

package com.atguigu.srb.oss.service;import java.io.InputStream;public interface FileService {/* 文件上传至阿里云*///module是放到哪个文件夹下,filename是文件名String upload(InputStream inputStream, String module, String fileName);/* 根据路径删除文件* @param url*/void removeFile(String url);
}
package com.atguigu.srb.oss.service.impl;import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.CannedAccessControlList;
import com.atguigu.srb.oss.service.FileService;
import com.atguigu.srb.oss.util.OssProperties;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;import java.io.InputStream;
import java.util.UUID;@Service
public class FileServiceImpl implements FileService {/* 文件上传至阿里云*/@Overridepublic String upload(InputStream inputStream, String module, String fileName) {// 创建OSSClient实例。OSS ossClient = new OSSClientBuilder().build(OssProperties.ENDPOINT,OssProperties.KEY_ID,OssProperties.KEY_SECRET);//判断oss的Bucket实例是否存在:如果不存在则创建,如果存在则获取if(!ossClient.doesBucketExist(OssProperties.BUCKET_NAME)){//创建bucketossClient.createBucket(OssProperties.BUCKET_NAME);//设置oss实例的访问权限:公共读ossClient.setBucketAcl(OssProperties.BUCKET_NAME, CannedAccessControlList.PublicRead);}//avatar为module//构建日期路径:avatar/2019/02/26/文件名String folder = new DateTime().toString("yyyy/MM/dd");//文件名:uuid.扩展名fileName = UUID.randomUUID().toString() + fileName.substring(fileName.lastIndexOf("."));//文件根路径String key = module + "/" + folder + "/" + fileName;//文件上传至阿里云ossClient.putObject(OssProperties.BUCKET_NAME, key, inputStream);// 关闭OSSClient。ossClient.shutdown();//阿里云文件绝对路径return "https://" + OssProperties.BUCKET_NAME + "." + OssProperties.ENDPOINT + "/" + key;}/* 根据路径删除文件* @param url*/@Overridepublic void removeFile(String url) {// 创建OSSClient实例。OSS ossClient = new OSSClientBuilder().build(OssProperties.ENDPOINT,OssProperties.KEY_ID,OssProperties.KEY_SECRET);//文件名(服务器上的文件路径)String host = "https://" + OssProperties.BUCKET_NAME + "." + OssProperties.ENDPOINT + "/";String objectName = url.substring(host.length());// 删除文件。ossClient.deleteObject(OssProperties.BUCKET_NAME, objectName);// 关闭OSSClient。ossClient.shutdown();}
}

未更新

未更新

未更新

未更新

未更新

未更新

未更新

未更新

未更新