springboot——集成阿里短信服务

本文详细介绍如何使用Java调用阿里云短信服务,包括快速入门步骤、Maven依赖配置、核心Java代码实现及缓存机制,助您快速上手短信验证功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、快速入门

1、注册账号;
2、进入短信服务,点击新手引导;
新手引导
3、申请国内短信签名 和 申请国内短信模版;
4、点击AccessKey创建AccessKey;
创建AccessKey
5、点击OpenAPI Explorer进入,选择“SendSms”
在这里插入图片描述
在这里插入图片描述

二、pom.xml配置

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter</artifactId>
	</dependency>
	<dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
		<optional>true</optional>
	</dependency>
	<dependency>
		<groupId>com.aliyun</groupId>
		<artifactId>aliyun-java-sdk-core</artifactId>
		<version>4.1.0</version>
	</dependency>
	<dependency>
		<groupId>com.google.guava</groupId>
		<artifactId>guava</artifactId>
		<version>28.1-jre</version>
	</dependency>
	<dependency>
		<groupId>org.apache.commons</groupId>
		<artifactId>commons-lang3</artifactId>
		<version>3.4</version>
	</dependency>
</dependencies>

三、Java代码

import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.gson.Gson;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * 短信服务
 */
@Service
public class SMSManagerImpl implements SMSManager {
    private static final Logger logger = LoggerFactory.getLogger(SMSManagerImpl.class);

    @Value("${aliyun.message.accessKeyId}")
    private String accessKeyId;
    @Value("${aliyun.message.accessKeySecret}")
    private String accessKeySecret;
    @Value("${aliyun.message.signName}")
    private String signName;

    @Override
    public boolean sendSmsRegisterCode(String phoneNumber){
        String code = getRandomCode();
        boolean success = false;
        try {
            success = isSuccess(sendSms(phoneNumber, "SMS_170800227", code));
            if (success) {
                numberCodeMapping.put(phoneNumber, Optional.of(code));
            }
        } catch (ClientException e) {
            logger.error("发送短信异常:", e);
        }
        return success;
    }

    @Override
    public boolean validateRegisterCode(String phoneNumber, String code) {
        Optional<String> optional = getValue(phoneNumber);
        return optional.filter(s -> Objects.equals(code, s)).isPresent();
    }

    /**
     * 判断是否成功
     *
     * @param response
     * @return
     */
    private boolean isSuccess(CommonResponse response) {
        boolean success = response.getHttpStatus() == 200;
        if (!success) {
            logger.error("短信发送失败:" + response.getData());
        } else {
            Map map = new Gson().fromJson(response.getData(), Map.class);
            success = Objects.equals("OK", map.get("Code"));
        }
        return success;
    }

    private IAcsClient getClient() {
        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        return new DefaultAcsClient(profile);
    }

    /**
     * 发送短信验证码
     *
     * @param phoneNumber
     * @param templateCode
     * @param code
     * @return
     */
    private CommonResponse sendSms(String phoneNumber, String templateCode, String code) throws ClientException {
        CommonRequest request = new CommonRequest();
        request.setMethod(MethodType.POST);
        request.setDomain("dysmsapi.aliyuncs.com");
        request.setVersion("2017-05-25");
        request.setAction("SendSms");
        request.putQueryParameter("RegionId", "cn-hangzhou");
        request.putQueryParameter("PhoneNumbers", phoneNumber);
        request.putQueryParameter("SignName", signName);
        request.putQueryParameter("TemplateCode", templateCode);
        request.putQueryParameter("TemplateParam", "{\"code\":\"" + code + "\"}");
        return getClient().getCommonResponse(request);
    }

    //============================================
    // 验证码缓存
    //============================================
    // 手机号<->验证码映射
    private LoadingCache<String, Optional<String>> numberCodeMapping = CacheBuilder.newBuilder()
            .concurrencyLevel(50).expireAfterAccess(15, TimeUnit.MINUTES)
            .build(new CacheLoader<String, Optional<String>>() {
                @Override
                public Optional<String> load(String key) throws Exception {
                    return Optional.empty();
                }
            });
    /**
     * 获取随机码
     *
     * @return
     */
    private String getRandomCode() {
        return RandomStringUtils.randomNumeric(6);
    }

