SpringBoot框架与短信解决方案


1.Spring Boot入门

1.1什么是Spring Boot

Spring 诞生时是 Java 企业版(Java Enterprise EditionJEE,也称 J2EE)的轻量级代替品。无需开发重量级的 Enterprise JavaBeanEJB),Spring 为企业级Java 开发提供了一种相对简单的方法,通过依赖注入和面向切面编程,用简单的Java 对象(Plain Old Java ObjectPOJO)实现了 EJB 的功能。

虽然 Spring 的组件代码是轻量级的,但它的配置却是重量级的。一开始,Spring XML 配置,而且是很多 XML 配置。Spring 2.5 引入了基于注解的组件扫描,这消除了大量针对应用程序自身组件的显式 XML 配置。Spring 3.0 引入了基于 Java 的配置,这是一种类型安全的可重构配置方式,可以代替 XML。所有这些配置都代表了开发时的损耗。因为在思考 Spring 特性配置和解决业务问题之间需要进行思维切换,所以写配置挤占了写应用程序逻辑的时间。和所有框架一样,Spring 实用,但与此同时它要求的回报也不少。

除此之外,项目的依赖管理也是件吃力不讨好的事情。决定项目里要用哪些库就已经够让人头痛的了,你还要知道这些库的哪个版本和其他库不会有冲突,这难题实在太棘手。并且,依赖管理也是一种损耗,添加依赖不是写应用程序代码。一旦选错了依赖的版本,随之而来的不兼容问题毫无疑问会是生产力杀手。

Spring Boot 让这一切成为了过去。

    Spring Boot Spring 社区较新的一个项目。该项目的目的是帮助开发者更容易的创建基于 Spring 的应用程序和服务,让更多人的人更快的对 Spring 进行入门体验,为 Spring 生态系统提供了一种固定的、约定优于配置风格的框架。

Spring Boot 具有如下特性:

1)为基于 Spring 的开发提供更快的入门体验

2)开箱即用,没有代码生成,也无需 XML 配置。同时也可以修改默认值来满足特定的需求。

3)提供了一些大型项目中常见的非功能性特性,如嵌入式服务器、安全、指标,健康检测、外部配置等。

4Spring Boot 并不是不对 Spring 功能上的增强,而是提供了一种快速使用 Spring 的方式。

1.2 Spring Boot入门小Demo

1.2.1起步依赖

创建Maven工程 springboot_demo(打包方式jar)  

pom.xml中添加如下依赖

  <parent>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-parent</artifactId>

<version>1.4.0.RELEASE</version>

  </parent>  

  <dependencies>

    <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-web</artifactId>

    </dependency>

  </dependencies>

我们会惊奇地发现,我们的工程自动添加了好多好多jar

SpringBoot框架与短信解决方案


而这些jar包正式我们做开发时需要导入的jar包。因为这些jar包被我们刚才引入的spring-boot-starter-web所引用了,所以我们引用spring-boot-starter-web后会自动把依赖传递过来。

1.2.2变更JDK版本

我们发现默认情况下工程的JDK版本是1.6 ,而我们通常用使用1.7的版本,所以我们需要在pom.xml中添加以下配置

  <properties>   

    <java.version>1.7</java.version>

  </properties>

添加后更新工程,会发现版本已经变更为1.7

1.2.3引导类

只需要创建一个引导类 .

package cn.itcast.demo;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}

简单解释一下,@SpringBootApplication其实就是以下三个注解的总和

@Configuration 用于定义一个配置类

@EnableAutoConfiguration Spring Boot会自动根据你jar包的依赖来自动配置项目。

@ComponentScan 告诉Spring 哪个packages 的用注解标识的类 会被spring自动扫描并且装入bean容器

我们直接执行这个引导类,会发现控制台出现的这个标识

SpringBoot框架与短信解决方案

1.2.4 Spring MVC实现Hello World输出

我们现在开始使用spring MVC框架,实现json数据的输出。如果按照我们原来的做法,需要在web.xml中添加一个DispatcherServlet的配置,再添加一个spring的配置文件,配置文件中需要添加如下配置

    <!-- 使用组件扫描,不用将controllerspring中配置 -->

