SpringBoot 整合 中國移動 MAS HTTP1.0 實現短信發送服務


因為客戶需要,本身使用的 阿里雲的短信服務改為了中國移動MAS HTTP 1.0  短信通知,因為看到網絡上關於此類的博客知識很少,再趟完坑后特地寫下這篇博客,提醒后來人。

特別感謝 中國移動MAS 客服  @左立,可能你看不到,非常感謝你 不厭其煩的回答!!

首先創建 接口,用戶類型是HTTP

然后下載文檔,下載簽名:

這里簡單說一下流程: HTTP 1.0 的通訊方式是,

1. 先向中國移動 發送 企業名、接口名、接口密碼,實現登錄操作。中國移動返回登錄id 和密鑰。

2. 攜帶中國移動返回的密鑰和 所需要的信息進行第二次的 請求,此次請求就是發送短信的請求。

 

根據文檔書寫所需要的發送短信的工具類:

 1 public class HttpSend {
 2     private  static String ec_name = "山東*****" ;  // 企業名
 3     private  static String user_name = "***" ;   // 接口賬號
 4     private  static String user_passwd = "****" ;   // 接口賬號密碼
 5     private  static String sign = "*****" ;  //簽名編號
 6     private  static String serial = "" ;   // 擴展碼
 7     private  static String checkUrl = "http://mas.ecloud.10086.cn/app/http/authorize" ;   // 身份驗證url
 8     private  static String sendUrl = "http://mas.ecloud.10086.cn/app/http/sendSms" ;      // 發送信息的url
 9 
10     // 身份驗證方法
11     public static CheckRes check (){
12         String req = "ec_name="+ec_name+"&user_name="+user_name+"&user_passwd="+user_passwd ;
13         System.out.println("傳入參數:"+req);
14         HttpRequest httpRequest = new HttpRequest() ;
15         String checkStr = httpRequest.sendPost(checkUrl,req) ;   //返回驗證信息的 回參
16         System.out.println("驗證身份結果:"+checkStr);
17         CheckRes checkRes = JSONUtils.json2pojo(checkStr,CheckRes.class);
18         String mas_user_id = checkRes.getMas_user_id() ;
19         System.out.println("mas_user_id:"+mas_user_id);
20         return checkRes ;
21     }
22 
23     // 發送短信 方法,需要使用到 check()方法的 返回值 CheckRes
24     public static Boolean send (CheckRes checkRes ,String mobiles ,String content){
25         String temporary = checkRes.getMas_user_id() + mobiles + content + sign + serial + checkRes.getAccess_token() ;  // 存放要進行加密的信息
26         String mac = MD5Util.getMD5Up(temporary) ;    //加密
27         String sendReq = "mas_user_id="+checkRes.getMas_user_id()+"&mobiles="+mobiles+"&content="+content+"&sign="+sign+"&serial="+serial+"&mac="+mac;
28         HttpRequest httpRequest = new HttpRequest() ;
29         String sendStr = httpRequest.sendPost(sendUrl,sendReq) ;     //發送 普通短信
30         System.out.println("發送結果:"+sendStr);
31         String[] test = sendStr.split(",",0);  // 將字符串 按照 逗號分隔,取前面一段
32         if (test[0].equals("{\"RET-CODE\":\"SC:0000\"")){  // 直接進行比較
33             return true ;
34         }else {
35             return false ;
36         }
37 
38     }
39 
40     // 測試 main函數
41     public static void main(String[] args){
42         CheckRes result = check() ;
43         Boolean b =send(result,"15610446589","益羊鐵路測試短信");
44         if (b){
45             System.out.println("成功");
46         }else {
47             System.out.println("失敗");
48         }
49     }
50 
51 }

這里用到的工具 HttpRequest ,用於攜帶參數請求頁面:

public class HttpRequest {
    /**
     * 向指定URL發送GET方法的請求
     *
     * @param url
     *            發送請求的URL
     * @param param
     *            請求參數,請求參數應該是 name1=value1&name2=value2 的形式。
     * @return URL 所代表遠程資源的響應結果
     */
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            URL realUrl = new URL(urlNameString);
            // 打開和URL之間的連接
            URLConnection connection = realUrl.openConnection();
            // 設置通用的請求屬性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立實際的連接
            connection.connect();
            // 獲取所有響應頭字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍歷所有的響應頭字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
            // 定義 BufferedReader輸入流來讀取URL的響應
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("發送GET請求出現異常!" + e);
            e.printStackTrace();
        }
        // 使用finally塊來關閉輸入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }
    /**
     * 向指定 URL 發送POST方法的請求
     *
     * @param url
     *            發送請求的 URL
     * @param param
     *            請求參數,請求參數應該是 name1=value1&name2=value2 的形式。
     * @return 所代表遠程資源的響應結果
     */
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打開和URL之間的連接
            URLConnection conn = realUrl.openConnection();
            // 設置通用的請求屬性
