对接七陌短信平台

开发过程中,需要发送信息给客户,调用第三方:容联七陌的短信平台 https://developer.7moor.com/v2docs/sms/;

首先需要将自己需要的短信模板想七陌报备, 模板样例: 尊敬的{1}先生您好,您的订单{2},如有问题请致电110;

其中的{1}{2}就是可变量,在发送信息时需要传递;最终客户收到的信息可能是这样的: [签名]尊敬的张三先生您好,您的订单OR123456789,如有问题请致电110;

其中签名也是报备短信模板一起规定的;

各个运营商为了防止你发送大批量的重复短信,会有一个拦截机制,规定一定时间内,同样的短信发送数量,例如五分钟两条;

运营商还有一个短信拦截机制,就是过滤一些敏感词汇,如果你的短信中含有敏感词汇,手机上就收不到短信,

但是!!! 你发送一条短信时,七陌不管你的手机号码会不会收到短信,只要他们发送成功了,就会返回给你说短信发送成功!

所以,在短信模板报备时,就必须注意,是否含有敏感词汇!不然的话,你发送一条短信,七陌告诉你成功了,但是,手机上没有收到信息!

为了规避运营商针对同样内容一定时间内短信数量的限制,可以报备多个内容相同但是签名不同的短信模板,在自己的代码中,根据七陌返回的信息判断,发送失败,就换一个短信模板发送.

所以,在自己的数据库中,需要两张表,一张表存七陌返回的报备的短信模板信息,另一张表存自己的短信模板信息:

(mysql数据库)

CREATE TABLE `t_msg_template` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `message_channel` varchar(32) DEFAULT NULL COMMENT '信息对接方:qimo',
  `message_type` char(2) DEFAULT NULL COMMENT '信息类型:1-短信;2-语音',
  `open_api_id` varchar(32) DEFAULT NULL COMMENT '对接方返回的模板主键',
  `num` int(10) DEFAULT NULL COMMENT '模板编号,发送信息时要传的参数',
  `name` varchar(32) DEFAULT NULL COMMENT '模板名称',
  `content` longtext COMMENT '模板内容,其中含有变量用{1},{2},按顺序增长',
  `vars` int(32) DEFAULT NULL COMMENT '变量个数',
  `sign` varchar(32) DEFAULT NULL COMMENT '签名',
  `is_deleted` char(1) NOT NULL DEFAULT 'N' COMMENT '是否删除',
  `creator` varchar(32) NOT NULL COMMENT '创建者',
  `modifier` varchar(32) NOT NULL COMMENT '修改者',
  `gmt_created` datetime NOT NULL COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='短信模板表';
 

CREATE TABLE `t_msg_detail_template` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `message_code` varchar(32) DEFAULT NULL COMMENT '短信模板code',
  `message_name` varchar(32) DEFAULT NULL COMMENT '短信模板名称',
  `expression` varchar(256) DEFAULT NULL COMMENT '表达式',
  `remark` varchar(256) DEFAULT NULL COMMENT '备注',
  `message_nums` varchar(32) NOT NULL COMMENT '短信模板num-多个用逗号隔开',
  `phone_number` varchar(256) DEFAULT NULL COMMENT '群发特定短信的号码-多个用逗号隔开',
  `is_deleted` char(1) NOT NULL DEFAULT 'N' COMMENT '是否删除',
  `creator` varchar(32) NOT NULL COMMENT '创建者',
  `modifier` varchar(32) NOT NULL COMMENT '修改者',
  `gmt_created` datetime NOT NULL COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8 COMMENT='内部短信详细模板';

这样就可以在自己的模板表中配置多个七陌的短信模板num,在他们返回发送失败,因为同一个内容一定时间内被拦截时,可以使用下一个签名的短信模板;在自己的短信详情模板中,加了expression字段,用于发送短信时,从一个大的Dto对象中,取出这条短信模板想要的特定字段,传递给七陌,拼接成想要的短信,这样一来,想要调用此接口发送短信,只要传入电话号码,模板编号,确定的参数即可在这个接口内部拼接完成.

