提示:本文仅记录本人工作中遇到的难点与个人见解,仅供参考,如有问题请见谅。
目录
3、MessageController类:短信验证码发送接口
前言
此文章仅记录网易云信的短信验证开发事项
提示:以下是本篇文章正文内容,下面案例可供参考
一、网易云信短信服务是什么?
短信服务(Short Message Service)是网易云信为用户提供的一种通信服务的能力,目前支持验证码类短信、通知类短信、运营类短信、语音类短信、国际短信等事务性短信。
二、使用步骤
1、创建网易云信工具类CheckSumBuilder
代码如下:
import lombok.extern.slf4j.Slf4j;
import java.security.MessageDigest;
/**
* 该类复制与网易云信的开发文档、用于生成一个CheckSum参数
*/
@Slf4j
public class CheckSumBuilder {
// 计算并获取CheckSum
public static String getCheckSum(String appSecret, String nonce, String curTime) {
return encode("sha1", appSecret + nonce + curTime);
}
// 计算并获取md5值
public static String getMD5(String requestBody) {
return encode("md5", requestBody);
}
private static String encode(String algorithm, String value) {
if (value == null) {
return null;
}
try {
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
messageDigest.update(value.getBytes());
return getFormattedText(messageDigest.digest());
} catch (Exception e) {
log.error("短信验证码错误:" + e.getMessage());
throw new RuntimeException(e);
}
}
private static String getFormattedText(byte[] bytes) {
int len = bytes.length;
StringBuilder buf = new StringBuilder(len * 2);
for (byte aByte : bytes) {
buf.append(HEX_DIGITS[(aByte >> 4) & 0x0f]);
buf.append(HEX_DIGITS[aByte & 0x0f]);
}
return buf.toString();
}
private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
}
2、短信验证码发送SendCodeUtil工具类
import com.alibaba.fastjson.JSONObject;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.util.*;
/**
* 网易云信-短信验证码发送
*/
public class SendCodeUtil {
// 发送验证码的URL
private static final String SERVER_URL = "https://api.netease.im/sms/sendcode.action";
// 校验验证码的URL
private static final String VERIFY_URL = "https://api.netease.im/sms/verifycode.action";
// 网易云信分配的账号
private static final String APP_KEY = "*****************";
// 网易云信分配的密钥
private static final String APP_SECRET = "**********";
// 随机数(认证人的生日)
private static final String NONCE = "*****";
// 短信模板ID
private static final String TEMPLATE_ID = "*****";
// 验证码长度,范围4~10,默认为4
private static final String CODE_LEN = "4";
// 发送短信验证码
public static JSONObject sendCode(String phone) {
// 当前时间戳0
String curTime = String.valueOf((new Date()).getTime() / 1000L);
// 计算CheckSum
String checkSum = CheckSumBuilder.getCheckSum(APP_SECRET, NONCE, curTime);
// 添加请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.add("AppKey", APP_KEY);
headers.add("Nonce", NONCE);
headers.add("CurTime", curTime);
headers.add("CheckSum", checkSum);
// 添加请求体
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("templateid", TEMPLATE_ID);
body.add("codeLen", CODE_LEN);
body.add("mobile", phone);
// 封装请求头和请求体
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(body, headers);
/*
获取返回结果,示例:{"code":200,"msg":"401","obj":"2596"}
code-200表示状态码正常
msg-401表示此次发送的sendId
obj-2596表示此次发送的验证码
*/
ResponseEntity<JSONObject> response = new RestTemplate().postForEntity(SERVER_URL, request, JSONObject.class);
// 返回Body体
return response.getBody();
}
// 检验验证码是否有效
public static Boolean verifyCode(String phone, String code) {
String curTime = String.valueOf((new Date()).getTime() / 1000L);
String checkSum = CheckSumBuilder.getCheckSum(APP_SECRET, NONCE, curTime);
// 添加请求体
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("mobile", phone);
body.add("code", code);
// 添加请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.add("AppKey", APP_KEY);
headers.add("Nonce", NONCE);
headers.add("CurTime", curTime);
headers.add("CheckSum", checkSum);
// 封装请求头和请求体
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(body, headers);
// 发送请求,获取到返回结果
ResponseEntity<JSONObject> response = new RestTemplate().postForEntity(VERIFY_URL, request, JSONObject.class);
// 获取到结果里面的Body内容
JSONObject object = response.getBody();
assert object != null;
// 如果code为200说明为true,否则为false
return object.get("code").toString().equals("200");
}
public static void main(String[] args) {
System.out.println(sendCode("155********"));
System.out.println(verifyCode("155********", "****"));
}
}
3、MessageController类:短信验证码发送接口
代码如下:
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@Api(tags = "短信验证码发送接口")
@RestController
@RequestMapping("/message")
public class MessageController {
/**
* 向指定的手机号发送短信验证码
* @param phone 手机号
*/
@ApiOperation(value = "发送短信验证码", notes = "发送短信验证码")
@RequestMapping(value = "/sendCode", method = RequestMethod.GET)
public Result<String> sendCode(@RequestParam("phone") String phone) {
// TODO 2022/12/8: 如何判断验证码是否已发送
Result<String> result = new Result<>();
try {
// 获取到返回结果
JSONObject object = SendCodeUtil.sendCode(phone);
if (oConvertUtils.isNotEmpty(object)) {
if (object.get("code").toString().equals("200")) {
result.setSuccess(true);
result.setMessage("请求成功,请稍候!");
} else {
result.setSuccess(false);
result.setMessage("验证码发送失败,请稍后再试!");
}
}
} catch (Exception e) {
result.setSuccess(false);
result.setMessage("未知错误,请稍后再试!" + e.getMessage());
}
return result;
}
}