//            conn.setRequestProperty("accept", "*/*");
//            conn.setRequestProperty("connection", "Keep-Alive");
//            conn.setRequestProperty("user-agent",
//                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 發送POST請求必須設置如下兩行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 獲取URLConnection對象對應的輸出流
            out = new PrintWriter(conn.getOutputStream());
            // 發送請求參數
            out.print(param);
            // flush輸出流的緩沖
            out.flush();
            // 定義BufferedReader輸入流來讀取URL的響應
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("發送 POST 請求出現異常!"+e);
            e.printStackTrace();
        }
        //使用finally塊來關閉輸出流、輸入流
        finally{
            try{
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
            }
            catch(IOException ex){
                ex.printStackTrace();
            }
        }
        return result;
    }
}

JSONUtils工具:

public class JSONUtils {
    private final static ObjectMapper objectMapper = new ObjectMapper();
    private static Logger log = LoggerFactory.getLogger(JSONUtils.class);

    private JSONUtils() {

    }

    public static ObjectMapper getInstance() {

        return objectMapper;
    }

    public static String obj2json(Object obj) {

        try {
            return objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            // TODO Auto-generated catch block
            log.error(e.getMessage());
        }
        return null;
    }

    public static <T> T json2pojo(String jsonStr, Class<T> clazz) {
        try {
            return objectMapper.readValue(jsonStr, clazz);
        } catch (JsonParseException e) {
            // TODO Auto-generated catch block
            log.error(e.getMessage());
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    }

MD5工具,加密使用大寫的 MD5加密方式

public class MD5Util {
    public static String getMD5(String value) {
        String s = null;
        char hexDigits[] = { // 用來將字節轉換成 16 進制表示的字符
                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c',
                'd', 'e', 'f'};
        try {
            java.security.MessageDigest md = java.security.MessageDigest
                    .getInstance("MD5");
            md.update(value.getBytes());
            // MD5 的計算結果是一個 128 位的長度整數,
            byte tmp[] = md.digest();

            // 用字節表示就是 16 個字節
            char str[] = new char[16 * 2]; // 每個字節用 16 進制表示的話,使用兩個字符,

            // 所以表示成 16 進制需要 32 個字符
            int k = 0; // 表示轉換結果中對應的字符位置
            for (int i = 0; i < 16; i++) { // 從第一個字節開始,對 MD5 的每一個字節
                // 轉換成 16 進制字符的轉換
                byte byte0 = tmp[i]; // 取第 i 個字節
                str[k++] = hexDigits[byte0 >>> 4 & 0xf]; // 取字節中高 4 位的數字轉換,
                // >>> 為邏輯右移(即無符號右移),將符號位一起右移
                // 取字節中低 4 位的數字轉換
                str[k++] = hexDigits[byte0 & 0xf];
            }
            s = new String(str); // 換后的結果轉換為字符串

        } catch (Exception e) {
            e.printStackTrace();
        }
        return s;
    }
    // MD5大寫
    public static String getMD5Up(String value) {
        String s = null;
        char hexDigits[] = { // 用來將字節轉換成 16 進制表示的字符
                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
                'D', 'E', 'F'};
        try {
            java.security.MessageDigest md = java.security.MessageDigest
                    .getInstance("MD5");
            md.update(value.getBytes());
            // MD5 的計算結果是一個 128 位的長度整數,
            byte tmp[] = md.digest();

            // 用字節表示就是 16 個字節
            char str[] = new char[16 * 2]; // 每個字節用 16 進制表示的話,使用兩個字符,

            // 所以表示成 16 進制需要 32 個字符
            int k = 0; // 表示轉換結果中對應的字符位置
            for (int i = 0; i < 16; i++) { // 從第一個字節開始,對 MD5 的每一個字節
                // 轉換成 16 進制字符的轉換
                byte byte0 = tmp[i]; // 取第 i 個字節
                str[k++] = hexDigits[byte0 >>> 4 & 0xf]; // 取字節中高 4 位的數字轉換,
                // >>> 為邏輯右移(即無符號右移),將符號位一起右移
                // 取字節中低 4 位的數字轉換
                str[k++] = hexDigits[byte0 & 0xf];
            }
            s = new String(str); // 換后的結果轉換為字符串

        } catch (Exception e) {
            e.printStackTrace();
        }
        return s;
    }

    /**
     * 判斷字符串的md5校驗碼是否與一個已知的md5碼相匹配
     *
     * @param md5  要校驗的字符串
     * @param md5PwdStr 已知的md5校驗碼
     */
    public static boolean checkPassword(String md5, String md5PwdStr) {
        return md5.equals(md5PwdStr);
    }
}

這里注意的是 ,這兩次的請求都是 post 請求。

要注意拼接字符串以及加密的字符串 的順序是不能亂的!!

                                                              最后再次感謝 @左立

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM