1. 程式人生 > >JAVA實現簡訊介面的呼叫

JAVA實現簡訊介面的呼叫

前言

   基本上在所有的APP或者網站上註冊使用者時大家都可以通過手機號進行註冊,這是一個專案必備的功能之一,但是怎麼實現的呢?通過接通簡訊介面,這一點大家想必都明白,接下來大家來看下具體操作,如有不對,請輕噴

第一步、找個簡訊批發商註冊個賬號,

筆者這裡選用的是榮聯-雲通訊平臺,只需要註冊一個賬號,進入管理控制檯自己檢視資訊即可,建立APP會產生APPID

二、配置檔案

我這使用的是SSM框架,進行如下配置(下面所有屬性都在榮聯裡面找得到)

三、編寫service層程式碼

package cn.yunfan.itrip.service.sms.impl;

import cn.yunfan.utils.SystemConfig;
import com.cloopen.rest.sdk.CCPRestSmsSDK;
import cn.yunfan.itrip.service.sms.SmsService;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Set;
@Service
public class SmsServiceImpl implements SmsService {
    Logger logger= Logger.getLogger(SmsServiceImpl.class);
    @Resource
    private SystemConfig systemConfig;
    @Override
    public void send(String to, String templateId, String[] datas) throws Exception {
        HashMap<String,Object>result =null;
        //初始化官方傳送簡訊的工具類
        CCPRestSmsSDK restAPI = new CCPRestSmsSDK();
         //根據主機和埠,初始化:resultAPI.init("app.cloopen.com","8883");
        restAPI.init(systemConfig.getSmsServerIP(),systemConfig.getSmsServerPort());
        //*初始化主賬號和主賬號令牌,對應官網開發者主賬號下的ACCOUNT SID 和 AUTH TOKEN
        //認證我的開發者賬號
        restAPI.setAccount(systemConfig.getSmsAccountSid(),systemConfig.getSmsAuthToken());
        //愛旅行的應用Id
        restAPI.setAppId(systemConfig.getSmsAppID());

        result= restAPI.sendTemplateSMS(to,templateId,datas);

        logger.debug("SDKTestGetSubAccounts result="+result);
        if("000000".equals(result.get("statusCode"))){//000000表示傳送成功
            //正常返回輸出data包體資訊(map)
            HashMap<String,Object> data = (HashMap<String,Object>)result.get("data");
            Set<String>keySet = data.keySet();
            for(String key:keySet){
                Object object = data.get(key);
                logger.debug(key+"="+object);
            }
        }else{
            //異常返回輸出錯誤碼和錯誤資訊
            System.out.println("錯誤碼="+result.get("statusCode")+"錯誤資訊="+result.get("statusMsg"));
            logger.error("錯誤碼="+result.get("statusCode")+"錯誤資訊="+result.get("statusMsg"));
            throw new Exception("錯誤碼="+result.get("statusCode")+"錯誤資訊="+result.get("statusMsg"));


        }
    }
}

PS:由於筆者使用了redis作為快取和一些工具類,這裡我就在下面一一列出

1、RedisAPI

package cn.yunfan.utils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

/**
 * RedisAPI
 * @author bdqn_hl
 * @date 2014-3-15
 */
public class RedisAPI {

   public JedisPool jedisPool;

   public JedisPool getJedisPool() {
      return jedisPool;
   }
   public void setJedisPool(JedisPool jedisPool) {
      this.jedisPool = jedisPool;
   }
   /**
    * set key and value to redis
    * @param key
    * @param value
    * @return
    */
   public boolean set(String key,String value){
      try{
         Jedis jedis = jedisPool.getResource();
         jedis.set(key, value);
         return true;
      }catch(Exception e){
         e.printStackTrace();
      }
      return false;
   }

   /**
    * set key and value to redis
    * @param key
    * @param seconds 有效期
    * @param value
    * @return
    */
   public boolean set(String key,int seconds,String value){
      try{
         Jedis jedis = jedisPool.getResource();
         jedis.setex(key, seconds, value);
         return true;
      }catch(Exception e){
         e.printStackTrace();
      }
      return false;
   }

   /**
    * 判斷某個key是否存在
    * @param key
    * @return
    */
   public boolean exist(String key){
      try{
         Jedis jedis = jedisPool.getResource();
         return jedis.exists(key);
      }catch(Exception e){
         e.printStackTrace();
      }
      return false;
   }