/**
     * 七陌-发送短信
     * 
     * @param qimoProperty 七陌接口-关键参数
     * @param requestDto 请求信息
     * @return 七陌返回结果
     */
    public static Result<QimoSendMessageResponseDto> sendMessage(QimoProperty qimoProperty, SendMessageDto requestDto) {
        Result<QimoSendMessageResponseDto> result = new Result<>();
        QimoSendMessageResponseDto responseDto = new QimoSendMessageResponseDto();
        // 七陌的短信模板编号
        String[] numsArray = requestDto.getMessageNums().split(QimoConstants.STRING_SPLIT_1);
        for (String num : numsArray) {
            // 请求参数
            JSONObject parameter = new JSONObject();
            parameter.put("num", requestDto.getPhoneNumber()); // 发送短信电话号码
            parameter.put("templateNum", num); // 七陌的短信模板编号

            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(requestDto));

            // 请求参数拼接表达式
            String expression = requestDto.getExpression();
            // 处理表达式 替换其中变量
            Result<String> dealResult = QimoCheckUtils.dealExpressionItem(expression, jsonObject);
            if (dealResult.isSuccess()) {
                expression = dealResult.getValue();
            } else {
                return TransformValue.copyErrorInfo(dealResult, result);
            }

            String[] expressionArray = expression.split(QimoConstants.STRING_SPLIT_1);
            for (int i = 0; i < expressionArray.length; i++) {
                parameter.put(String.format(QimoConstants.STRING_FORMAT_2, QimoConstants.VAR, i + 1),
                        expressionArray[i]);
            }

            // 校验qimoProperty
            QimoCheckUtils.checkProperty(qimoProperty);

            String accountId = qimoProperty.getAccountId();
            String apiSecret = qimoProperty.getApiSecret();
            String currentTime = getCurrentTime();

            // 签名
            String sign = QimoMessageUtils.genSign(accountId, apiSecret, currentTime);
            // 包头授权信息
            String authorization = QimoMessageUtils.genAuthorization(accountId, currentTime);

            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.add("Authorization", authorization);
            String response = RestUtils.postJsonWithHeaders(restTemplate, httpHeaders, qimoProperty.getSendMessageUrl(),
                    JSON.toJSONString(parameter), accountId, sign);
            // 七陌-返回信息乱码处理
            response = EncodeUtils.genRightString(response, QimoConstants.ENCODE_METHOD_ISO_8859_1,
                    QimoConstants.ENCODE_METHOD_UTF_8);
            log.info("七陌返回的信息-response:{}", response);

            responseDto = JSONObject.parseObject(response, QimoSendMessageResponseDto.class);
            if (responseDto.getSuccess()) {
                result.setValue(responseDto).setSuccess(true);
                break;
            }
        }

        result = responseDto.getSuccess() ? result.setValue(responseDto).setSuccess(true)
                : TransformValue.setErrorInfo(result, responseDto.getFlag(), responseDto.getMessage());
        return result;
    }

package com.yifenqi.qimo.utils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSONObject;
import com.github.myoss.phoenix.core.lang.dto.Result;
import com.github.myoss.phoenix.core.lang.dto.TransformValue;
import com.yifenqi.bank.constants.CodeMsgEnum;
import com.yifenqi.common.DateUtils;
import com.yifenqi.common.StringDealUtils;
import com.yifenqi.qimo.common.QimoConstants;
import com.yifenqi.qimo.config.QimoProperty;

/**
 * 七陌校验工具类
 * 
 * @author zhangshiwei
 * @time 2018年8月16日下午4:30:04
 */
@SuppressWarnings("all")
public class QimoCheckUtils {

    /**
     * 校验 七陌接口-关键参数
     * 
     * @param property 参数
     * @return 未传入则报错
     */
    public static Result checkProperty(QimoProperty property) {
        Result result = new Result();
        if (null == property) {
            return TransformValue.setErrorInfo(result, CodeMsgEnum.VALUE_IS_BLANK.getCode(), "property为null!");
        }
        return result;
    }