<context:component-scan base-package="cn.itcast.demo.controller" />

    <!-- 使用注解驱动不用在下边定义映射器和适配置器 -->

  <mvc:annotation-driven>

  <mvc:message-converters register-defaults="true">

    <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">  

      <property name="supportedMediaTypes" value="application/json"/>

      <property name="features">

        <array>

          <value>WriteMapNullValue</value>

          <value>WriteDateUseDateFormat</value>

        </array>

      </property>

    </bean>

  </mvc:message-converters>  

</mvc:annotation-driven>

但是我们用SpringBoot,这一切都省了。我们直接写Controller

package cn.itcast.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

@RestController

public class HelloWorldController {

@RequestMapping("/info")

public String info(){

return "HelloWorld";

}

}

我们运行启动类来运行程序

在浏览器地址栏输入 http://localhost:8080/info 即可看到运行结果

1.2.5修改tomcat启动端口

src/main/resources下创建application.properties

server.port=8088

重新运行引导类。地址栏输入

http://localhost:8088/info

1.2.6读取配置文件信息

src/main/resources下的application.properties 增加配置

url=http://www.itcast.cn

我要在类中读取这个配置信息,修改HelloWorldController  

@Autowired

private Environment env;

 

@RequestMapping("/info")

public String info(){

return "HelloWorld~~"+env.getProperty("url");

}

1.2.7热部署

我们在开发中反复修改类、页面等资源,每次修改后都是需要重新启动才生效,这样每次启动都很麻烦,浪费了大量的时间,能不能在我修改代码后不重启就能生效呢?可以,在pom.xml中添加如下配置就可以实现这样的功能,我们称之为热部署。

<dependency>  

    <groupId>org.springframework.boot</groupId>  

    <artifactId>spring-boot-devtools</artifactId>  

</dependency>  


1.3 Spring BootActiveMQ整合

1.3.1使用内嵌服务

1)在pom.xml中引入ActiveMQ起步依赖

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-activemq</artifactId>

</dependency>

2)创建消息生产者

/**

 * 消息生产者

 * @author Administrator

 */

@RestController

public class QueueController {

@Autowired

private JmsMessagingTemplate jmsMessagingTemplate;

 

@RequestMapping("/send")

public void send(String text){

jmsMessagingTemplate.convertAndSend("itcast", text);

}

}

3)创建消息消费者

@Component

public class Consumer {

@JmsListener(destination="itcast")

public void readMessage(String text){

System.out.println("接收到消息:"+text);

}

}

测试:启动服务后,在浏览器执行 

http://localhost:8088/send.do?text=aaaaa

即可看到控制台输出消息提示。Spring Boot内置了ActiveMQ的服务,所以我们不用单独启动也可以执行应用程序。

1.3.2使用外部服务

src/main/resources下的application.properties增加配置, 指定ActiveMQ的地址

spring.activemq.broker-url=tcp://192.168.25.135:61616

运行后,会在activeMQ中看到发送的queue 


SpringBoot框架与短信解决方案

1.3.3发送Map信息

1)修改QueueController.java

@RequestMapping("/sendmap")

public void sendMap(){

Map map=new HashMap<>();

map.put("mobile", "13900001111");

map.put("content", "恭喜获得10元代金券");

jmsMessagingTemplate.convertAndSend("itcast_map",map);

}

2)修改Consumer.java

@JmsListener(destination="itcast_map")

public void readMap(Map map){

System.out.println(map);

}


2.短信发送平台-阿里大于

2.1阿里大于简介

  阿里大于是阿里云旗下产品,融合了三大运营商的通信能力,通过将传统通信业务和能力与互联网相结合,创新融合阿里巴巴生态内容,全力为中小企业和开发者提供优质服务阿里大于提供包括短信、语音、流量直充、私密专线、店铺手机号等个性化服务。通过阿里大于打通三大运营商通信能力,全面融合阿里巴巴生态,以开放APISDK的方式向开发者提供通信和数据服务,更好地支撑企业业务发展和创新服务。

2.2准备工作

2.2.1注册账户

首先我们先进入“阿里大于”  www.alidayu.com  https://dayu.aliyun.com/


SpringBoot框架与短信解决方案