   /**
    * 返還到連線池
    * @param pool
    * @param redis
    */
   public static void returnResource(JedisPool pool,Jedis redis){
      if(redis != null){
         pool.returnResource(redis);
      }
   }

   /**
    * 獲取資料
    * @param key
    * @return
    */
   public String get(String key){
      String value = null;
      Jedis jedis = null;
      try{
         jedis = jedisPool.getResource();
         value = jedis.get(key);
      }catch(Exception e){
         e.printStackTrace();
      }finally{
         //返還到連線池
         returnResource(jedisPool, jedis);
      }

      return value;
   }

   /**
    * 查詢key的有效期,當 key 不存在時,返回 -2 。 當 key 存在但沒有設定剩餘生存時間時,返回 -1 。 否則,以秒為單位,返回 key 的剩餘生存時間。
    * 注意:在 Redis 2.8 以前,當 key 不存在,或者 key 沒有設定剩餘生存時間時,命令都返回 -1 。
    * @param key
    * @return 剩餘多少秒
    */
   public Long ttl(String key){
      try{
         Jedis jedis = jedisPool.getResource();
         return jedis.ttl(key);
      }catch(Exception e){
         e.printStackTrace();
      }
      return (long) -2;
   }

   /**
    * 刪除
    * @param key
    */
   public void delete(String key){
      try{
         Jedis jedis = jedisPool.getResource();
         jedis.del(key);
      }catch(Exception e){
         e.printStackTrace();
      }
   }
}

2、SystemCofing

package cn.yunfan.utils;
/**
 * SystemConfig
 * @author hanlu
 *
 */
public class SystemConfig {

   /**
    * 檔案上傳路徑,通過properties檔案進行配置
    */
   private String fileUploadPathString;
   /**
    * 上傳檔案訪問URL,通過properties檔案進行配置
    */
   private String visitImgUrlString;
   /**
    * 生成訂單的機器碼,通過properties檔案進行配置
    */
   private String machineCode;

   private String orderProcessOK;

   private String orderProcessCancel;

   /**
    * 雲通訊簡訊平臺賬戶Account Sid
    */
   private String smsAccountSid;
   /**
    * 雲通訊簡訊平臺賬戶Auth Toke
    */
   private String smsAuthToken;
   /**
    * 雲通訊簡訊平臺賬戶App ID
    */
   private String smsAppID;
   /**
    * 雲通訊簡訊平臺Server IP
    */
   private String smsServerIP;
   /**
    * 雲通訊簡訊平臺Server Port
    */
   private String smsServerPort;
   
   /**
    * 線上支付交易完成通知後續處理介面的地址
    */
   private String tradeEndsUrl;   

   /**
    * 支付模組傳送Get請求是否使用代理
    */
   private Boolean tradeUseProxy;
   /**
    * 代理主機
    */
   private String tradeProxyHost;
   /**
    * 代理埠
    */
   private Integer tradeProxyPort;

   public String getTradeEndsUrl() {
      return tradeEndsUrl;
   }

   public void setTradeEndsUrl(String tradeEndsUrl) {
      this.tradeEndsUrl = tradeEndsUrl;
   }
   public Boolean getTradeUseProxy() {
      return tradeUseProxy;
   }

   public void setTradeUseProxy(Boolean tradeUseProxy) {
      this.tradeUseProxy = tradeUseProxy;
   }

   public String getTradeProxyHost() {
      return tradeProxyHost;
   }

   public void setTradeProxyHost(String tradeProxyHost) {
      this.tradeProxyHost = tradeProxyHost;
   }

   public Integer getTradeProxyPort() {
      return tradeProxyPort;
   }

   public void setTradeProxyPort(Integer tradeProxyPort) {
      this.tradeProxyPort = tradeProxyPort;
   }

   public String getSmsAccountSid() {
      return smsAccountSid;
   }

   public void setSmsAccountSid(String smsAccountSid) {
      this.smsAccountSid = smsAccountSid;
   }

   public String getSmsAuthToken() {
      return smsAuthToken;
   }

   public void setSmsAuthToken(String smsAuthToken) {
      this.smsAuthToken = smsAuthToken;
   }

   public String getSmsAppID() {
      return smsAppID;
   }

   public void setSmsAppID(String smsAppID) {
      this.smsAppID = smsAppID;
   }

