xmtrock
发布于 2021-06-09 / 273 阅读
0

阿里云短信 | 邮箱邮件通知

1、依赖

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
</dependency>

2、properties

# 服务端口
server.port=8204
# 服务名
spring.application.name=service-msm
#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
spring.redis.host=47.115.203.188
spring.redis.port=6604
spring.redis.password=flowerpower
spring.redis.database=0
spring.redis.timeout=1800000
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0
# nacos服务地址
spring.cloud.nacos.discovery.server-addr=localhost:8848
# 阿里云短信服务
aliyun.sms.regionId=default
aliyun.sms.accessKeyId=LT6I0Y5633pX89qC
aliyun.sms.secret=jX8D04Dm12I3gGKj345FYSzu0fq8mT

3、启动类(发送短信不需要数据库,所以取消)

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)//取消数据源自动配置
@EnableDiscoveryClient
@ComponentScan(basePackages = "com.soulike")//swagger找到
public class ServiceMsmApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceMsmApplication.class, args);
        System.out.println("http://localhost:8204/swagger-ui.html");
    }
}

4、配置类(用来拿到properties的值且当做常量来用:ConstantPropertiesUtils.REGION_ID)

@Component
public class ConstantPropertiesUtils implements InitializingBean {

    @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;
    }
}

5、短信验证码生成类

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;
    }
}

6、配合redis来做

@RestController
@RequestMapping("/api/msm")
public class MsmApiController {
    @Autowired
    private MsmService msmService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    //发送手机验证码的方法
    @GetMapping("/send/{phone}")
    public Result sendCode(@PathVariable("phone") String phone) {
        //先从redis获取。如果可以获取那么直接返回ok
        String code = redisTemplate.opsForValue().get(phone);
        if (!StringUtils.isEmpty(code)) return Result.ok();

        //否则生成验证码通过整合阿里云短信服务进行发送
        //生成验证码,通过整合短信服务进行发送
        code = RandomUtil.getSixBitRandom();
        boolean isSend = msmService.send(phone, code);

        //生成验证码放到redis里,设置有效时间
        if (isSend) {
            redisTemplate.opsForValue().set(phone, code, 30, TimeUnit.MINUTES);
            return Result.ok();
        } else {
            return Result.fail().message("发送短信失败");
        }
    }
}
@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.putQueryParameter("PhoneNumbers", phone);
        //签名名称
        request.putQueryParameter("SignName", "尚医通");
        //模板code
        request.putQueryParameter("TemplateCode", "SMS_218156204");
        //验证码  使用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;
    }
}

1、依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

2、properties(password是授权码不是密码)

# 服务端口
server.port=8204
# 服务名
spring.application.name=service-msm
#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
spring.redis.host=47.115.203.188
spring.redis.port=6604
spring.redis.password=flowerpower
spring.redis.database=0
spring.redis.timeout=1800000
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0
# nacos服务地址
spring.cloud.nacos.discovery.server-addr=localhost:8848
# 邮箱
spring.mail.host=smtp.126.com
spring.mail.port=465
spring.mail.username=miantianhold@126.com
spring.mail.password=DPCKKXYFAPXYYBHS
spring.mail.default-encoding=UTF-8
spring.mail.properties.mail.smtp.ssl.enable=true
spring.mail.properties.mail.smpt.socketFactoryClass=javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.smpt.debug=true

3、使用上比手机容易

@RestController
@RequestMapping("/api/mail")
public class MailApiController {
    @Autowired
    private MailService mailService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    //发送手机验证码的方法
    @GetMapping("/send/{email}")
    public Result sendCode(@PathVariable("email") String email) {
        //先从redis获取。如果可以获取那么直接返回ok
        String code = redisTemplate.opsForValue().get(email);
        if (!StringUtils.isEmpty(code)) return Result.ok();

        //否则生成验证码通过mail进行发送
        code = RandomUtil.getSixBitRandom();
        boolean isSend = mailService.send(email, code);

        //生成验证码放到redis里,设置有效时间
        if (isSend) {
            redisTemplate.opsForValue().set(email, code, 30, TimeUnit.MINUTES);
            return Result.ok();
        } else {
            return Result.fail().message("发送邮件失败");
        }
    }
}
@Service
public class MailServiceImpl implements MailService {
    @Autowired
    JavaMailSenderImpl javaMailSender;

