美文网首页
2021-07-25_基于SpringBoot短信发送学习笔记

2021-07-25_基于SpringBoot短信发送学习笔记

作者: kikop | 来源:发表于2021-07-25 19:43 被阅读0次

    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}
    

    参考

    1SpringBoot 实现发送短信

    https://juejin.cn/post/6844903817922740232

    2SpringBoot 封装自己的Starter

    https://juejin.cn/post/6844903827519307784

    3短信开发指导

    https://www.ihuyi.com/demo/sms/java.html

    https://user.ihuyi.com/new/sms/send/send

    相关文章

      网友评论

          本文标题:2021-07-25_基于SpringBoot短信发送学习笔记

          本文链接:https://www.haomeiwen.com/subject/zoeimltx.html