• 全网最详细SpringBoot、SpringCloud整合阿里云短信服务


    1、进入阿里云官网

    https://www.aliyun.com/

    2、搜索短信服务 

    3、进入短信控制台

    4、选择国内消息

    5、点击添加签名

    6、输入相关信息,点击提交

    7、点击模块管理,选择添加模块

    8、输入相关信息,点击提交

     

    9、鼠标放在头像上,点击下拉框中的AccessKey管理

    10、点击创建AccessKey

    11、输入验证码

    12、创建成功,两串字符串复制一下

    13、pom.xml中引入阿里云相关依赖,还有redis的依赖

    1. <dependency>
    2. <groupId>com.aliyungroupId>
    3. <artifactId>aliyun-java-sdk-coreartifactId>
    4. <version>4.5.16version>
    5. dependency>
    6. <dependency>
    7. <groupId>org.springframework.bootgroupId>
    8. <artifactId>spring-boot-starter-data-redisartifactId>
    9. dependency>

    14、配置application.properties(不是微服务项目就不要加nacos了)

    1. # 服务端口
    2. server.port=8204
    3. # 服务名
    4. spring.application.name=service-msm
    5. #返回json的全局时间格式
    6. spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
    7. spring.jackson.time-zone=GMT+8
    8. # redis配置
    9. spring.redis.host=192.168.44.165
    10. spring.redis.port=6379
    11. spring.redis.database= 0
    12. spring.redis.timeout=1800000
    13. spring.redis.lettuce.pool.max-active=20
    14. spring.redis.lettuce.pool.max-wait=-1
    15. # 最大阻塞等待时间(负数表示没限制)
    16. spring.redis.lettuce.pool.max-idle=5
    17. spring.redis.lettuce.pool.min-idle=0
    18. # nacos服务地址
    19. spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
    20. aliyun.sms.regionId=default
    21. # 第12步复制的两串字符串
    22. aliyun.sms.accessKeyId=LT6I0Y5633pX89qC
    23. aliyun.sms.secret=jX8D04Dm12I3gGKj345FYSzu0fq8mT

    15、添加启动类

    1. //取消数据源自动配置,因为application.properties配置文件中没有配置数据库
    2. //如果application.properties配置文件中配置了数据库,“(exclude = DataSourceAutoConfiguration.class)”就不用加了
    3. @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
    4. @EnableDiscoveryClient
    5. public class ServiceMsmApplication {
    6. public static void main(String[] args) {
    7. SpringApplication.run(ServiceMsmApplication.class, args);
    8. }
    9. }

    16、配置网关(不是微服务项目就不用写这一步)

    1. spring.cloud.gateway.routes[3].id=service-msm
    2. #设置路由的uri
    3. spring.cloud.gateway.routes[3].uri=lb://service-msm
    4. #设置路由断言,代理servicerId为auth-service的/auth/路径
    5. spring.cloud.gateway.routes[3].predicates= Path=/*/msm/**

    17、添加阿里云短信服务配置类

    1. import org.springframework.beans.factory.InitializingBean;
    2. import org.springframework.beans.factory.annotation.Value;
    3. import org.springframework.stereotype.Component;
    4. @Component
    5. public class ConstantPropertiesUtils implements InitializingBean {
    6. //对应application.properties配置文件中的aliyun.sms.regionId=default
    7. @Value("${aliyun.sms.regionId}")
    8. private String regionId;
    9. //对应application.properties配置文件中的aliyun.sms.accessKeyId=LT6I0Y5633pX89qC
    10. @Value("${aliyun.sms.accessKeyId}")
    11. private String accessKeyId;
    12. //对应application.properties配置文件中的aliyun.sms.secret=jX8D04Dm12I3gGKj345FYSzu0fq8mT
    13. @Value("${aliyun.sms.secret}")
    14. private String secret;
    15. public static String REGION_Id;
    16. public static String ACCESS_KEY_ID;
    17. public static String SECRECT;
    18. @Override
    19. public void afterPropertiesSet() throws Exception {
    20. REGION_Id=regionId;
    21. ACCESS_KEY_ID=accessKeyId;
    22. SECRECT=secret;
    23. }
    24. }

    18、添加redis配置类(如果项目中redis已经有配置类了,就不用再添加了)

    1. import com.fasterxml.jackson.annotation.JsonAutoDetect;
    2. import com.fasterxml.jackson.annotation.PropertyAccessor;
    3. import com.fasterxml.jackson.databind.ObjectMapper;
    4. import org.springframework.cache.CacheManager;
    5. import org.springframework.cache.annotation.EnableCaching;
    6. import org.springframework.cache.interceptor.KeyGenerator;
    7. import org.springframework.context.annotation.Bean;
    8. import org.springframework.context.annotation.Configuration;
    9. import org.springframework.data.redis.cache.RedisCacheConfiguration;
    10. import org.springframework.data.redis.cache.RedisCacheManager;
    11. import org.springframework.data.redis.connection.RedisConnectionFactory;
    12. import org.springframework.data.redis.core.RedisTemplate;
    13. import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    14. import org.springframework.data.redis.serializer.RedisSerializationContext;
    15. import org.springframework.data.redis.serializer.RedisSerializer;
    16. import org.springframework.data.redis.serializer.StringRedisSerializer;
    17. import java.lang.reflect.Method;
    18. import java.time.Duration;
    19. @Configuration
    20. @EnableCaching
    21. public class RedisConfig {
    22. /**
    23. * 自定义key规则
    24. * @return
    25. */
    26. @Bean
    27. public KeyGenerator keyGenerator() {
    28. return new KeyGenerator() {
    29. @Override
    30. public Object generate(Object target, Method method, Object... params) {
    31. StringBuilder sb = new StringBuilder();
    32. sb.append(target.getClass().getName());
    33. sb.append(method.getName());
    34. for (Object obj : params) {
    35. sb.append(obj.toString());
    36. }
    37. return sb.toString();
    38. }
    39. };
    40. }
    41. /**
    42. * 设置RedisTemplate规则
    43. * @param redisConnectionFactory
    44. * @return
    45. */
    46. @Bean
    47. public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
    48. RedisTemplate redisTemplate = new RedisTemplate<>();
    49. redisTemplate.setConnectionFactory(redisConnectionFactory);
    50. Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    51. //解决查询缓存转换异常的问题
    52. ObjectMapper om = new ObjectMapper();
    53. // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
    54. om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    55. // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
    56. om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    57. jackson2JsonRedisSerializer.setObjectMapper(om);
    58. //序列号key value
    59. redisTemplate.setKeySerializer(new StringRedisSerializer());
    60. redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
    61. redisTemplate.setHashKeySerializer(new StringRedisSerializer());
    62. redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
    63. redisTemplate.afterPropertiesSet();
    64. return redisTemplate;
    65. }
    66. /**
    67. * 设置CacheManager缓存规则
    68. * @param factory
    69. * @return
    70. */
    71. @Bean
    72. public CacheManager cacheManager(RedisConnectionFactory factory) {
    73. RedisSerializer redisSerializer = new StringRedisSerializer();
    74. Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    75. //解决查询缓存转换异常的问题
    76. ObjectMapper om = new ObjectMapper();
    77. om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    78. om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    79. jackson2JsonRedisSerializer.setObjectMapper(om);
    80. // 配置序列化(解决乱码的问题),过期时间600秒
    81. RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
    82. .entryTtl(Duration.ofSeconds(600))
    83. .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
    84. .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
    85. .disableCachingNullValues();
    86. RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
    87. .cacheDefaults(config)
    88. .build();
    89. return cacheManager;
    90. }
    91. }

    19、添加验证码自动生成工具类

    1. import java.text.DecimalFormat;
    2. import java.util.ArrayList;
    3. import java.util.HashMap;
    4. import java.util.List;
    5. import java.util.Random;
    6. public class RandomUtil {
    7. private static final Random random = new Random();
    8. private static final DecimalFormat fourdf = new DecimalFormat("0000");
    9. private static final DecimalFormat sixdf = new DecimalFormat("000000");
    10. public static String getFourBitRandom() {
    11. return fourdf.format(random.nextInt(10000));
    12. }
    13. public static String getSixBitRandom() {
    14. return sixdf.format(random.nextInt(1000000));
    15. }
    16. /**
    17. * 给定数组,抽取n个数据
    18. * @param list
    19. * @param n
    20. * @return
    21. */
    22. public static ArrayList getRandom(List list, int n) {
    23. Random random = new Random();
    24. HashMap hashMap = new HashMap();
    25. // 生成随机数字并存入HashMap
    26. for (int i = 0; i < list.size(); i++) {
    27. int number = random.nextInt(100) + 1;
    28. hashMap.put(number, i);
    29. }
    30. // 从HashMap导入数组
    31. Object[] robjs = hashMap.values().toArray();
    32. ArrayList r = new ArrayList();
    33. // 遍历数组并打印数据
    34. for (int i = 0; i < n; i++) {
    35. r.add(list.get((int) robjs[i]));
    36. System.out.print(list.get((int) robjs[i]) + "\t");
    37. }
    38. System.out.print("\n");
    39. return r;
    40. }
    41. }

    20、开发阿里云发送短信接口

    20.1、Controller层:

    1. import com.hospital.common.result.Result;
    2. import com.hospital.msm.service.MsmService;
    3. import com.hospital.msm.utils.RandomUtil;
    4. import org.apache.commons.lang.StringUtils;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.data.redis.core.RedisTemplate;
    7. import org.springframework.web.bind.annotation.GetMapping;
    8. import org.springframework.web.bind.annotation.PathVariable;
    9. import org.springframework.web.bind.annotation.RequestMapping;
    10. import org.springframework.web.bind.annotation.RestController;
    11. import java.util.concurrent.TimeUnit;
    12. @RestController
    13. @RequestMapping("/api/msm")
    14. public class MsmApiController {
    15. @Autowired
    16. private MsmService msmService;
    17. @Autowired
    18. private RedisTemplate redisTemplate;
    19. /**
    20. * 发送手机验证码
    21. * @param phone
    22. * @return
    23. */
    24. @GetMapping("/send/{phone}")
    25. public Result sendCode(@PathVariable String phone){
    26. //从redis中获取验证码,如果获取到,返回ok
    27. //key:手机号,value:验证码
    28. String code = redisTemplate.opsForValue().get(phone);
    29. if (!StringUtils.isEmpty(code)){
    30. return Result.ok();
    31. }
    32. //如果从redis中获取不到,就自己生成验证码
    33. code = RandomUtil.getSixBitRandom();
    34. //通过调用service方法,整合阿里云短信服务进行发送
    35. boolean isSend = msmService.send(phone,code);
    36. //如果阿里云短信服务发送成功就给isSend返回为true
    37. //然后把生成的验证码放到redis里面,并设置过期时间
    38. if(isSend){
    39. //超过两分钟,验证码就失效了
    40. redisTemplate.opsForValue().set(phone,code,2, TimeUnit.MINUTES);
    41. return Result.ok();
    42. }else {
    43. return Result.fail().message("发送短信失败!!!");
    44. }
    45. }
    46. }

    20.2、Service层:

    1. public interface MsmService {
    2. //阿里云短信服务发送手机验证码
    3. boolean send(String phone, String code);
    4. }

    20.3、Service实现层:

    1. import com.alibaba.fastjson.JSONObject;
    2. import com.aliyuncs.CommonRequest;
    3. import com.aliyuncs.CommonResponse;
    4. import com.aliyuncs.DefaultAcsClient;
    5. import com.aliyuncs.IAcsClient;
    6. import com.aliyuncs.exceptions.ClientException;
    7. import com.aliyuncs.exceptions.ServerException;
    8. import com.aliyuncs.http.MethodType;
    9. import com.aliyuncs.profile.DefaultProfile;
    10. import com.hospital.msm.service.MsmService;
    11. import com.hospital.msm.utils.ConstantPropertiesUtils;
    12. import org.apache.commons.lang.StringUtils;
    13. import org.springframework.stereotype.Service;
    14. import java.util.HashMap;
    15. import java.util.Map;
    16. @Service
    17. public class MsmServiceImpl implements MsmService {
    18. /**
    19. * 阿里云短信服务发送手机验证码
    20. * @param phone
    21. * @param code
    22. * @return
    23. */
    24. @Override
    25. public boolean send(String phone, String code) {
    26. //判断手机号是否为空
    27. if (StringUtils.isEmpty(phone)){
    28. return false;
    29. }
    30. //传入ConstantPropertiesUtils配置类中从application.properties配置文件中获取的三个值
    31. DefaultProfile profile = DefaultProfile.
    32. getProfile(ConstantPropertiesUtils.REGION_Id,
    33. ConstantPropertiesUtils.ACCESS_KEY_ID,
    34. ConstantPropertiesUtils.SECRECT);
    35. IAcsClient client = new DefaultAcsClient(profile);
    36. CommonRequest request = new CommonRequest();
    37. //request.setProtocol(ProtocolType.HTTPS); //发送的协议如果是https就不注释
    38. request.setMethod(MethodType.POST); //这一行是固定的
    39. request.setDomain("dysmsapi.aliyuncs.com"); //这一行是固定的
    40. request.setVersion("2017-05-25"); //这一行是固定的
    41. request.setAction("SendSms"); //这一行是固定的
    42. //手机号
    43. request.putQueryParameter("PhoneNumbers", phone);
    44. //签名名称
    45. request.putQueryParameter("SignName", "我的谷粒在线教育网站");
    46. //模板code
    47. request.putQueryParameter("TemplateCode", "SMS_257677932");
    48. //验证码 使用json格式 {"code":"123456"}
    49. Map param = new HashMap();
    50. param.put("code",code);
    51. request.putQueryParameter("TemplateParam", JSONObject.toJSONString(param));
    52. //调用方法进行短信发送
    53. try {
    54. CommonResponse response = client.getCommonResponse(request);
    55. System.out.println(response.getData());
    56. return response.getHttpResponse().isSuccess();
    57. } catch (ServerException e) {
    58. e.printStackTrace();
    59. } catch (ClientException e) {
    60. e.printStackTrace();
    61. }
    62. //失败就返回false
    63. return false;
    64. }
    65. }

    21、登录接口判断用户输入的验证码和阿里云服务发送的验证码是否相同

  • 相关阅读:
    【论文笔记】An Image Patch is a Wave: Phase-Aware Vision MLP
    MySQL 学习笔记②
    Go语言的100个错误使用场景(30-40)|数据类型与字符串使用
    RunApi在发送请求的时候添加Token
    服务器动态/静态/住宅/原生IP都是什么意思
    2023秋招大厂经典面试题及答案整理归纳(341-360)校招必看【Linux篇】
    js数据过滤算法搭建
    现货白银的价格如何变动
    如何进行列间排序
    Bias and Debias in Recommender System: A Survey and Future Directions学习笔记
  • 原文地址:https://blog.csdn.net/weixin_55076626/article/details/127853987