    @Override
    public boolean send(String email, String code) {
        //判断邮箱
        if (StringUtils.isEmpty(email)) return false;

        try {
            // 构建一个邮件对象
            SimpleMailMessage message = new SimpleMailMessage();
            // 设置邮件主题
            message.setSubject("尚医通项目的测试");
            // 设置邮件发送者,这个跟application.yml中设置的要一致
            message.setFrom("miantianhold@126.com");
            // 设置邮件接收者,可以有多个接收者,中间用逗号隔开,以下类似
            // message.setTo("10*****16@qq.com","12****32*qq.com");
            message.setTo(email);
            // 设置邮件抄送人,可以有多个抄送人
            //message.setCc("12****32*qq.com");
            // 设置隐秘抄送人,可以有多个
            //message.setBcc("7******9@qq.com");
            // 设置邮件发送日期
            message.setSentDate(new Date());
            // 设置邮件的正文
            message.setText("你好,你的验证码是:" + code + "。验证码30分钟内有效");
            // 发送邮件
            javaMailSender.send(message);
        } catch (Exception e) {

        }

        return true;
    }
}

阿里云的短信工具类(端口调用)

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dm.model.v20151123.SingleSendMailRequest;
import com.aliyuncs.dm.model.v20151123.SingleSendMailResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import org.junit.Test;

public class SMSUtils {
    private static final String accessKeyId = "LTAI5tJ5SXhVhucZtWanfAY7";
    private static final String accessKeySecret = "gxPRkZgf6tYkScZO7XO4tLyHeD4LBM";
    //private static final String emailAddress = "728407682@qq.com";
    private static final String messageTemplate = "你好,你的验证码是";
    private static final String accountName = "mail@soulike.xyz";
    private static final String alias = "腼腆Hold";

    public static void sample(String emailAddress, String message) {
        // 如果是除杭州region外的其它region(如新加坡、澳洲Region),需要将下面的"cn-hangzhou"替换为"ap-southeast-1"、或"ap-southeast-2"。
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);

        IAcsClient client = new DefaultAcsClient(profile);

        SingleSendMailRequest request = new SingleSendMailRequest();
        try {
            //request.setVersion("2017-06-22");// 如果是除杭州region外的其它region(如新加坡region),必须指定为2017-06-22
            request.setAccountName(accountName);
            request.setFromAlias(alias);//发信人昵称,长度小于15个字符。
            request.setAddressType(1);//0:为随机账号 1:为发信地址
            request.setTagName("标签");
            request.setReplyToAddress(true);// 是否启用管理控制台中配置好回信地址(状态须验证通过),取值范围是字符串true或者false
            //可以给多个收件人发送邮件,收件人之间用逗号分开,批量发信建议使用BatchSendMailRequest方式
            //request.setToAddress("邮箱1,邮箱2");
            request.setToAddress(emailAddress);

            request.setSubject("邮件主题");
            //如果采用byte[].toString的方式的话请确保最终转换成utf-8的格式再放入htmlbody和textbody,若编码不一致则会被当成垃圾邮件。
            //注意:文本邮件的大小限制为3M,过大的文本会导致连接超时或413错误
            request.setHtmlBody(messageTemplate + ":" + message);
            //SDK 采用的是http协议的发信方式, 默认是GET方法,有一定的长度限制。
            //若textBody、htmlBody或content的大小不确定,建议采用POST方式提交,避免出现uri is not valid异常
            request.setMethod(MethodType.POST);
            //开启需要备案,0关闭,1开启
            //request.setClickTrace("0");
            //如果调用成功,正常返回httpResponse;如果调用失败则抛出异常,需要在异常中捕获错误异常码;错误异常码请参考对应的API文档;
            SingleSendMailResponse httpResponse = client.getAcsResponse(request);

        } catch (ServerException e) {
            //捕获错误异常码
            System.out.println("ErrCode : " + e.getErrCode());
            e.printStackTrace();
        } catch (ClientException e) {
            //捕获错误异常码
            System.out.println("ErrCode : " + e.getErrCode());
            e.printStackTrace();
        }
    }
}