    /**
     * 根据表达式去除请求参数对象中的特定值
     * 
     * @param expression 表达式
     * @param jsonObject 请求参数对象
     * @return 特定请求参数
     */
    public static Result<String> dealExpressionItem(String expression, JSONObject jsonObject) {
        Result<String> dealResult = new Result<>();
        // [@{userName},@{userName}]
        List<String> expressionItemList = StringDealUtils.subStrWithAffix(expression, QimoConstants.STRING_SPLIT_5,
                QimoConstants.STRING_SPLIT_6);
        if (!CollectionUtils.isEmpty(expressionItemList)) {
            for (int i = 0; i < expressionItemList.size(); i++) {
                String paramStr = expressionItemList.get(i); // @{userName}
                String paramStrNoEspecial = paramStr.replace(QimoConstants.STRING_SPLIT_5, StringUtils.EMPTY)
                        .replace(QimoConstants.STRING_SPLIT_6, StringUtils.EMPTY); // userName
                String param = jsonObject.getString(paramStrNoEspecial); // 请求参数

                // 此参数是时间Date格式的时间戳 需要转换处理 curDt billDt
                if (paramStrNoEspecial.contains(QimoConstants.DT)) {
                    param = genDateString(param);
                }

                if (StringUtils.isBlank(param)) {
                    return TransformValue.setErrorInfo(dealResult, paramStrNoEspecial, "请求参数不能为空");
                } else {
                    expression = expression.replace(paramStr, param);
                }
            }
        }
        return dealResult.setValue(expression);
    }

    /**
     * 获取符合格式的时间
     * 
     * @param timeStamp 时间
     * @return 目的格式的时间 yyyy年MM月dd日
     */
    public static String genDateString(String timeStamp) {
        Date date = DateUtils.parseTimestampToDate(Long.parseLong(timeStamp));
        String currentDateTime = new SimpleDateFormat(QimoConstants.MESSAGE_TIME_FORMAT).format(date);
        return currentDateTime;
    }

}
 

注意:

    七陌短信接口的对接,要求头文件组装Authorization加入授权参数,进行base64编码,具体参考七陌文档;

    还需要签名sign参数,使用特定的参数进行MD5加密,具体参考七陌文档;

    然后使用post方式访问;

    最后,七陌返回的数据,你接收到的可能乱码!因为他们返回的数据,编码方式是ISO-8859-1;

可以使用一个方法获取当前字符串的编码方式,然后进行反编码:

package com.yifenqi.common;

import java.io.UnsupportedEncodingException;

import lombok.extern.slf4j.Slf4j;

/**
 * 处理乱码字符串
 * 
 * @author zhangshiwei
 * @time 2018年8月20日下午3:28:15
 */
@Slf4j
public class EncodeUtils {

    /**
     * 将乱码的字符串按照指定格式重新编码
     * 
     * @param str 乱码的字符串
     * @param encodeMethodList 指定的编码方式
     * @return 不乱码中文字符串
     */
    public static String genRightString(String str, String encodeMethod) {
        String currentMethod = getEncodMethod(str);
        log.info("此字符串的编码方式为:{}", currentMethod);
        try {
            return new String(str.getBytes(currentMethod), encodeMethod);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取字符串的编码方式:GB2312 , ISO-8859-1 ,UTF-8 , GBK , UTF-16 , UTF-16BE ,
     * UTF-16LE
     * 
     * @param str 待检查字符串
     * @return 编码方式
     */
    public static String getEncodMethod(String str) {
        String encode = "GB2312";
        encode = "ISO-8859-1";
        try {
            if (str.equals(new String(str.getBytes(encode), encode))) {
                return encode;
            }
        } catch (Exception exception1) {
        }
        encode = "UTF-8";
        try {
            if (str.equals(new String(str.getBytes(encode), encode))) {
                String s2 = encode;
                return s2;
            }
        } catch (Exception exception2) {
        }
        encode = "GBK";
        try {
            if (str.equals(new String(str.getBytes(encode), encode))) {
                String s3 = encode;
                return s3;
            }
        } catch (Exception exception3) {
        }
        encode = "UTF-16";
        try {
            if (str.equals(new String(str.getBytes(encode), encode))) {
                String s3 = encode;
                return s3;
            }
        } catch (Exception exception3) {
        }
        encode = "UTF-16BE";
        try {
            if (str.equals(new String(str.getBytes(encode), encode))) {
                String s3 = encode;
                return s3;
            }
        } catch (Exception exception3) {
        }
        encode = "UTF-16LE";
        try {
            if (str.equals(new String(str.getBytes(encode), encode))) {
                String s3 = encode;
                return s3;
            }
        } catch (Exception exception3) {
        }
        return "";
    }

    /**
     * @param str 乱码字符串
     * @param errorMethod 错误的编码方式
     * @param rightMethod 想要的编码方式
     * @return 正确的中文字符串
     */
    public static String genRightString(String str, String errorMethod, String rightMethod) {
        try {
            return new String(str.getBytes(errorMethod), rightMethod);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

}
 

解决乱码问题;

猜你喜欢

转载自blog.csdn.net/weixin_41564440/article/details/82117444