1、業務場景,在使用阿里大魚發送短信時,不知因何原因,後端接口發送短信較耗時,前端請求後端接口很快出現請求錯誤,這跟前端設置的響應時間相關,可以讓前端增加時間,但這並不是一個好的解決方法。
2、解決方案
使用異步調用阿里發送短信的方案。
3、啓動類添加註解
@EnableAsync // 開啓異步任務
4、異步調用,方法加註解
@Async
package com.ahies.stm.app.synthesizes.sys.service.impl;
import com.ahies.stm.app.synthesizes.sys.entity.Message;
import com.ahies.stm.app.synthesizes.sys.mapper.MessageMapper;
import com.ahies.stm.app.synthesizes.sys.service.MessageService;
import com.ahies.stm.app.base.BaseServiceImpl;
import com.ahies.stm.app.util.AliSendMessageUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;
@Service
@Transactional
public class MessageServiceImpl extends BaseServiceImpl<MessageMapper, Message> implements MessageService {
@Value("${accessKeyId}")
private String accessKeyId;
@Value("${accessKeySecret}")
private String accessKeySecret;
@Value("${templatecode.forgetpassword}")
private String templatecode;
@Value("${sign}")
private String sign;
/*
* @Description: 異步調用有返回值的阿里發送短信的方法
* @param phone, code
* @return java.util.concurrent.Future<java.lang.Boolean>
* @menu /
* @status done
*/
@Async
@Override
public Future<Boolean> sendMessage(String phone, String code) {
Map<String, String> param = new HashMap<>();
param.put("code", code);
boolean flag = AliSendMessageUtils.sendMessage(accessKeyId, accessKeySecret, phone, templatecode, sign, param);
return new AsyncResult<>(flag);
}
}
4、後臺發送短信的接口
package com.ahies.stm.app.interactive.index;
import com.ahies.stm.app.base.BaseController;
import com.ahies.stm.app.constant.SysConstant;
import com.ahies.stm.app.synthesizes.staff.entity.Member;
import com.ahies.stm.app.synthesizes.staff.service.MemberService;
import com.ahies.stm.app.synthesizes.sys.entity.Message;
import com.ahies.stm.app.synthesizes.sys.service.MessageService;
import com.ahies.stm.app.util.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/interactive/index/login")
@CrossOrigin
public class MemberLoginController extends BaseController {
@Autowired
MessageService messageService;
@Autowired
RedissonClient redissonClient;
@Value("${accessKeyId}")
private String accessKeyId;
@Value("${accessKeySecret}")
private String accessKeySecret;
@Value("${templatecode.forgetpassword}")
private String templatecode;
@Value("${sign}")
private String sign;
@RequestMapping("/authenticode")
public ResponseResult<String> authenticode(@RequestParam(name = "phone") String phone,
@RequestParam(name = "ckeckPhone", required = false) String ckeckPhone) {
if (StringUtils.isNotBlank(ckeckPhone)) {
QueryWrapper<Member> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(Member::getPhoneNum, phone);
Member member = memberService.getOne(wrapper);
if (null == member) {
return ResponseResult.dataFailed(null, SysConstant.PHONE_NOT_EXITS);
}
}
RBucket<String> rBucket = redissonClient.getBucket(SysConstant.AUTHENTICODE_KEY_PRE + phone);
String authenticode = "";
boolean flag = false;
if (StringUtils.isBlank(rBucket.get())) {
authenticode = String.valueOf((int) (Math.random() * 900000 + 100000));
String content = "您本次服務的驗證碼爲" + authenticode + ",請在10分鐘內使用。請勿向他人透露您的驗證碼。";
Map<String, String> param = new HashMap<>();
param.put("code", authenticode);
Future<Boolean> future = messageService.sendMessage(phone, authenticode);
try {
flag = future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
// flag = AliSendMessageUtils.sendMessage(accessKeyId, accessKeySecret, phone, templatecode, sign, param);
Message message = Message.builder().phone(phone).code(authenticode).content(content)
.build();
messageService.save(message);
rBucket.set(authenticode, 10, TimeUnit.MINUTES);
} else {
authenticode = rBucket.get();
rBucket.set(authenticode, 10, TimeUnit.MINUTES);
flag = true;
}
if (flag) {
return ResponseResult.dataSuccess(authenticode, SysConstant.SEND_SUCCESS);
}
return ResponseResult.dataFailed(authenticode, SysConstant.SEND_FAIL);
}
}