第三方接口调用案例(以阿里云短信服务为例)

第三方接口或者服务大部分都是以rest风格的,需要http请求去调用,通过网络发送请求去调用,然后等待第三方服务的响应,并发量多的话,会严重拖慢业务逻辑的处理速度。为了提高系统的性能,调用第三方服务,最好做成异步的,如果条件允许,最好用单独的服务器,或者几台服务器来做调用第三方接口,来提高业务逻辑的处理速度。当然,测试环境也可以用一台机器来做伪分布式。

实现方式:将业务逻辑与调用第三方服务的代码分离,来达到解耦,以及异步调用,具体实现(以调用阿里云短信服务为例):

1、编写配置类

public class ApiConfig implements Serializable {
    private static final long serialVersionUID = -3043278191484112872L;
    /**
     * 产品名称
     */
    protected String product;
    /**
     * 接口域名或者IP地址
     */
    protected String domain;
    /**
     * appCode;
     */
    protected String accessKeyId;

    /**
     * appSecret
     */
    protected String accessKeySecret;

    /**
     * 链接超时时间
     */
    private String defaultConnectTimeout;
    /**
     * 读取返回参数的超时时间
     */
    private String defaultReadTimeout;
    /**
     * 短信模板代码
     */
    private String templateCode;
    /**
     * 签名
     */
    private String signName;
    /**
     * 请求参数
     */
    private String templateParam;

省略get,set方法

}

2、将调用阿里云服务的demo封装成接口:

     public interface ShortMessageSendService<T extends ApiConfig> {
    /**
     * 发送短信
     * @param config 配置类(appkey等配置信息)
     * @param phoneNumbers  要发送的手机号
     * @param templateParam  短信的模板以及短信的内容
     * @throws ClientException 
     */    
    public void sendMsessages (T config, String phoneNumber, String templateParam,Emp user) throws ClientException;
       /**
     * 获取信息发送结果
     * @param config  配置类(appkey等配置信息)
     * @param ShortMessage 发送的短信的内容,以及是否发送成功
     * @throws ClientException
     * @throws ParseException 
     */
    public void getMessageInfo (T config, ShortMessage message) throws ClientException, ParseException;
}

2、根据业务逻辑,把不同类型的短信进行分类,并编写配置文件,方便spring自动注入。

扫描二维码关注公众号,回复: 4119603 查看本文章

mes.product = Dysmsapi
mes.domain = dysmsapi.aliyuncs.com
mes.accessKeyId = 
mes.accessKeySecret = 
mes.queueName =
mes.defaultConnectTimeout = 10000
mes.defaultReadTimeout = 10000

  spring 配置父类:

    <bean id="messageConfig" class="com.zedev.config.ApiConfig">
        <property name="product" value="${mes.product}"></property>
        <property name="domain" value="${mes.domain}"></property>
        <property name="accessKeyId" value="${mes.accessKeyId}"></property>
        <property name="accessKeySecret"
            value="${mes.accessKeySecret}"></property>
        <property name="defaultConnectTimeout"
            value="${mes.defaultConnectTimeout}"></property>
        <property name="defaultReadTimeout"
            value="${mes.defaultReadTimeout}"></property>
        <property name="queueName" value="${mes.queueName}"></property>
    </bean>

  spring 配置子类1:短信模板和签名不一样
    <bean id="XXConfig"
        class="com.zedev.config.XXConfig" parent="messageConfig">
        <property name="templateCode" value="${vio.mes.templateCode}"></property> 
        <property name="signName" value="${vio.mes.signName}"></property>

    </bean>

spring 配置子类2:短信模板和签名不一样

    <bean id="XXXConfig"
        class="com.zedev.config.XXXConfig" parent="messageConfig">
        <property name="templateCode"
            value="${code.mes.templateCode}"></property>
        <property name="signName" value="${code.mes.signName}"></property>
    </bean>

3、结合消息队列,将调用短信接口和业务逻辑进行解耦。

将短信息发送给消息队列:(消息队列的配置jmsQueueTemplate已省略,源码: https://github.com/jialestudio/lib

@Component
public class MessageSender {
    @Autowired
    @Qualifier("jmsQueueTemplate")
    private JmsTemplate jmsTemplate;
    /**
     * @Description: 将消息发送给消息队列
     * @param destination 消息队列名称
     * @param message  消息体
     */
     public void send(String destination, final String message) {
         jmsTemplate.send(destination, new MessageCreator() {
                @Override
                public Message createMessage(Session session) throws JMSException {
                    return jmsTemplate.getMessageConverter().toMessage(message, session);
                }
            });
        }
}

消息队列监听器:

@Component
@EnableJms
public class MesSenderQueueListener {
    protected Logger log = LoggerFactory.getLogger(ViolationQueryQueueListener.class);
     // 当收到消息后,自动调用该方法,spring配置默认监听器,负责接收消息 concurrency = "3-8"最少三个线程,最多8个线程监听,启用多线程,提高系统效率
    @JmsListener(containerFactory = "jmsListenerContainerFactory", destination = "消息队列名", concurrency = "3-8")
    public void onMessage(Message message) throws JMSException {
        ActiveMQTextMessage msg = (ActiveMQTextMessage) message;
        final String ms = msg.getText();
        try {

            if (StringUtils.isBlank(ms)) {
                return;
            }
            Emp user = null;
            user = userService.getSystemUser();
            /**
             * 业务逻辑处理,调用2发送请求,并获取信息发送的结果,并存入数据库
             */
            XXConfig= null;
            param = JSONObject.parseObject(ms, XXConfig.class);// 转换成相应的对象
            if (null == param) {
                return;
            }

            //这里调用调用短信发送的接口,生成记录短信的对象ShortMessage ,并存入数据库中。
        } catch (Exception e) {
            log.info(ms);
            e.printStackTrace();
        }
    }
}

阿里云短信回执消息队列监听器

@Component
public class ShortMessageQueueListener {
    @Autowired
    private VioMessageConfig cioConfig;
    @Autowired
    private ShortMessageService mesService;
    private Logger log = LoggerFactory.getLogger(ShortMessageQueueListener.class);

    @PostConstruct
    public void listenMessage() throws ClientException, ParseException {
        DefaultAlicomMessagePuller puller = new DefaultAlicomMessagePuller();
        puller.startReceiveMsg(cioConfig.getAccessKeyId(), cioConfig.getAccessKeySecret(), "SmsReport",
                cioConfig.getQueueName(), new MyMessageListener());
    }
    class MyMessageListener implements MessageListener {
        @Override
        public boolean dealMessage(Message message) {
            JSONObject result = null;
            result = JSONObject.parseObject(message.getMessageBodyAsString());
            if (null == result) {
                return true;
            }
           //业务逻辑,更新MesSenderQueueListener生成的发送结果,并处理相关的业务逻辑
        }
    }

}

以上可以整合到一个系统,也可以整合成分布式架构,不需要spring cloud或者dubbo等分布式的开源框架。

猜你喜欢

转载自blog.csdn.net/qq_20845121/article/details/84183929