    private Optional<String> getValue(String key) {
        try {
            return numberCodeMapping.get(key);
        } catch (ExecutionException e) {
            logger.error("获取缓存出错:", e);
        }
        return Optional.empty();
    }
}

四、参考链接

  1. Java实现短信验证码–(完整教程)
  2. Java调用阿里云短信通道服务【千锋出品】
  3. Java实现短信验证码(阿里云短信服务)
### Spring Boot 集成阿里短信服务 #### 1. 添加 Maven 依赖 为了在 Spring Boot 项目中集成阿里短信服务,首先需要在 `pom.xml` 文件中添加必要的依赖项。以下是推荐的依赖配置: ```xml <dependencies> <!-- 阿里短信服务 --> <dependency> <groupId>com.aliyun</groupId> <artifactId>dysmsapi20170525</artifactId> <version>2.0.22</version> </dependency> <!-- 阿里云 SDK 核心库 --> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>4.3.3</version> </dependency> </dependencies> ``` 这些依赖提供了访问阿里云 SMS API 所需的功能[^4]。 #### 2. 创建核心配置类 创建一个 Java 类来封装阿里短信服务的核心配置参数。这有助于提高代码的可读性和维护性。下面是一个简单的配置类示例: ```java @Configuration public class SmsConfig { @Value("${aliyun.sms.accessKeyId}") private String accessKeyId; @Value("${aliyun.sms.accessKeySecret}") private String accessKeySecret; @Bean public DefaultAcsClient acsClient() throws ClientException { Config config = new Config() .setAccessKeyId(accessKeyId) .setAccessKeySecret(accessKeySecret); return new DefaultAcsClient(config); } } ``` 此配置允许应用程序通过注入的方式轻松获取到 `DefaultAcsClient` 实例,从而简化后续的服务调用逻辑[^2]。 #### 3. 编写发送短信工具方法 定义一个实用程序类用于处理实际的短信发送操作。这里提供了一个基于模板 ID 和签名名称的方法作为例子: ```java @Service public class SmsUtil { @Autowired private DefaultAcsClient client; /** * 发送短信验证码给指定电话号码 */ public Result sendSms(String phoneNumber, String templateCode, Map<String, Object> params) { SendSmsRequest request = new SendSmsRequest(); request.setPhoneNumbers(phoneNumber); request.setSignName("您的签名"); request.setTemplateCode(templateCode); request.setTemplateParam(new Gson().toJson(params)); try { SendSmsResponse response = client.getAcsResponse(request); if ("OK".equals(response.getCode())) { return Result.success("发送成功!"); } else { return Result.fail(response.getMessage()); } } catch (ClientException e) { log.error("Failed to send SMS", e); return Result.fail(e.getErrMsg()); } } } ``` 这段代码展示了如何构建并执行一次完整的短信请求过程,同时也包含了异常捕获机制以确保系统的健壮性[^5]。 #### 4. 测试接口 最后,在控制器层面上可以设计一个 RESTful 接口来进行快速测试: ```java @RestController @RequestMapping("/sms") public class SmsController { @Autowired private SmsUtil smsUtil; @GetMapping("/sendVerificationCode") public ResponseEntity<?> sendVerificationCode(@RequestParam String phone) { String verificationCode = generateRandomCode(); // 将验证码存入缓存(如 Redis),以便稍后验证 Map<String, Object> param = Collections.singletonMap("code", verificationCode); Result result = smsUtil.sendSms(phone, "SMS_XXXXXX", param); if (!result.isSuccess()) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result.getMsg()); } return ResponseEntity.ok("验证码已发送,请查收!"); } private static final Random random = new Random(System.currentTimeMillis()); private String generateRandomCode() { StringBuilder sb = new StringBuilder(6); for (int i = 0; i < 6; ++i) { sb.append(random.nextInt(10)); } return sb.toString(); } } ``` 上述实现不仅实现了基本的短信发送功能,还考虑到了安全性因素——即生成临时性的六位数随机码并通过安全通道传递给用户。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值