短信微服务

发送短信测试

创建aldy_demo的jar工程
导入依赖信息

<dependencies>
	<dependency>
		<groupId>com.aliyun</groupId>
		<artifactId>aliyun-java-sdk-core</artifactId>
		<version>3.7.1</version>
	</dependency>
	<dependency>
		<groupId>com.aliyun</groupId>
		<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
		<version>1.1.0</version>
	</dependency>
</dependencies>

参考阿里云短信服务的api短信服务api
创建demo类测试发送短信

public class SmsDemo {

    //产品名称:云通信短信API产品,开发者无需替换
    static final String product = "Dysmsapi";
    //产品域名,开发者无需替换
    static final String domain = "dysmsapi.aliyuncs.com";

    //此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)
    static final String accessKeyId = "";
    static final String accessKeySecret = "";

    public static SendSmsResponse sendSms() throws ClientException {

        //可自助调整超时时间
        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("");
        //必填:短信签名-可在短信控制台中找到
        request.setSignName("");
        //必填:短信模板-可在短信控制台中找到
        request.setTemplateCode("");
        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
        request.setTemplateParam("{\"code\":\"666888\"}");

        //hint 此处可能会抛出异常,注意catch
        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
        return sendSmsResponse;
    }

    public static void main(String[] args) throws ClientException, InterruptedException {
        //发短信
        SendSmsResponse response = sendSms();
        System.out.println("短信接口返回的数据----------------");
        System.out.println("Code=" + response.getCode());
        System.out.println("Message=" + response.getMessage());
        System.out.println("RequestId=" + response.getRequestId());
        System.out.println("BizId=" + response.getBizId());

    }

}

运行测试类向自己手机上发送一条验证码
在这里插入图片描述

微服务搭建

构建一个通用的短信发送服务(spring boot),接收activeMQ的消息(MAP类型)消息包括手机号(mobile)、短信模板号(template_code)、签名(sign_name)、参数字符串(param)
AcitiveMQ的消息类型是点对点的队列消息
创建一个jar工程youlexuan_sms
pom依赖信息

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.4.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-core</artifactId>
        <version>3.7.1</version>
    </dependency>
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
        <version>1.1.0</version>
    </dependency>

</dependencies>

创建引导类,放在包的根目录下

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

创建配置文件application.properties

server.port = 8888
spring.activemq.broker-url=tcp://192.168.2.123:61616
accessKeyId = *********
accessKeySecret = ********

抽取短信工具类(原来短信测试类的静态方法改成非静态的,因为是工具类,所以会通过工具类调用方法,所以没必要是静态方法;抽取出来的param字段要求是json格式的)

@Component
public class SmsUtil {

    @Value("${accessKeyId}")
    private String accessKeyId;
    @Value("${accessKeySecret}")
    private String accessKeySecret;

    //产品名称:云通信短信API产品,开发者无需替换
    static final String product = "Dysmsapi";
    //产品域名,开发者无需替换
    static final String domain = "dysmsapi.aliyuncs.com";

    public SendSmsResponse sendSms(String phone, String sign, String templateId, String param) throws ClientException {

        //可自助调整超时时间
        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(phone);
        //必填:短信签名-可在短信控制台中找到
        request.setSignName(sign);
        //必填:短信模板-可在短信控制台中找到
        request.setTemplateCode(templateId);
        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
        request.setTemplateParam(param);

        //hint 此处可能会抛出异常,注意catch
        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
        return sendSmsResponse;
    }
}

创建SmsListener类:

@Component
public class SmsListener {
    @Autowired
    private SmsUtil smsUtil;
    @JmsListener(destination = "smsDestination")
    public void sendSms(Map<String, String> map) {
        try {
            String phone = map.get("phone");
            String sign = map.get("sign");
            String templateId = map.get("templateId");
            String param = map.get("param");

            System.out.println(">>>>>receive msg: phone" + phone + ", sign: " + sign + ", templateId: " + templateId + ",param: " + param);

            SendSmsResponse sendSmsResponse = smsUtil.sendSms(phone, sign, templateId, param);

            System.out.println(">>>>>sms_service send sms result: " + sendSmsResponse.getCode());

        } catch (ClientException e) {
            e.printStackTrace();
        }
    }
}

这样发送短信的微服务我们就搭建好了,下面只需要在用户controller层以及service层进行生成验证码以及发送AcitiveMQ的消息
配置user_service工程下的spring-jms-producer.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    		http://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/context
    		http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.weilinyang" />

    <!-- 产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
    <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://192.168.2.123:61616" />
    </bean>

    <!-- Spring用于管理ConnectionFactory的ConnectionFactory -->
    <bean id="connectionFactory"
          class="org.springframework.jms.connection.SingleConnectionFactory">
        <property name="targetConnectionFactory" ref="targetConnectionFactory" />
    </bean>

    <!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="connectionFactory" />
    </bean>

    <!-- 队列目的地,点对点信息 -->
    <bean id="smsDestination" class="org.apache.activemq.command.ActiveMQQueue">
        <constructor-arg value="sms_queue" />
    </bean>

</beans>

@Reference
private UserService userService;

@RequestMapping("/sendCode")
public Result sendCode(String phone){
    if (!PhoneFormatCheckUtils.isChinaPhoneLegal(phone)){
        return new Result(false,"手机号非法!");
    }
    try {
        userService.createSmsCode(phone);
        return new Result(false,"短信发送成功!");
    } catch (Exception e) {
        e.printStackTrace();
        return new Result(false,"短信发送异常!");
    }
}
@Value("${sign}")
private String sign;
@Value("${templateId}")
private String templateId;
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private JmsTemplate jmsTemplate;

@Override
public void createSmsCode(String phone) {
    //Math.random()  范围[0,1)
    //1、生成6位验证码 100000-999999
    int num = (int)(Math.random() * 900000 + 100000);
    System.out.println("生成的验证码为"+num);
    Map<String,String> map = new HashMap<>();
    map.put("param","{\"code\":\"" + num + "\"}");
    map.put("phone",phone);
    map.put("sign",sign);
    map.put("templateId",templateId);

    // 2. 将验证码在 redis 中保存起来,以便注册时候校验
    redisTemplate.boundHashOps("register_code").put("code",num);
    System.out.println("存入redis");
    // 3. 发送验证码:通过向消息中间件发送消息,来驱动 sms_service 短信服务帮你发验证码
    jmsTemplate.convertAndSend("smsDestination",map);
    System.out.println("已发送actMQ");
}

验证码的校验

验证码的保存
验证码保存在redis数据库中,当用户点击注册时,我们再去redis库中查询与前端提交的进行比对

@RequestMapping("/add")
public Result addUser(@RequestBody TbUser user, String code){
    //校验验证码
    Integer redisCode = (Integer) redisTemplate.boundHashOps("register_code").get("code");
    try {
        if (Integer.parseInt(code)!=redisCode){
            return new Result(false,"验证码错误!");
        }
        // 设置注册时的一些默认信息
        user.setCreated(new Date());
        user.setUpdated(new Date());

        // 密码加密 md5
        user.setPassword(DigestUtils.md5Hex(user.getPassword()));
        userService.addUser(user);
        return new Result(true,"注册成功!");

    } catch (Exception e) {
        e.printStackTrace();
        return new Result(false,"注册失败!");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值