上一篇外层项目构建我们讲解如何构建一个外层项目,现在开始我们讲解的是Com模块的相关功能
Com模块是一个starter包,至于什么事starter包,后面我会单独来讲解。
项目源码:源码地址
这一篇是公共模块中阿里云相关功能讲解,在日常开发中其实我们跟阿里云的接触是相当的频繁的。而且阿里云的产品确实也非常好用,这里就介绍三个功能的集成:
首先,在我们构建的项目上新建一个module:new->module,这里和创建项目一样也是一个POM,大家如果忘记了可以看上一篇文章。
OK,com模块建立好之后,我们在Com模块的基础上构建阿里云模块和api模块。唯一区别于上面外层项目构建就是这里选择的是quickstart。
有人可能问为啥要新建api模块,主要是在部分业务场景减少不必要的全量引入。
在aliyun模块引入api模块
com-aliyun-service
com.clark
com-api-service
1.0-SNAPSHOT
OK到这里基本的项目构建完成。
引入相关的jar包以及单元测试相关jar
com.aliyun
aliyun-java-sdk-core
3.3.1
com.aliyun
aliyun-java-sdk-dysmsapi
1.0.0
com.aliyun.oss
aliyun-sdk-oss
2.8.2
com.aliyun
aliyun-java-sdk-vod
2.15.2
com.aliyun
aliyun-java-vod-upload
1.3.2
org.springframework.boot
spring-boot-configuration-processor
true
junit
junit
4.12
test
org.springframework.boot
spring-boot-starter-test
test
这里需要注意点版本关联,阿里云的各个SDK的版本关联有点乱。
/**
* oss配置类
* @author 大仙
*/
@Data
@ConfigurationProperties(prefix = "edu.aliyun.oss")
public class OssProperties implements Serializable {
/**
* 站点
*/
private String point;
/**
* keyId
*/
private String key;
/**
* key密码
*/
private String secret;
/**
* bucket名称
*/
private String buckName;
/**
* 访问路径
*/
private String baseUrl;
/**
* 角色管理获得
*/
private String roleArn;
/**
* session名称
*/
private String roleSessionName;
}
/**
* 短信配置类
* @author 大仙
*/
@Data
@ConfigurationProperties(prefix = "edu.aliyun.sms")
public class SmsProperties implements Serializable {
/**
* 短信API产品名称(短信产品名固定,无需修改)
*/
private String product;
/**
* 短信API产品域名(接口地址固定,无需修改)
*/
private String domain;
/**
* 签名名称
*/
private String signName;
/**
* 断点
*/
private String endpoint;
/**
* key:单独授权
*/
private String key;
/**
* secret: 单独授权
*/
private String secret;
}
/**
* 视频配置类
* @author 大仙
*/
@Data
@ConfigurationProperties(prefix = "edu.aliyun.vod")
public class VodProperties implements Serializable {
/**
* key:单独权限
*/
private String key;
/**
* secret: 单独权限
*/
private String secret;
/**
* 区域
*/
private String region;
/**
* 用户ID
*/
private String uid;
/**
* 图片前缀
*/
private String coverUrl;
/**
* 模板组
*/
private String templateMode;
}
功能实现的相关接口,需要抽象到API模块里面,这里就不详细说了。
/**
* OSS业务实现
* @author 大仙
*/
@Slf4j
public class OssServiceImpl implements OssService {
private OssProperties ossProperties;
@Override
public String uploadByte(byte[] content, String key) {
String bucket_resource = ossProperties.getBuckName();
// 初始化OSSClient
OSSClient client = new OSSClient(ossProperties.getPoint(), ossProperties.getKey(), ossProperties.getSecret());
// 上传Object.
try {
client.putObject(bucket_resource, key, new ByteArrayInputStream(content));
} catch (Exception e) {
log.error("OSSUtils upload Exception", e);
throw new AliyunException(e.getMessage());
} finally {
client.shutdown();
}
return ossProperties.getBaseUrl() + "/" + key;
}
@Override
public String upload(String key, InputStream inputStream) {
OSSClient ossClient = new OSSClient(ossProperties.getPoint(), ossProperties.getKey(), ossProperties.getSecret());
try {
ossClient.putObject(ossProperties.getBuckName(), key, inputStream);
} catch (Exception e) {
log.error("OSSUtils upload Exception", e);
throw new AliyunException(e.getMessage());
} finally {
ossClient.shutdown();
}
return ossProperties.getBaseUrl() + "/" + key;
}
@Override
public JSONObject getToken(String key) {
JSONObject result = new JSONObject();
Map tokenMessage = getSTSToken();
if (tokenMessage.size() == 0) {
log.info("没有查询到数据");
return null;
}
result.put("Expiration", tokenMessage.get("Expiration"));
result.put("AccessKey", tokenMessage.get("AccessKey"));
result.put("AccessKeySecret", tokenMessage.get("AccessKeySecret"));
result.put("SecurityToken", tokenMessage.get("SecurityToken"));
result.put("endpoint", ossProperties.getPoint());
result.put("bucket", ossProperties.getBuckName());
result.put("key", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")).toString() +key);
return result;
}
/**
* 获取TOKEN
* @param source
* @param userId
* @return
*/
/**
* 获取STStoken
*
* @return
*/
private Map getSTSToken() {
Map tokenMessage = new HashMap();
String policy = null;
try {
// 添加endpoint(直接使用STS endpoint,前两个参数留空,无需添加region ID)
DefaultProfile.addEndpoint("", "", "Sts", ossProperties.getPoint());
// 构造default profile(参数留空,无需添加region ID)
IClientProfile profile = DefaultProfile.getProfile("cn-beijing", ossProperties.getKey(), ossProperties.getSecret());
// 用profile构造client
DefaultAcsClient client = new DefaultAcsClient(profile);
final AssumeRoleRequest request = new AssumeRoleRequest();
request.setMethod(MethodType.POST);
request.setRoleArn(ossProperties.getRoleArn());
request.setRoleSessionName(ossProperties.getRoleSessionName());
request.setPolicy(policy); // Optional
request.setDurationSeconds(900L);
final AssumeRoleResponse response = client.getAcsResponse(request);
tokenMessage.put("Expiration", response.getCredentials().getExpiration());
tokenMessage.put("AccessKey", response.getCredentials().getAccessKeyId());
tokenMessage.put("AccessKeySecret", response.getCredentials().getAccessKeySecret());
tokenMessage.put("SecurityToken", response.getCredentials().getSecurityToken());
tokenMessage.put("RequestId", response.getRequestId());
} catch (ClientException e) {
log.error("Error code: ", e.getErrCode());
log.error("Error message: ", e.getErrMsg());
log.error("RequestId: ", e.getRequestId());
throw new AliyunException(e.getMessage());
}
return tokenMessage;
}
public void setOssProperties(OssProperties ossProperties) {
this.ossProperties = ossProperties;
}
}
/**
* 短信实现
* @author 大仙
*/
@Slf4j
public class SmsServiceImpl implements SmsService {
private Logger logger = LoggerFactory.getLogger(getClass());
private SmsProperties smsProperties;
@Override
public void sendSMS(String phoneNum, SMSTemplate templateCode, String params) {
send(phoneNum, templateCode.toString(), params);
}
/**
* 发送短信
* @param phoneNum 接收短信内容
* @param templateCode
* @param param
* @return
* @throws ClientException
* @throws LimitExceededException
*/
private boolean send(String phoneNum, String templateCode, String param) {
try {
//初始化ascClient,暂时不支持多region(请勿修改)
IClientProfile profile = DefaultProfile.getProfile(smsProperties.getEndpoint(), smsProperties.getKey(),
smsProperties.getSecret());
DefaultProfile.addEndpoint(smsProperties.getEndpoint(), smsProperties.getEndpoint(), smsProperties.getProduct(), smsProperties.getDomain());
IAcsClient acsClient = new DefaultAcsClient(profile);
//组装请求对象
SendSmsRequest request = new SendSmsRequest();
request.setConnectTimeout(3000);
request.setReadTimeout(10000);
//使用post提交
request.setMethod(MethodType.POST);
//必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
request.setPhoneNumbers(phoneNum);
//必填:短信签名-可在短信控制台中找到
request.setSignName(smsProperties.getSignName());
//必填:短信模板-可在短信控制台中找到
request.setTemplateCode(templateCode);
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
//友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
request.setTemplateParam(param);
//可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
//request.setSmsUpExtendCode("90997");
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
// request.setOutId("yourOutId");
//请求失败这里会抛ClientException异常
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
logger.info("发送短信结果:" + JSONObject.toJSONString(sendSmsResponse));
if (sendSmsResponse.getCode() != null) {
if (sendSmsResponse.getCode().equals("OK")) {
return true;
}
if (sendSmsResponse.getCode().equals("isv.BUSINESS_LIMIT_CONTROL")) {
throw new AliyunException("短信服务限流");
}
}
}catch (Exception e){
throw new AliyunException(e.getMessage());
}
return false;
}
public void setSmsProperties(SmsProperties smsProperties) {
this.smsProperties = smsProperties;
}
}
/**
* 视频点播业务
* @author 大仙
*/
@Slf4j
public class VodServiceImpl implements VodService {
private Logger logger = LoggerFactory.getLogger(getClass());
/**
* 正常
*/
private static final String STATUS = "Normal";
private VodProperties vodProperties;
public void setVodProperties(VodProperties vodProperties) {
this.vodProperties = vodProperties;
}
@Override
public JSONObject getVideoPlayAuth(String vid) {
DefaultProfile profile = DefaultProfile.getProfile(vodProperties.getRegion(), vodProperties.getKey(), vodProperties.getSecret());
DefaultAcsClient client = new DefaultAcsClient(profile);
GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();
request.setVideoId(vid);
request.setAuthInfoTimeout(3000L);
GetVideoPlayAuthResponse response = null;
try {
response = client.getAcsResponse(request);
} catch (ServerException e) {
throw new RuntimeException("GetVideoPlayAuthRequest Server failed");
} catch (ClientException e) {
throw new RuntimeException("GetVideoPlayAuthRequest Client failed");
}
JSONObject result = new JSONObject();
result.put("status", false);
try {
if (STATUS.equals(response.getVideoMeta().getStatus())) {
result.put("status", true);
}
result.put("playAuth", response.getPlayAuth()); // 播放凭证
} catch (Exception e) {
logger.error("获取播放凭证出错");
}
return result;
}
@Override
public JSONObject uploadVideoToVOD(String source, Long cateId) {
DefaultProfile profile = DefaultProfile.getProfile(vodProperties.getRegion(), vodProperties.getKey(), vodProperties.getSecret());
DefaultAcsClient client = new DefaultAcsClient(profile);
CreateUploadVideoRequest request = new CreateUploadVideoRequest();
String randomCode = System.currentTimeMillis() + PubUtils.generateRandomFullCode(5);
String fileName = source + "_" + randomCode + ".mp4";
//封面图片
String coverUrl = vodProperties.getCoverUrl() + source + "_" + randomCode + ".jpg";
String title = fileName;
request.setFileName(fileName);
request.setTitle(title);
request.setCateId(cateId);
request.setCoverURL(coverUrl);
request.setTemplateGroupId(vodProperties.getTemplateMode());
CreateUploadVideoResponse response = null;
try {
response = client.getAcsResponse(request);
} catch (ClientException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
logger.info("result:{}",JSONObject.toJSONString(response));
/*System.out.print("RequestId=" + response.getRequestId() + "\n"); //请求视频点播服务的请求ID
System.out.print("VideoId=" + response.getVideoId() + "\n");
System.out.print("uploadAddress=" + response.getUploadAddress() + "\n");
System.out.print("uploadAuth=" + response.getUploadAuth() + "\n");*/
JSONObject result = new JSONObject();
result.put("videoId", response.getVideoId());
result.put("uploadAddress", response.getUploadAddress());
result.put("uploadAuth", response.getUploadAuth());
result.put("fileName", fileName);
result.put("region", vodProperties.getRegion());
result.put("coverUrl", coverUrl);
result.put("imageFileName", source + "_" + randomCode + ".jpg");
result.put("uid", vodProperties.getUid());
return result;
}
/**
* 上传视频
* @param title
* @param fileName
* @param file
* @return
*/
@Override
public String uploadVideoByStream(String title, String fileName, InputStream file) {
UploadStreamRequest request = new UploadStreamRequest(vodProperties.getKey(), vodProperties.getSecret(), title, fileName, file);
request.setCateId(1000066766L);
UploadVideoImpl uploader = new UploadVideoImpl();
UploadStreamResponse response = uploader.uploadStream(request);
System.out.print("RequestId=" + response.getRequestId() + "\n"); //请求视频点播服务的请求ID
if (response.isSuccess()) {
System.out.print("VideoId=" + response.getVideoId() + "\n");
} else {
/* 如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因 */
System.out.print("VideoId=" + response.getVideoId() + "\n");
System.out.print("ErrorCode=" + response.getCode() + "\n");
System.out.print("ErrorMessage=" + response.getMessage() + "\n");
}
return response.getVideoId();
}
}
/**
* OSS config
* @author 大仙
*/
@EnableConfigurationProperties({ OssProperties.class})
public class OssAutoConfig {
@Autowired
OssProperties ossProperties;
/**
* 实例化OSS
* @return
*/
@Bean
OssService ossService(){
OssServiceImpl ossService = new OssServiceImpl();
ossService.setOssProperties(ossProperties);
return ossService;
}
}
@EnableConfigurationProperties({ SmsProperties.class})
public class SmsAutoConfig {
@Autowired
SmsProperties smsProperties;
/**
* 实例化OSS
* @return
*/
@Bean
SmsService smsService(){
SmsServiceImpl smsService = new SmsServiceImpl();
smsService.setSmsProperties(smsProperties);
return smsService;
}
}
@EnableConfigurationProperties({ VodProperties.class})
public class VodAutoConfig {
@Autowired
private VodProperties vodProperties;
/**
* 阿里云视频点播业务
* @return
*/
@Bean
VodService vodService(){
VodServiceImpl vodService = new VodServiceImpl();
vodService.setVodProperties(vodProperties);
return vodService;
}
}
/**
* 阿里云Oss的启动注解
* @author 大仙
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(OssAutoConfig.class)
public @interface EnableAliOss {
}
/**
* 阿里云启动短信注解
* @author 大仙
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(SmsAutoConfig.class)
public @interface EnableAliSms {
}
/**
* 阿里云启动视频注解
* @author 大仙
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(VodAutoConfig.class)
public @interface EnableAliVod {
}
OK到这里,基本上常用的阿里云的接口功能都封装完毕了