SpringBoot框架与短信解决方案   SpringBoot框架与短信解决方案

注册账号后,再在手机下载“阿里云”应用,登陆,然后进行在线实名认证。

2.2.2登陆系统

使用刚才注册的账号进行登陆。


SpringBoot框架与短信解决方案

SpringBoot框架与短信解决方案


点击进入控制台



SpringBoot框架与短信解决方案

点击使用短信服务


SpringBoot框架与短信解决方案

3.2.3申请签名


SpringBoot框架与短信解决方案

SpringBoot框架与短信解决方案


SpringBoot框架与短信解决方案

3.2.4申请模板

SpringBoot框架与短信解决方案

SpringBoot框架与短信解决方案

3.2.5创建accessKey


SpringBoot框架与短信解决方案

SpringBoot框架与短信解决方案

SpringBoot框架与短信解决方案

SpringBoot框架与短信解决方案

SpringBoot框架与短信解决方案


SpringBoot框架与短信解决方案


3.3 SDK安装

从阿里云通信官网上下载Demo工程

SpringBoot框架与短信解决方案

红线框起来的两个工程就是阿里云通信的依赖jar源码,我们将其安装到本地仓库

(删除aliyun-java-sdk-core的单元测试类)

本地jar包安装后 alicom-dysms-api工程引入依赖

<dependencies>

     <dependency>

     <groupId>com.aliyun</groupId>

     <artifactId>aliyun-java-sdk-dysmsapi</artifactId>

     <version>1.0.0-SNAPSHOT</version>

     </dependency>

     <dependency>

     <groupId>com.aliyun</groupId>

     <artifactId>aliyun-java-sdk-core</artifactId>

     <version>3.2.5</version>

     </dependency>

</dependencies>

红叉消失了 :-) 

SpringBoot框架与短信解决方案

3.4发送短信测试

1)打开SmsDemo

替换下列几处代码

SpringBoot框架与短信解决方案

这个accessKeyIdaccessSecret到刚才申请过的

手机号,短信签名和模板号

SpringBoot框架与短信解决方案

模板参数

SpringBoot框架与短信解决方案

number是我们申请模板时写的参数

执行main方法我们就可以在手机收到短信啦


3.短信微服务

3.1需求分析

构建一个通用的短信发送服务(独立于品优购的单独工程),接收activeMQ的消息(MAP类型)  消息包括手机号(mobile)、短信模板号(template_code)、签名(sign_name)、参数字符串(param

3.2代码实现

3.2.1工程搭建

1)创建工程itcast_sms JAR工程),POM文件引入依赖  

  <properties>   

    <java.version>1.7</java.version>

  </properties>

  <parent>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-parent</artifactId>

<version>1.4.0.RELEASE</version>

  </parent>  

  <dependencies>

    <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-web</artifactId>

    </dependency>

    <dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-activemq</artifactId>

</dependency>

    <dependency>

    <groupId>com.aliyun</groupId>

    <artifactId>aliyun-java-sdk-dysmsapi</artifactId>

    <version>1.0.0-SNAPSHOT</version>

    </dependency>

    <dependency>

    <groupId>com.aliyun</groupId>

    <artifactId>aliyun-java-sdk-core</artifactId>

    <version>3.2.5</version>

    </dependency>

  </dependencies>

2)创建引导类

package cn.itcast.sms;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}

3)创建配置文件application.properties

server.port=9003

spring.activemq.broker-url=tcp://192.168.25.135:61616

accessKeyId=不告诉你

accessKeySecret=不告诉你

3.2.2短信工具类

参照之前的短信demo创建短信工具类

package cn.itcast.sms;

import com.aliyuncs.DefaultAcsClient;

import com.aliyuncs.IAcsClient;

import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest;

import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;

import com.aliyuncs.exceptions.ClientException;

import com.aliyuncs.profile.DefaultProfile;

import com.aliyuncs.profile.IClientProfile;

import java.text.SimpleDateFormat;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.core.env.Environment;

import org.springframework.stereotype.Component;

/**

 * 短信工具类

 * @author Administrator

 *

 */

@Component

public class SmsUtil {

 

    //产品名称:云通信短信API产品,开发者无需替换

    static final String product = "Dysmsapi";

