1:个人如何使用阿里云短信服务?
2022如何使用个人阿里云短信服务?_linxiMY的博客-CSDN博客
添加完成之后,等待审核!一般2个小时就会出来审核结果了,这里我因为注册申请时填写规则有误,足足审核了7次才通过!点击进来以后,按照要求填写:因为一个账号只能选购一种,所以我这里就没法仔细演示了。然后点击添加即可,一把2-3个小时就可以申请出结果了。ConstantPropertiesUtils 工具类。点击登录阿里云短信服务控制台--->点击。3:创建一个SpringBoot 启动类。将下面的服务地址改为自己对应的地址。AccessKey 保存下来!4:添加一个配置工具类类。开启启动类调接口测试。
2:直接上代码
2.1:建表SQL
CREATE TABLE `sys_user` ( `id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'id', `username` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '用户名', `password` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '密码', `nickname` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '昵称', `email` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '邮箱', `phone` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '电话', `address` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '地址', `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `avatarUrl` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '头像', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
2.2:后端代码
引入pom.xml 依 赖:
<dependencies> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> </dependency> </dependencies>
yml 文件:
server: port: 9999 spring: application: name: demo-end datasource: druid: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/数据库?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true username: root password: root redis: host: ip地址 port: 6379 lettuce: pool: max-active: 8 # ???? max-idle: 8 # ?????? min-idle: 0 # ?????? max-wait: 100ms # ?????? mybatis: configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl mapper-locations: classpath:mapper/*.xml type-aliases-package: com.xi.demoend.entity
application.properties:
aliyun.sms.regionId=default aliyun.sms.accessKeyId=xxxxxx aliyun.sms.secret=xxxxxx
common公共包下的类:
全局统一返回结果:
package com.xialj.demoend.common; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * @Author * @Date Created in 2023/2/23 17:25 * @DESCRIPTION: 全局统一返回结果 * @Version V1.0 */ @Data @ApiModel(value = "全局统一返回结果") @SuppressWarnings("all") public class Result<T> { @ApiModelProperty(value = "返回码") private Integer code; @ApiModelProperty(value = "返回消息") private String message; @ApiModelProperty(value = "返回数据") private T data; private Long total; public Result(){} protected static <T> Result<T> build(T data) { Result<T> result = new Result<T>(); if (data != null) result.setData(data); return result; } public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) { Result<T> result = build(body); result.setCode(resultCodeEnum.getCode()); result.setMessage(resultCodeEnum.getMessage()); return result; } public static <T> Result<T> build(Integer code, String message) { Result<T> result = build(null); result.setCode(code); result.setMessage(message); return result; } public static<T> Result<T> ok(){ return Result.ok(null); } /** * 操作成功 * @param data * @param <T> * @return */ public static<T> Result<T> ok(T data){ Result<T> result = build(data); return build(data, ResultCodeEnum.SUCCESS); } public static<T> Result<T> fail(){ return Result.fail(null); } /** * 操作失败 * @param data * @param <T> * @return */ public static<T> Result<T> fail(T data){ Result<T> result = build(data); return build(data, ResultCodeEnum.FAIL); } public Result<T> message(String msg){ this.setMessage(msg); return this; } public Result<T> code(Integer code){ this.setCode(code); return this; } public boolean isOk() { if(this.getCode().intValue() == ResultCodeEnum.SUCCESS.getCode().intValue()) { return true; } return false; } }
统一返回结果状态信息类:
package com.xialj.demoend.common; import lombok.Getter; /** * @Author * @Date Created in 2023/2/23 17:25 * @DESCRIPTION: 统一返回结果状态信息类 * @Version V1.0 */ @Getter @SuppressWarnings("all") public enum ResultCodeEnum { SUCCESS(200,"成功"), FAIL(201, "失败"), PARAM_ERROR( 202, "参数不正确"), SERVICE_ERROR(203, "服务异常"), DATA_ERROR(204, "数据异常"), DATA_UPDATE_ERROR(205, "数据版本异常"), LOGIN_AUTH(208, "未登陆"), PERMISSION(209, "没有权限"), CODE_ERROR(210, "验证码错误"), // LOGIN_MOBLE_ERROR(211, "账号不正确"), LOGIN_DISABLED_ERROR(212, "改用户已被禁用"), REGISTER_MOBLE_ERROR(213, "手机号码格式不正确"), REGISTER_MOBLE_ERROR_NULL(214, "手机号码为空"), LOGIN_AURH(214, "需要登录"), LOGIN_ACL(215, "没有权限"), URL_ENCODE_ERROR( 216, "URL编码失败"), ILLEGAL_CALLBACK_REQUEST_ERROR( 217, "非法回调请求"), FETCH_ACCESSTOKEN_FAILD( 218, "获取accessToken失败"), FETCH_USERINFO_ERROR( 219, "获取用户信息失败"), //LOGIN_ERROR( 23005, "登录失败"), PAY_RUN(220, "支付中"), CANCEL_ORDER_FAIL(225, "取消订单失败"), CANCEL_ORDER_NO(225, "不能取消预约"), HOSCODE_EXIST(230, "医院编号已经存在"), NUMBER_NO(240, "可预约号不足"), TIME_NO(250, "当前时间不可以预约"), SIGN_ERROR(300, "签名错误"), HOSPITAL_OPEN(310, "医院未开通,暂时不能访问"), HOSPITAL_LOCK(320, "医院被锁定,暂时不能访问"), HOSPITAL_LOCKKEY(330,"医院对应key不一致") ; private Integer code; private String message; private ResultCodeEnum(Integer code, String message) { this.code = code; this.message = message; } }
untils包下的工具类:
ConstantPropertiesUtils 用来读取 application.properties文件中的配置
package com.xialj.demoend.utils; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * @Author * @Date Created in 2023/2/23 17:25 * @DESCRIPTION: * @Version V1.0 */ @Component public class ConstantPropertiesUtils implements InitializingBean { //InitializingBean 初始化bean 让spring 容器一初始化就加载 @Value("${aliyun.sms.regionId}") private String regionId; @Value("${aliyun.sms.accessKeyId}") private String accessKeyId; @Value("${aliyun.sms.secret}") private String secret; public static String REGION_Id; public static String ACCESS_KEY_ID; public static String SECRECT; @Override public void afterPropertiesSet() throws Exception { REGION_Id=regionId; ACCESS_KEY_ID=accessKeyId; SECRECT=secret; } }
RandomUtil 工具类用来生成6位验证码:
package com.xialj.demoend.utils; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Random; /** * @Author * @Date Created in 2023/2/23 17:25 * @DESCRIPTION: * @Version V1.0 */ @SuppressWarnings("ALL") public class RandomUtil { private static final Random random = new Random(); private static final DecimalFormat fourdf = new DecimalFormat("0000"); private static final DecimalFormat sixdf = new DecimalFormat("000000"); public static String getFourBitRandom() { return fourdf.format(random.nextInt(10000)); } public static String getSixBitRandom() { return sixdf.format(random.nextInt(1000000)); } /** * 给定数组,抽取n个数据 * @param list * @param n * @return */ public static ArrayList getRandom(List list, int n) { Random random = new Random(); HashMap<Object, Object> hashMap = new HashMap<Object, Object>(); // 生成随机数字并存入HashMap for (int i = 0; i < list.size(); i++) { int number = random.nextInt(100) + 1; hashMap.put(number, i); } // 从HashMap导入数组 Object[] robjs = hashMap.values().toArray(); ArrayList r = new ArrayList(); // 遍历数组并打印数据 for (int i = 0; i < n; i++) { r.add(list.get((int) robjs[i])); System.out.print(list.get((int) robjs[i]) + "\t"); } System.out.print("\n"); return r; } }
User实体类:(实现了简单的手机验证码登录+email邮箱登录)
package com.xialj.demoend.entity; import com.alibaba.druid.sql.visitor.functions.Insert; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; import java.io.Serializable; import java.text.SimpleDateFormat; import java.util.Date; /** * @Author * @Date Created in 2023/2/24 13:07 * @DESCRIPTION: User 实体类 * @Version V1.0 */ @Data public class User extends PageQuery implements Serializable { private static final long serialVersionUID = 1L; /** * id */ private String id; /** * 用户名 */ private String username; /** * 密码 */ private String password; /** * 昵称 */ private String nickname; /** * 邮箱 */ @ApiModelProperty(value = "联系人邮箱") @NotBlank(message = "邮箱不能为空", groups = {Insert.class}) @NotNull(message = "邮箱不能为空", groups = {Insert.class}) @Pattern(regexp = ".+@.+\\.com$", message = "Email格式不正确") private String email; /** * 电话 */ @ApiModelProperty(value = "联系人电话") @NotBlank(message = "手机号码不能为空", groups = {Insert.class}) @NotNull(message = "手机号不能为空", groups = {Insert.class}) @Length(min = 11, max = 11, message = "手机号只能为11位") @Pattern(regexp = "^[1][3,4,5,6,7,8,9][0-9]{9}$", message = "手机号格式有误") private String phone; /** * 地址 */ private String address; /** * 验证码 */ private Integer code; /** * 创建时间 */ @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") private Date createTime; /** * 头像 */ private String avatarUrl; }
MsmApiController:用来实现发送验证码的接口
package com.xialj.demoend.controller; import cn.hutool.extra.mail.MailUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.xialj.demoend.common.Result; import com.xialj.demoend.common.ResultCodeEnum; import com.xialj.demoend.common.paramCommon; import com.xialj.demoend.entity.User; import com.xialj.demoend.service.MsmService; import com.xialj.demoend.utils.JsonSerializer; import com.xialj.demoend.utils.RandomUtil; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.mail.MessagingException; import javax.validation.constraints.Email; import java.util.Set; import java.util.concurrent.TimeUnit; /** * @Author xlj * @Date Created in 2023/2/23 17:25 * @DESCRIPTION: 主要是为了实现邮箱发送验证码,以及手机发送验证码登录 * @Version V1.0 */ @RestController @RequestMapping("/api/msm") @SuppressWarnings("ALL") @Slf4j @CrossOrigin public class MsmApiController { @Autowired private MsmService msmService; @Autowired private RedisTemplate<String,String> redisTemplate; //将手机验证码存放到redis 中,并设置过期时间 @ApiOperation(value = "发送手机验证码") @PostMapping("sendPhoneCode") public Result sendCode(@RequestBody(required = true) @Validated User user){ String phoneNum = user.getPhone(); // phone 作为redis 中的key, code 作为redis 中的value值 String code = redisTemplate.opsForValue().get(phoneNum); if (!StringUtils.isEmpty(code)) { //这里为什么从redis 拿取 验证码 我理解的是 ,因为redis 验证码我们给他设置了时间限制,所以在规定时间内,验证码 //可以多次使用,一旦时间到期之后,我们就需要从新生成6位数的验证码了。 return Result.ok(code); } //生成六位验证码 code = RandomUtil.getSixBitRandom(); //调用service 方法,整合阿里云短信服务进行发送 Boolean isSend = msmService.send(phoneNum,code); //返回的Boolean 值进行判断 ,如果发送信息成功,即存入到redis 中,如果没有则提示验证码发送失败 if (isSend) { //放到redis中规定时间内有效 redisTemplate.opsForValue().set(phoneNum,code,1, TimeUnit.MINUTES); redisTemplate.setDefaultSerializer(new JsonSerializer<>()); // redisTemplate.opsForValue().set(phoneNum,code); String codeMessage = redisTemplate.opsForValue().get(phoneNum); Set<String> allKeys = redisTemplate.keys("*"); for (String key : allKeys) { System.out.println(key); System.out.println(key.getClass().getName()); } log.info("当前存储的验证码为:{}",codeMessage); return Result.ok(code); } else { return Result.fail().message(paramCommon.FAIL_MESSAGE); } } }
MsmServiceImpl实现类:
package com.hospital.service.impl; import com.alibaba.fastjson.JSONObject; import com.aliyuncs.CommonRequest; import com.aliyuncs.CommonResponse; import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.IAcsClient; import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.exceptions.ServerException; import com.aliyuncs.http.MethodType; import com.aliyuncs.profile.DefaultProfile; import com.hospital.service.MsmService; import com.hospital.utils.ConstantPropertiesUtils; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import java.util.HashMap; import java.util.Map; @Service public class MsmServiceImpl implements MsmService { //根据手机号,存入验证码 @Override public Boolean send(String phone, String code) { //判断手机号是否为空 if (StringUtils.isEmpty(phone)) { return false; } //整合阿里云的短信服务 DefaultProfile profile = DefaultProfile. getProfile(ConstantPropertiesUtils.REGION_Id, ConstantPropertiesUtils.ACCESS_KEY_ID, ConstantPropertiesUtils.SECRECT); IAcsClient client = new DefaultAcsClient(profile); CommonRequest request = new CommonRequest(); //request.setProtocol(ProtocolType.HTTPS); request.setMethod(MethodType.POST); request.setDomain("dysmsapi.aliyuncs.com"); request.setVersion("2017-05-25"); request.setAction("SendSms"); // request.setSysAction(); //手机号 request.putQueryParameter("PhoneNumbers", phone); //签名名称 request.putQueryParameter("SignName", "自己申请的短信签名"); //模板code request.putQueryParameter("TemplateCode", "短信模板CODE"); //验证码 使用json格式 {"code":"123456"} Map<String,Object> param = new HashMap(); param.put("code",code); request.putQueryParameter("TemplateParam", JSONObject.toJSONString(param)); //调用方法进行短信发送 try { CommonResponse response = client.getCommonResponse(request); System.out.println(response.getData()); return response.getHttpResponse().isSuccess(); } catch (ServerException e) { e.printStackTrace(); } catch (ClientException e) { e.printStackTrace(); } return false; } }