   public String getSmsServerIP() {
      return smsServerIP;
   }

   public void setSmsServerIP(String smsServerIP) {
      this.smsServerIP = smsServerIP;
   }

   public String getSmsServerPort() {
      return smsServerPort;
   }

   public void setSmsServerPort(String smsServerPort) {
      this.smsServerPort = smsServerPort;
   }

   public String getOrderProcessOK() {
      return orderProcessOK;
   }

   public void setOrderProcessOK(String orderProcessOK) {
      this.orderProcessOK = orderProcessOK;
   }

   public String getOrderProcessCancel() {
      return orderProcessCancel;
   }

   public void setOrderProcessCancel(String orderProcessCancel) {
      this.orderProcessCancel = orderProcessCancel;
   }

   public String getMachineCode() {
      return machineCode;
   }

   public void setMachineCode(String machineCode) {
      this.machineCode = machineCode;
   }

   public String getVisitImgUrlString() {
      return visitImgUrlString;
   }

   public void setVisitImgUrlString(String visitImgUrlString) {
      this.visitImgUrlString = visitImgUrlString;
   }

   public String getFileUploadPathString() {
      return fileUploadPathString;
   }

   public void setFileUploadPathString(String fileUploadPathString) {
      this.fileUploadPathString = fileUploadPathString;
   }
   
   
   
}

3、驗證電話號碼格式 ValiPhone

package cn.yunfan.utils;

import java.util.regex.Pattern;

public class ValidPhone {
    public static boolean validata(String phoneNumber){
        String pattern = "(1[345678]\\d{9})";
        Pattern r = Pattern.compile(pattern);
        return r.matcher(phoneNumber).matches();
    }
}

4、MD5密碼加密

package cn.yunfan.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

public class MD5 {

   public static String getMd5(String plainText,int length) {
      try {
         MessageDigest md = MessageDigest.getInstance("MD5");
         md.update(plainText.getBytes());
         byte b[] = md.digest();

         int i;

         StringBuffer buf = new StringBuffer("");
         for (int offset = 0; offset < b.length; offset++) {
            i = b[offset];
            if (i < 0)
               i += 256;
            if (i < 16)
               buf.append("0");
            buf.append(Integer.toHexString(i));
         }
         // 32位
         // return buf.toString();
         // 16位
         // return buf.toString().substring(0, 16);
         
         return buf.toString().substring(0, length);
      } catch (NoSuchAlgorithmException e) {
         e.printStackTrace();
         return null;
      }

   }

   public static int getRandomCode(){    
      int max=9999;
        int min=1111;
        Random random = new Random();
        return random.nextInt(max)%(max-min+1) + min;     
   }
   public static void main(String[] args) {
      System.out.println(MD5.getMd5("helloadsfdsffsf",6));
      System.out.println(getRandomCode());
   }

}

5、資料傳輸物件 Dto工具類

package cn.yunfan.itrip.pojo.dto;

/**
 * 資料傳輸物件(後端輸出物件)
 * @param <T>
 * Created by hanlu on 2017/5/7.
 */
public class Dto<T>{
   private String success; //判斷系統是否出錯做出相應的true或者false的返回,與業務無關,出現的各種異常
   private String errorCode;//該錯誤碼為自定義,一般0表示無錯
   private String msg;//對應的提示資訊
   private T data;//具體返回資料內容(pojo、自定義VO、其他)
   
   public T getData() {
      return data;
   }
   public void setData(T data) {
      this.data = data;
   }
   public String getSuccess() {
      return success;
   }
   public void setSuccess(String success) {
      this.success = success;
   }
   public String getErrorCode() {
      return errorCode;
   }
   public void setErrorCode(String errorCode) {
      this.errorCode = errorCode;
   }
   public String getMsg() {
      return msg;
   }
   public void setMsg(String msg) {
      this.msg = msg;
   }
   
}
package cn.yunfan.itrip.pojo.dto;

import io.swagger.annotations.ApiModelProperty;

/**
 * 資料傳輸物件(輸入物件)
 */
public class InputDto {

   @ApiModelProperty(value="單一引數傳入")
   private String paramString;
   @ApiModelProperty(value="多個引數傳入")
   private String[] paramStrings;
   public String getParamString() {
      return paramString;
   }
   public void setParamString(String paramString) {
      this.paramString = paramString;
   }
   public String[] getParamStrings() {
      return paramStrings;
   }
   public void setParamStrings(String[] paramStrings) {
      this.paramStrings = paramStrings;
   }
   
   
   
}