    //产品域名,开发者无需替换

    static final String domain = "dysmsapi.aliyuncs.com";

    

    @Autowired

    private Environment env;

 

    // TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)

    

    /**

     * 发送短信

     * @param mobile 手机号

     * @param template_code 模板号

     * @param sign_name 签名

     * @param param 参数

     * @return

     * @throws ClientException

     */

    public SendSmsResponse sendSms(String mobile,String template_code,String sign_name,String param) throws ClientException {

 

     String accessKeyId =env.getProperty("accessKeyId");

        String accessKeySecret = env.getProperty("accessKeySecret");

    

        //可自助调整超时时间

        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");

        System.setProperty("sun.net.client.defaultReadTimeout", "10000");

 

        //初始化acsClient,暂不支持region化

        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);

        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);

        IAcsClient acsClient = new DefaultAcsClient(profile);

 

        //组装请求对象-具体描述见控制台-文档部分内容

        SendSmsRequest request = new SendSmsRequest();

        //必填:待发送手机号

        request.setPhoneNumbers(mobile);

        //必填:短信签名-可在短信控制台中找到

        request.setSignName(sign_name);

        //必填:短信模板-可在短信控制台中找到

        request.setTemplateCode(template_code);

        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为

        request.setTemplateParam(param);

 

        //选填-上行短信扩展码(无特殊需求用户请忽略此字段)

        //request.setSmsUpExtendCode("90997");

 

        //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者

        request.setOutId("yourOutId");

 

        //hint 此处可能会抛出异常,注意catch

        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);

 

        return sendSmsResponse;

    }

 

    public  QuerySendDetailsResponse querySendDetails(String mobile,String bizId) throws ClientException {

     String accessKeyId =env.getProperty("accessKeyId");

        String accessKeySecret = env.getProperty("accessKeySecret");

        //可自助调整超时时间

        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");

        System.setProperty("sun.net.client.defaultReadTimeout", "10000");

        //初始化acsClient,暂不支持region化

        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);

        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);

        IAcsClient acsClient = new DefaultAcsClient(profile);

        //组装请求对象

        QuerySendDetailsRequest request = new QuerySendDetailsRequest();

        //必填-号码

        request.setPhoneNumber(mobile);

        //可选-流水号

        request.setBizId(bizId);

        //必填-发送日期 支持30天内记录查询,格式yyyyMMdd

        SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd");

        request.setSendDate(ft.format(new Date()));

        //必填-页大小

        request.setPageSize(10L);

        //必填-当前页码从1开始计数

        request.setCurrentPage(1L);

        //hint 此处可能会抛出异常,注意catch

        QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request);

        return querySendDetailsResponse;

    }

}

3.2.3消息监听类

创建SmsListener.java

package cn.itcast.sms;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.jms.annotation.JmsListener;

import org.springframework.stereotype.Component;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;

import com.aliyuncs.exceptions.ClientException;

/**

 * 消息监听类

 * @author Administrator

 */

@Component

public class SmsListener {

@Autowired

private SmsUtil smsUtil;

@JmsListener(destination="sms")

public void sendSms(Map<String,String> map){

try {

SendSmsResponse response = smsUtil.sendSms(

map.get("mobile"),

map.get("template_code"),

map.get("sign_name"),

map.get("param")  );  

    System.out.println("Code=" + response.getCode());

        System.out.println("Message=" + response.getMessage());

        System.out.println("RequestId=" + response.getRequestId());

        System.out.println("BizId=" + response.getBizId());

} catch (ClientException e) {

e.printStackTrace();

}

}

}

3.3代码测试

修改springboot-demo  QueueController.java

@RequestMapping("/sendsms")

public void sendSms(){

Map map=new HashMap<>();

map.put("mobile", "13900001111");

map.put("template_code", "SMS_85735065");

map.put("sign_name", "黑马");

map.put("param", "{\"number\":\"102931\"}");

jmsMessagingTemplate.convertAndSend("sms",map);

}

启动itcast_sms

启动springboot-demo

地址栏输入:http://localhost:8088/sendsms.do 

观察控制台输出

SpringBoot框架与短信解决方案

随后短信也成功发送到你的手机上