2021-07-25_基于SpringBoot短信发送学习笔记
2021-07-25 本文已影响0人
kikop
20210725_基于SpringBoot短信发送学习笔记
1概述
本篇主要是配合自定义starter进行功能验证。源码后面我会放到git上。
1.1关于spring.factories文件
spring.factories该文件用来定义需要自动配置的类,SpringBoot启动时会进行对象的实例化,会通过加载类SpringFactoriesLoader加载该配置文件,将文件中的配置类加载到spring容器。
1.2关于@SpringBootApplication
这里一定要注意@SpringBootApplication注解等价于默认属性使用@Configuration+@EnableAutoConfiguration+@ComponentScan,如果@SpringBootApplication和@ComponentScan注解同时存在,那么@SpringBootApplication注解中@ComponentScan的扫描范围会被覆盖,所以单独使用@ComponentScan的话,必须在该注解上配置项目需要扫描的包的所有范围,即项目包路径+依赖包路径。
1.3互亿无线账号注册
在互亿无线平台:https://www.ihuyi.com/ 注册账号并且认证为个人开发者(需要身份证),这个不难,不多说了。注册成功得到如下信息:
apiid、apikey。如果想真实的进行短信发送测试,需购买套餐添加签名和模板才可以。
[图片上传失败...(image-3cdae8-1627213379964)]
2代码实战
2.1自定义starter包
2.1.1maven依赖
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.kikop.sms</groupId>
<artifactId>mysms-spring-boot-starter</artifactId>
<version>2.0.0-SNAPSHOT</version>
<name>mysms-spring-boot-starter</name>
<description>mysms-spring-boot-starter project</description>
<properties>
<java.version>1.8</java.version>
<spring-boot.version>2.1.4.RELEASE</spring-boot.version>
<commons-pool2.version>2.6.0</commons-pool2.version>
<commons-lang.version>2.6</commons-lang.version>
<!--jaxen-->
<jaxen.version>1.1.1</jaxen.version>
<dom4j.version>1.6.1</dom4j.version>
</properties>
<dependencies>
<!--1.自动装配-->
<!--封装Starter核心依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!--2.该依赖作用是在使用IDEA编写配置文件有代码提示-->
<!--非必需-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!-- 3.lombok 插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
<optional>true</optional>
</dependency>
<!-- 4.spring-boot-starter-web-->
<!--因为要使用RestTemplate和转换Json,所以引入这两个依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!--5.fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.45</version>
</dependency>
<!--6.commons-httpclient-->
<!--commons-httpclient 是 apache-commons 项目下的一个子项目,-->
<!--后来被 HttpComponents 取代,后者提供了更好的性能和更大的灵活性。-->
<!--commons-httpclient的GAV地址为-->
<!--其最新版本为3.1,且已经不再更新;-->
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<!--7.httpclient-->
<!--HttpComponents的GAV地址为-->
<!--https://blog.csdn.net/cym0359/article/details/106826374/-->
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<!--<dependency>-->
<!--<groupId>org.apache.httpcomponents</groupId>-->
<!--<artifactId>httpclient</artifactId>-->
<!--<version>4.5.5</version>-->
<!--</dependency>-->
<!--3.jaxen-->
<!--内置dom4j-->
<!--Jaxen是一个开源的XPath库-->
<!-- https://mvnrepository.com/artifact/jaxen/jaxen -->
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>${jaxen.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<!--1.spring-boot-maven-plugin-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- 2.跳过单元测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.1.2服务url定义
package com.kikop.sms.utils;
import lombok.Getter;
/**
* @author kikop
* @version 1.0
* @project Name: mysms-spring-boot-starter
* @file Name: Enum_Sms_URL
* @desc 创建短信接口枚举类,用于存放短信接口API地址
* @date 2019/9/15
* @time 16:50
* @by IDE: IntelliJ IDEA
*/
@Getter
public enum Enum_Sms_URL {
SENDSMS("https://open.ucpaas.com/ol/sms/sendsms"),
SENDBATCHSMS("https://open.ucpaas.com/ol/sms/sendsms_batch"),
SENDSMS2("http://106.ihuyi.com/webservice/sms.php?method=Submit");
private String url;
Enum_Sms_URL(String url) {
this.url = url;
}
}
2.1.3定义SmsProperties
package com.kikop.sms.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author kikop
* @version 1.0
* @project Name: mysms-spring-boot-starter
* @file Name: SmsProperties
* @desc 创建SmsProperties配置属性类,并注入到 spring容器中
* 该类主要用于读取yml/properties信息
* @date 2019/9/15
* @time 16:52
* @by IDE: IntelliJ IDEA
*/
@Data
@ConfigurationProperties(prefix = "mysms2")
public class SmsProperties {
private String appid;
private String accountSid;
private String authToken;
private String apiid;
private String apikey;
}
2.1.4定义参数数据结构
package com.kikop.sms.dto;
import lombok.Data;
/**
* @author kikop
* @version 1.0
* @project Name: mysms-spring-boot-starter
* @file Name: SmsDTO
* @desc 传输类,用于参数传递
* @date 2019/9/15
* @time 16:46
* @by IDE: IntelliJ IDEA
*/
@Data
public class SmsDTO {
/**
* 模板ID
*/
private String templateid;
/**
* 用户穿透ID
* 可以为空
*/
private String uid;
/**
* 参数
*/
private String param;
/**
* 手机号(可多个)
*/
private String mobile;
}
2.1.5定义ISmsService
package com.kikop.sms.service;
import com.kikop.sms.dto.SmsDTO;
/**
* @author kikop
* @version 1.0
* @project Name: mysms-spring-boot-starter
* @file Name: ISmsService
* @desc 创建短信核心服务接口
* @date 2019/9/15
* @time 16:54
* @by IDE: IntelliJ IDEA
*/
public interface ISmsService {
/**
* 单独发送
*/
String sendsms(SmsDTO sendSMSDTO);
/**
* 群体发送
*/
String sendsms_batch(SmsDTO sendSMSDTO);
/**
* 查询余额
*/
String queryAccount(SmsDTO sendSMSDTO);
}
2.1.6定义HYWXSmsServiceImpl
package com.kikop.sms.service.impl;
import com.kikop.sms.dto.SmsDTO;
import com.kikop.sms.properties.SmsProperties;
import com.kikop.sms.service.ISmsService;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.client.RestTemplate;
import java.net.URLEncoder;
/**
* @author kikop
* @version 1.0
* @project Name: sms-spring-boot-starter
* @file Name: SmsService
* @desc 创建短信核心服务类(基于互亿无线云)
* 注意,这里没加@Component,在 SmsAutoConfiguration 中手动 new
* @date 2019/9/15
* @time 16:54
* @by IDE: IntelliJ IDEA
*/
public class HYWXSmsServiceImpl implements ISmsService {
@Autowired
private RestTemplate restTemplate;
private String appid;
private String accountSid;
private String authToken;
private String apiid;
private String apikey;
public HYWXSmsServiceImpl(SmsProperties smsProperties) {
this.appid = smsProperties.getAppid();
this.accountSid = smsProperties.getAccountSid();
this.authToken = smsProperties.getAuthToken();
this.apiid = smsProperties.getApiid();
this.apikey = smsProperties.getApikey();
}
/**
* 单独发送
*/
public String sendsms(SmsDTO sendSMSDTO) {
String Url = "http://106.ihuyi.com/webservice/sms.php?method=Submit";
String SubmitResult = null;
try {
HttpClient client = new HttpClient();
PostMethod method = new PostMethod(Url);
client.getParams().setContentCharset("UTF-8"); // GBK
method.setRequestHeader("ContentType",
"application/x-www-form-urlencoded;charset=UTF-8");
// int mobile_code = (int) ((Math.random() * 9 + 1) * 100000);
// String content = new String("您的验证码是:" + mobile_code + "。请不要把验证码泄露给其他人。");
String account = this.apiid;
String password = this.apikey;
String mobile = sendSMSDTO.getMobile();
// 您的验证码是:1234。请不要把验证码泄露给其他人。
String content = null;
content = URLEncoder.encode(sendSMSDTO.getParam(), "UTF-8");
NameValuePair[] data = {//提交短信
// new NameValuePair("signature", "互亿无线"),
new NameValuePair("account", account), //查看用户名 登录用户中心->验证码通知短信>产品总览->API接口信息->APIID
new NameValuePair("password", password), //查看密码 登录用户中心->验证码通知短信>产品总览->API接口信息->APIKEY
//new NameValuePair("password", util.StringUtil.MD5Encode("密码")),
new NameValuePair("mobile", mobile),
new NameValuePair("content", content),
new NameValuePair("format", "json"),
};
method.setRequestBody(data);
client.executeMethod(method);
SubmitResult = method.getResponseBodyAsString();
//System.out.println(SubmitResult);
return SubmitResult;
// Document doc = DocumentHelper.parseText(SubmitResult);
// Element root = doc.getRootElement();
//
// String code = root.elementText("code");
// String msg = root.elementText("msg");
// String smsid = root.elementText("smsid");
//
// System.out.println(code);
// System.out.println(msg);
// System.out.println(smsid);
//
// if ("2".equals(code)) {
// System.out.println("短信提交成功");
// }
} catch (Exception e) {
e.printStackTrace();
}
return SubmitResult;
}
/**
* 群体发送
*/
public String sendsms_batch(SmsDTO sendSMSDTO) {
return null;
}
public String queryAccount(SmsDTO sendSMSDTO) {
String Url = "http://106.ihuyi.com/webservice/sms.php?method=GetNum";
String SubmitResult = null;
try {
HttpClient client = new HttpClient();
PostMethod method = new PostMethod(Url);
client.getParams().setContentCharset("UTF-8");
method.setRequestHeader("ContentType",
"application/x-www-form-urlencoded;charset=UTF-8");
String account = this.apiid;
String password = this.apikey;
String mobile = sendSMSDTO.getMobile();
NameValuePair[] data = {//提交短信
new NameValuePair("account", account), //查看用户名 登录用户中心->验证码通知短信>产品总览->API接口信息->APIID
new NameValuePair("password", password), //查看密码 登录用户中心->验证码通知短信>产品总览->API接口信息->APIKEY
//new NameValuePair("password", util.StringUtil.MD5Encode("密码")),
new NameValuePair("format", "json"),
};
method.setRequestBody(data);
client.executeMethod(method);
SubmitResult = method.getResponseBodyAsString();
// System.out.println(SubmitResult);
return SubmitResult;
} catch (Exception e) {
e.printStackTrace();
}
return SubmitResult;
}
// 互亿无线
// public String queryAccount(SmsDTO sendSMSDTO) {
//
// String SubmitResult = null;
// try {
// // https://www.ihuyi.com/api/sms.html
// // http://106.ihuyi.com/webservice/sms.php?method=Submit
// // &account=APIID&password=APIKEY&mobile=手机号码
// // &content=您的验证码是:1234。请不要把验证码泄露给其他人。
// String reqServer = "http://106.ihuyi.com/webservice/sms.php?method=GetNum";
// String account = this.apiid;
// String password = this.apikey;
//
// JSONObject reqSmsPayLoad = new JSONObject();
// // 基础配置,在开发平台认证后获取
// reqSmsPayLoad.put("account", account);
// reqSmsPayLoad.put("password", password);
// reqSmsPayLoad.put("format", "json");
//
// String reqSmsPayLoadStrJson = JSONObject.toJSONString(reqSmsPayLoad);
//
// // 使用restTemplate进行访问远程Http服务
// HttpHeaders headers = new HttpHeaders();
// headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
// HttpEntity<String> httpEntity = new HttpEntity<String>(reqSmsPayLoadStrJson, headers);
//
// //单发短信API
// SubmitResult = restTemplate.postForObject(reqServer, httpEntity, String.class);
//
// } catch (Exception ex) {
// ex.printStackTrace();
// }
// return SubmitResult;
// }
}
2.1.7定义自动配置类
package com.kikop.sms.config;
import com.kikop.sms.properties.SmsProperties;
import com.kikop.sms.service.ISmsService;
import com.kikop.sms.service.impl.HYWXSmsServiceImpl;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @author kikop
* @version 1.0
* @project Name: mysms-spring-boot-starter
* @file Name: SmsAutoConfiguration
* @desc 创建核心业务类实例
* @date 2019/9/15
* @time 17:09
* @by IDE: IntelliJ IDEA
*/
@Configuration
@EnableConfigurationProperties(SmsProperties.class)
public class SmsAutoConfiguration {
/**
* 构建短信业务服务
*
* @param smsProperties
* @return
*/
@Bean
public ISmsService smsService(SmsProperties smsProperties) {
return new HYWXSmsServiceImpl(smsProperties);
}
/**
* 创建RestTemplateConfig配置类,用于调用短信接口
*
* @return
*/
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
2.1.8新建spring.factories
在src/main/resources新建META-INF文件夹,在META-INF文件夹下新建spring.factories文件.配置内容如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.kikop.sms.config.SmsAutoConfiguration
2.2打包和测试
2.2.1新建测试项目,引入我们自己的Starter,Maven依赖如下:
<?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">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<parent>
<artifactId>technicaltools</artifactId>
<groupId>com.kikop</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<groupId>com.kikop</groupId>
<artifactId>mysmsspringbootdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>${project.artifactId}</name>
<description>mysmsspringbootdemo project</description>
<modules>
<module>mycustomsmsdemo</module>
</modules>
<dependencies>
<!--lombok:用到slf4j的依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<!--<version>1.18.10</version>-->
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- 1.改动 Spring Boot,基于 2.1.4.RELEASE,主要是解决 maven的单继承问题 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<!--<version>2.3.7.RELEASE</version>-->
<!--<version>2.0.4.RELEASE</version>-->
<!--现在我们设置成了pom,说明导入的是一个父模块-->
<type>pom</type>
<!--scope标签中的值import代表把父模块中的jar包导入进来-->
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.2.2定义MySmsConfig
package com.kikop.config;
import org.springframework.context.annotation.Configuration;
/**
* @author kikop
* @version 1.0
* @project Name: mycustomsmsdemo
* @file Name: MySmsConfig
* @desc
* @date 2021/3/30
* @time 8:00
* @by IDE: IntelliJ IDEA
*/
@Configuration
public class MySmsConfig {
}
2.2.3资源配置
2.2.3.1application.yml
spring:
# 1.指定环境:开发v
profiles:
active: dev
mysms:
appid: e0b4acef2846b8e08188aea9fb0e
accountSid: 60637ea52ed10f3267c1184b0260
authToken: 491be330eac**********05c9c846058
mysms2:
apiid: 37657
apikey: f1b372975828bc35816ed5873db9
2.2.3.2application-dev.properties
server.port=8080
server.servlet.context-path=/mysmsdemodev
2.2.4定义MySmsApplication
package com.kikop;
import com.kikop.sms.dto.SmsDTO;
import com.kikop.sms.properties.SmsProperties;
import com.kikop.sms.service.ISmsService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
// 注解扫描多个包下示例,内嵌包中有@Component注解,需开启如下内容
//@ComponentScan({"com.kikopxxx", "com.kikop"})
public class MySmsApplication {
public static void main(String[] args) {
ConfigurableApplicationContext configurableApplicationContext =
SpringApplication.run(MySmsApplication.class, args);
// 1.获取配置
SmsProperties smsProperties = configurableApplicationContext.getBean(SmsProperties.class);
System.out.println("apiid:" + smsProperties.getApiid());
System.out.println("apikey:" + smsProperties.getApikey());
// 3.发送短信
// http://docs.ucpaas.com/doku.php?id=error_code
// https://www.ihuyi.com/api/sms.html
// ISmsService smsService = configurableApplicationContext.getBean(ISmsService.class);
// SmsDTO smsDTO = new SmsDTO();
// String mobile_code = "123456";
// smsDTO.setParam("您的验证码是:123456。请不要把验证码泄露给其他人。");
// smsDTO.setMobile("13776647245");
// System.out.println(smsService.sendsms(smsDTO));
// 4.queryAccount
// http://docs.ucpaas.com/doku.php?id=error_code
// https://www.ihuyi.com/api/sms.html
ISmsService querySmsService = configurableApplicationContext.getBean(ISmsService.class);
SmsDTO smsDTOQ = new SmsDTO();
System.out.println(querySmsService.queryAccount(smsDTOQ));
}
}
// 输出如下内容:
{"code":2,"msg":"查询成功","num":9}