6、EmptyUtils工具

package cn.yunfan.utils;

import java.util.Collection;
import java.util.Map;

/**
 * <p>判斷是否是空的 工具類</p>
 * @author XX
 * @version v1.0
 * @since 2015/5/5
 */
public class EmptyUtils {
    //判空
    public static boolean isEmpty(Object obj){
        if (obj == null)
            return true;
        if (obj instanceof CharSequence)
            return ((CharSequence) obj).length() == 0;
        if (obj instanceof Collection)
            return ((Collection) obj).isEmpty();
        if (obj instanceof Map)
            return ((Map) obj).isEmpty();
        if (obj instanceof Object[]) {
            Object[] object = (Object[]) obj;
            if (object.length == 0) {
                return true;
            }
            boolean empty = true;
            for (int i = 0; i < object.length; i++) {
                if (!isEmpty(object[i])) {
                    empty = false;
                    break;
                }
            }
            return empty;
        }
        return false;
    }
    public static boolean isNotEmpty(Object obj){
        return !isEmpty(obj);
    }



    private boolean validPropertyEmpty(Object ...args) {
        for (int i = 0; i < args.length; i++) {
            if(EmptyUtils.isEmpty(args[i])){
                return true;
            }
        }
        return false;
    }
}

第四步、編寫Controller層

package cn.yunfan.itrip.controller;
import cn.yunfan.itrip.pojo.dto.Dto;
import cn.yunfan.itrip.pojo.ItripUser;

import cn.yunfan.itrip.service.user.UserService;
import cn.yunfan.itrip.pojo.vo.userinfo.ItripUserVO;
import cn.yunfan.utils.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;


import javax.annotation.Resource;

@Controller
@RequestMapping("/api")
public class UserController {

    @Resource
    UserService userService;
   //驗證是否該註冊名存在
    @RequestMapping(value = "/ckusr", method = RequestMethod.GET, produces = "application/json")
    @ResponseBody
    public Dto checkUser(@RequestParam String name) {
        try {
            //判斷註冊的使用者名稱是否存在 -- 如果返回真則已存在 --否者可以使用
            if (userService.findUserByUserCode(name) != null) {
                return DtoUtil.returnFail("使用者已經存在", ErrorCode.AUTH_USER_ALREADY_EXISTS);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return DtoUtil.returnFail("伺服器正忙,請稍後再試", ErrorCode.AUTH_UNKNOWN);
        }
        return DtoUtil.returnSuccess("使用者名稱可用");
    }
  
    //手機註冊
    @RequestMapping(value = "registerbyphone",method = RequestMethod.POST)
    public @ResponseBody Dto registerByPhone(@RequestBody ItripUser userVo){
        if(!ValidPhone.validata(userVo.getUserCode())){
            return DtoUtil.returnFail("手機號碼格式不正確",ErrorCode.AUTH_ILLEGAL_USERCODE);
        }
        try{
            //  呼叫傳送簡訊、插入使用者資料
            userVo.setActivated(0);
            userVo.setUserType(0); //自己註冊的賬號
            userVo.setUserPassword(MD5.getMd5(userVo.getUserPassword(),32));
            userService.itripexCreateUserByPhone(userVo);
            return  DtoUtil.returnSuccess("手機註冊成功");//返回一個成功的Json物件
        }catch (Exception ex){
            ex.printStackTrace();
        }
        return DtoUtil.returnFail("手機註冊失敗!",ErrorCode.AUTH_UNKNOWN);
    }
   //啟用手機賬號
    @RequestMapping("/validatephone")
    public @ResponseBody Dto activeByPhone(@RequestParam String user ,@RequestParam String code){
        if(!ValidPhone.validata(user)){ //驗證手機號是否正確
            return DtoUtil.returnFail("手機號碼格式不正確",ErrorCode.AUTH_ILLEGAL_USERCODE);
        }
        try {//呼叫啟用
            boolean isActived = userService.activateByPhone(user,code);
            if(isActived){
                return DtoUtil.returnSuccess("啟用成功!");
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }
        return DtoUtil.returnFail("手機啟用失敗!",ErrorCode.AUTH_ACTIVATE_FAILED);
    }
}

第五步、執行程式碼,測試成功