前期准备

  1. 从第三方云服务商购买短信服务:如:阿里云,腾讯云,华为云都可购买

准备工作:

2. 手机号,个人签名,模板code,随机验证码,阿里云扣钱的账号和value。

导入阿里云依赖:

<!--阿里云短信发送-->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.0.6</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
            <version>1.1.0</version>
        </dependency>
        
<!--jedis-->
    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.9.0</version>
    </dependency>

发送短信的工具类:

public class SmsUtil {

    private static String accessKeyId = "LTAI4sdqaE3rsdfXqa";//需要替换成自己申请的accessKeyId

    private static String accessKeySecret = "0IEmomXoHVtUCSFECsDY7X7YlePoDbZ";//需要替换成自己申请的accessKeySecret

    static final String product = "Dysmsapi";//产品名称:云通信短信API产品,开发者无需替换

    static final String domain = "dysmsapi.aliyuncs.com";//产品域名,开发者无需替换

    /**
     * 发送短信
     *
     * @param phoneNumbers 手机号
     * @param code         验证码
     */
    public static void sendSms(String phoneNumbers, String code) {
        sendSms(phoneNumbers, "[****]", "SMS_16822572160", "{\"code\":\"" + code + "\"}");
    }

    /**
     * 发送短信
     *
     * @param phoneNumbers 要发送短信到哪个手机号
     * @param signName     短信签名[必须使用前面申请的]
     * @param templateCode 短信短信模板ID[必须使用前面申请的]
     * @param param        模板中${code}位置传递的内容
     */
    public static void sendSms(String phoneNumbers, String signName, String templateCode, String param) {
        try {
            //可自助调整超时时间
            System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
            System.setProperty("sun.net.client.defaultReadTimeout", "10000");

            //初始化acsClient,暂不支持region化
            IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
            IAcsClient acsClient = new DefaultAcsClient(profile);

            //组装请求对象-具体描述见控制台-文档部分内容
            SendSmsRequest request = new SendSmsRequest();
            //必填:待发送手机号
            request.setPhoneNumbers(phoneNumbers);
            //必填:短信签名-可在短信控制台中找到
            request.setSignName(signName);
            //必填:短信模板-可在短信控制台中找到
            request.setTemplateCode(templateCode);
            //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
            request.setTemplateParam(param);

            //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
            //request.setSmsUpExtendCode("90997");

            //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
            request.setOutId("yourOutId");

            //hint 此处可能会抛出异常,注意catch
            SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);

            if (!"OK".equals(sendSmsResponse.getCode())) {
                throw new RuntimeException(sendSmsResponse.getMessage());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("发送短信失败");
        }
    }

redis工具类:

public class JedisUtils {
    private static JedisPool jedisPool=null;
    static {
        //加载一次连接池即可
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(50);
        jedisPoolConfig.setMaxIdle(5);
        //1 创建jedis的连接池
       jedisPool = new JedisPool(jedisPoolConfig,"localhost",6379);
    }
    //从连接池中获取jedis的方法
    public static Jedis getJedis(){

        //2 从连接池中获取jedis
        Jedis jedis = jedisPool.getResource();
        return jedis;
    }
}

登录业务流程:

ios 阿里一键登录600004 阿里云手机一键登录_redis


Controller层

@Controller
@RequestMapping(value = "/user")
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/sendSMS",name = "发短信")
    public String sendSMS(String telephone){
        String sjyzm = RandomUtil.randomNumbers(8);
        //将手机号和验证码传递给阿里云第三方工具类
        SmsUtil.sendSms(telephone,sjyzm);
        //将验证码放入redis并设置过期时间
        Jedis jedis = JedisUtils.getJedis();
        //设置过期时间180秒
        jedis.setex("telephoneYZM", 60 * 2, sjyzm);
        jedis.close();
        return "ok";
    }
    @RequestMapping(value = "/login",name = "登录")
    @ResponseBody
    public String login(String telephone, String yzm, HttpSession httpSession){
        //先从jedis中获取验证码
        Jedis jedis = JedisUtils.getJedis();
        String telephoneYZM = jedis.get("telephoneYZM");
        //用户输入的验证码和redis中的验证码做对比
        if (yzm ==null || !yzm.equals(telephoneYZM)){
            return "0";
        }
        //调用service看有没有该手机号
        User user = userService.UserService(telephone);
        if (user==null){
            return "1";
        }
        httpSession.setAttribute("user",user);
        return "ok";
    }
}

Service层接口:

public interface UserService {
    public User UserService(String telephone);
}

Service层实现类:

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    public User UserService(String telephone) {
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        //条件对象查询如果手机号和收据库信息相同
        criteria.andUsernameEqualTo(telephone);
        List<User> list = userMapper.selectByExample(userExample);
        if (list.size()>0){
            return list.get(0); //说明有数据
        }
        return null;
    }
}

mapper接口:

public interface UserMapper {
 List<User> selectByExample(UserExample example);
 }
<select id="selectByExample" parameterType="com.puxinkeji.domain.UserExample" resultMap="BaseResultMap">
    select
    <if test="distinct">
      distinct
    </if>
    <include refid="Base_Column_List" />
    from tb_user
    <if test="_parameter != null">
      <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null">
      order by ${orderByClause}
    </if>
  </select>