JAVA實現多線程處理批量發送短信、APP推送


/**
	 * 推送消息 APP、短信
	 * @param message
	 * @throws Exception
	 */
	public void sendMsg(Message message) throws Exception{
		try {
			logger.info("send message start...");
			long startTime = System.currentTimeMillis();
			BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(20000);
			ThreadPoolExecutor executors = new ThreadPoolExecutor(5, 6, 60000, TimeUnit.SECONDS, queue);
			
			//要推送的用戶總數
			int count = filterPhonesCount(message);
			logger.info("message all count=>{}",count);
			//初始每個線程處理的用戶數量
			final int eveLength = 2000;
			//計算處理所有用戶需要的線程數量
			int eveBlocks = count / eveLength + (count % eveLength != 0 ? 1 : 0);
			logger.info("need thread's count=>{}",eveBlocks);
			//線程計數器
			CountDownLatch doneSignal = new CountDownLatch(eveBlocks);
			
			//開啟線程處理
			int doneCount = 0;
			for (int page = 0; page < eveBlocks; page++) { /* blocks太大可以再細分重新調度 */
				MessageSendThread ms = new MessageSendThread(messageDao,message,page + 1,eveLength,doneSignal);
				executors.execute(ms);
				//logger.info("start thread =>{}",page+1);
				doneCount++;
			}
			doneSignal.await();//等待所有計數器線程執行完
			long endTime = System.currentTimeMillis();
			logger.info("send message all thread ends!time(s)=>{}",(startTime-endTime)/1000);
			logger.info("all thread count=>{}",doneCount);
		} catch (Exception e) {
			logger.error("send message error=>{}",e);
		}
	}

  

package com.bankhui.center.business.service.message;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.impl.cookie.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.bankhui.center.business.dao.message.MessageDao;
import com.bankhui.center.business.entity.message.Message;
import com.bankhui.center.common.utils.DateUtil;
import com.bankhui.center.common.utils.SmsUtils;
import com.bankhui.center.jpush.JPushClient;
import com.bankhui.center.jpush.JPushScheduleClient;

/**
 * 系統消息推送線程(處理 block數據塊)
 */
public class MessageSendThread implements Runnable{
	
	private final Logger logger = LoggerFactory.getLogger(MessageSendThread.class);

	private Integer currentIndex;//當前索引
	private Integer rows;//處理數據條數
	private CountDownLatch doneSignal;//處理線程條數
	private Message message;//消息實體
	private MessageDao messageDao;//DAO

	public MessageSendThread(MessageDao messageDao,Message message,Integer currentIndex,Integer rows, CountDownLatch doneSignal) {
		this.message = message;
		this.messageDao = messageDao;
		this.currentIndex = currentIndex;
		this.rows = rows;
		this.doneSignal = doneSignal;
	}
	
	
	@Override
	public void run() {
		try {
			/**
			 * ---------1.查詢當前的block范圍內的發送的手機號=>篩選目標客戶群手機號---------
			 */
			Map<String,Object> smsDataMap = filterPhones(message,currentIndex,rows);
			if(MapUtils.isEmpty(smsDataMap)|| null == smsDataMap.get("jgAlias") 
					||StringUtils.isBlank(smsDataMap.get("jgAlias").toString())){
				logger.debug("push param is null,caurse by target customers is nothing");
				throw new RuntimeException();
			}
			logger.info("type of target customers=>{}", message.getReceiverGroupType());
			logger.info(" result of filter target customers=>{}", smsDataMap);
			 
			/**
			 *  ---------2.批量發送消息---------
			 *  TODO://((-?)\d{1,11}\,?){1,n}  n個線程分批發送
			 */
			if("0".equals(message.getType())){//短信發送
				sendBatch(smsDataMap.get("phone").toString(),message);
			}
			if("1".equals(message.getType())){//APP推送
				if("0".equals(message.getMethod())){//實時發送
					sendNormal(smsDataMap);
				}
				if("1".equals(message.getMethod())){//定時發送
					sendDelay(smsDataMap);
				}
			 }
		} catch (Exception e) {
			logger.error("send message thread exception=>{}{}{}{}",message,currentIndex,rows,e);
		}finally{
			doneSignal.countDown();//工人完成工作,計數器減一
		}
	}
	
	/**
	 * APP實時推送
	 * @param smsDataMap
	 */
	private void sendNormal(Map<String,Object> smsDataMap) {
		 //0為全部發送
		if("0".equals(message.getReceiverGroupType())){
			JPushClient.appSendAll(message.getTitle(), message.getContent(), message.getId().toString(), StringUtils.isBlank(message.getLink())?"0":"1", message.getLink());
		}else{
			String[] jgAlias = smsDataMap.get("jgAlias").toString().split(",");
			for(String jgAlia:jgAlias){
				JPushClient.appSend(message.getTitle(), message.getContent(), jgAlia, message.getId().toString(), StringUtils.isBlank(message.getLink())?"0":"1", message.getLink());
			}
		}
	}

    /**
     * APP定時推送
     * @param smsDataMap
     */
	private void sendDelay(Map<String,Object> smsDataMap) {
		 //0為全部發送
		if("0".equals(message.getReceiverGroupType())){
			JPushScheduleClient.createSingleSchedule(
					DateUtil.formatDateToStr("yyyy-MM-dd HH:mm:ss", message.getExpectTime()), 
					message.getTitle(), 
					message.getContent(),  
					message.getId().toString(), 
					StringUtils.isBlank(message.getLink())?"0":"1", 
					message.getLink());
		}else{
			String[] jgAlias = smsDataMap.get("jgAlias").toString().split(",");
			JPushScheduleClient.createSingleSchedule(
					Arrays.asList(jgAlias),
					DateUtil.formatDateToStr("yyyy-MM-dd HH:mm:ss", message.getExpectTime()), 
					message.getTitle(), 
					message.getContent(),  
					message.getId().toString(), 
					StringUtils.isBlank(message.getLink())?"0":"1", 
					message.getLink());
		}
	}


	
	
	/**
	 * 批量發送消息
	 * @param smsDataList
	 * @param message
	 */
	private void sendBatch(String smsDataListStr,Message message){
		try {
			//批量發送方法使用異步發送
			if(!message.getContent().contains("退訂回T")){
				message.setContent(message.getContent()+"退訂回T");
			}
			SmsUtils.batchExecuteTask(smsDataListStr, message.getContent());
			//短信測試方法
			//SmsUtils.batchExecuteTask(smsDataListStr, message.getContent(),true);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("批量發送消息異常=>{}{}",smsDataListStr,e);
		}
	}
	

}
 1 /**
 2      * 批量發送消息
 3      * @param smsDataList
 4      * @param message
 5      */
 6     private void sendBatch(String smsDataListStr,Message message){
 7         try {
 8             //批量發送方法使用異步發送
 9             if(!message.getContent().contains("退訂回T")){
10                 message.setContent(message.getContent()+"退訂回T");
11             }
12             SmsUtils.batchExecuteTask(smsDataListStr, message.getContent());
13             //短信測試方法
14             //SmsUtils.batchExecuteTask(smsDataListStr, message.getContent(),true);
15         } catch (Exception e) {
16             e.printStackTrace();
17             logger.error("批量發送消息異常=>{}{}",smsDataListStr,e);
18         }
19     }
 1 public static String sendSmsCL(String mobile, String content,String urlStr,String un, String pw, String rd) {
 2            // 創建StringBuffer對象用來操作字符串
 3             StringBuffer sb = new StringBuffer(urlStr+"?");
 4             // 用戶賬號
 5             sb.append("un="+un);
 6 
 7             //用戶密碼
 8             sb.append("&pw="+pw);
 9 
10             // 是否需要狀態報告,0表示不需要,1表示需要
11             sb.append("&rd="+rd);
12 
13             // 向StringBuffer追加手機號碼
14             sb.append("&phone="+mobile);
15 
16             // 返回發送結果
17             String inputline;
18             BufferedReader in = null;
19             InputStreamReader isr = null;
20             try {
21                 // 向StringBuffer追加消息內容轉URL標准碼
22                 sb.append("&msg="+URLEncoder.encode(content,"UTF8"));
23                 // 創建url對象
24                 URL url = new URL(sb.toString());
25 
26                 // 打開url連接
27                 HttpURLConnection connection = (HttpURLConnection) url.openConnection();
28 
29                 // 設置url請求方式 ‘get’ 或者 ‘post’
30                 connection.setRequestMethod("POST");
31                 isr = new InputStreamReader(url.openStream());
32                 // 發送
33                 in = new BufferedReader(isr);
34                 inputline = in.readLine();
35                 if(inputline.contains(",0")){
36                     logger.info("手機號:【{}】發送短信成功", mobile);
37                 }else{
38                     logger.info("手機號:【{}】發送短信失敗,errorMsg is:{}", mobile,inputline);
39                 }
40                 // 輸出結果
41                 return inputline;
42             } catch (Exception e) {
43                 logger.error("發送短信請求異常:{}", e.getMessage());
44                 return e.getMessage();
45             } finally{
46                 if(null != isr){
47                     try {
48                         isr.close();
49                     } catch (IOException e) {
50                         logger.error("關閉流異常:{}", e.getMessage());
51                     }
52                 }
53                 if(null != in){
54                     try {
55                         in.close();
56                     } catch (IOException e) {
57                         logger.error("關閉流異常:{}", e.getMessage());
58                     }
59                 }
60             }
61 
62     }
package com.bankhui.center.jpush;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The entrance of JPush API library.
 *
 */
public class JPushClient extends BaseClient {
    private static Logger logger = LoggerFactory.getLogger(JPushClient.class);
    //在極光注冊上傳應用的 appKey 和 masterSecret
    private static final String appKeyStr ="******************";////必填,
    
    private static final String masterSecretStr = "******************";//必填,每個應用都對應一個masterSecret
    
    private static JPushClient jpush = null;

    /*
     * 保存離線的時長。秒為單位。最多支持10天(864000秒)。
     * 0 表示該消息不保存離線。即:用戶在線馬上發出,當前不在線用戶將不會收到此消息。
     * 此參數不設置則表示默認,默認為保存1天的離線消息(86400秒
     */
    private static long timeToLive =  60 * 60 * 24;  
    
    protected static HttpPostClient httpClient = new HttpPostClient();

    /**
     * 給指定用戶推送消息
     * @param msgTitle    標題
     * @param msgContent    內容
     * @param jgAlias    極光通訊id
     * @param sysMsgId    系統保存的消息id
     * @param type    跳轉類型0不帶鏈接跳轉,1帶鏈接跳轉 2 站內信
     * @param url 跳轉url
     * @author wxz
     * @date 2017年2月27日
     */
    public static void appSend(String msgTitle,String msgContent,String jgAlias,String sysMsgId,String type,String url) {
        try {
            Map<String, Object> extra1 =new HashMap<String, Object>();
            extra1.put("sysMsgId", sysMsgId);
            extra1.put("type", type);//0不帶鏈接跳轉,1帶鏈接跳轉
            extra1.put("url", url);
            if(null == jpush){
                jpush = new JPushClient(masterSecretStr, appKeyStr, timeToLive);
            }
            MessageResult msgResult = jpush.sendNotificationWithAlias(getRandomSendNo(), jgAlias, msgTitle, msgContent, 0,  extra1);

            if (null != msgResult) {
                logger.info("服務器返回數據: " + msgResult.toString());
                if (msgResult.getErrcode() == ErrorCodeEnum.NOERROR.value()) {
                    logger.info("發送成功, sendNo=" + msgResult.getSendno());
                } else {
                    logger.error("發送失敗, 錯誤代碼=" + msgResult.getErrcode() + ", 錯誤消息=" + msgResult.getErrmsg());
                }
            } else {
                logger.error("無法獲取數據");
            }
        } catch (Exception e) {
            logger.error("發送失敗,error msg is :"+e);
        }
    }
    /**
     * 給所有用戶推送消息
     * @param msgTitle 標題 
     * @param msgContent    內容
     * @param sysMsgId 消息id
     * @param type 跳轉類型0不帶鏈接跳轉,1帶鏈接跳轉
     * @param url 跳轉url
     * @author wxz
     * @date 2017年2月27日
     */
    public static void appSendAll(String msgTitle,String msgContent,String sysMsgId,String type,String url) {
        /*
         * IOS設備擴展參數,
         * 設置badge,設置聲音
         */

        Map<String, Object> extra1 =new HashMap<String, Object>();
        extra1.put("sysMsgId", sysMsgId);
        extra1.put("type", type);//0不帶鏈接跳轉,1帶鏈接跳轉
        extra1.put("url", url);
        if(null == jpush){
            jpush = new JPushClient(masterSecretStr, appKeyStr, timeToLive);
        }
        MessageResult msgResult = jpush.sendNotificationWithAppKey(getRandomSendNo(), msgTitle, msgContent, 0, extra1);
        
        if (null != msgResult) {
            logger.info("服務器返回數據: " + msgResult.toString());
            if (msgResult.getErrcode() == ErrorCodeEnum.NOERROR.value()) {
                logger.info("發送成功, sendNo=" + msgResult.getSendno());
            } else {
                logger.error("發送失敗, 錯誤代碼=" + msgResult.getErrcode() + ", 錯誤消息=" + msgResult.getErrmsg());
            }
        } else {
            logger.error("無法獲取數據");
        }
        
        
    }
    
    public JPushClient(String masterSecret, String appKey) {
        this.masterSecret = masterSecret;
        this.appKey = appKey;
    }
    
    public JPushClient(String masterSecret, String appKey, long timeToLive) {
        this.masterSecret = masterSecret;
        this.appKey = appKey;
        this.timeToLive = timeToLive;
    }

    public JPushClient(String masterSecret, String appKey, DeviceEnum device) {
        this.masterSecret = masterSecret;
        this.appKey = appKey;
        devices.add(device);
    }

    public JPushClient(String masterSecret, String appKey, long timeToLive, DeviceEnum device) {
        this.masterSecret = masterSecret;
        this.appKey = appKey;
        this.timeToLive = timeToLive;
        devices.add(device);
    }

    /*
     * @description 發送帶IMEI的通知
     * @return MessageResult
     */
    public MessageResult sendNotificationWithImei(String sendNo, String imei, String msgTitle, String msgContent) {
        NotifyMessageParams p = new NotifyMessageParams();
        p.setReceiverType(ReceiverTypeEnum.IMEI);
        p.setReceiverValue(imei);
        return sendNotification(p, sendNo, msgTitle, msgContent, 0, null);
    }

    /*
     * @params builderId通知欄樣式
     * @description 發送帶IMEI的通知
     * @return MessageResult
     */
    public MessageResult sendNotificationWithImei(String sendNo, String imei, String msgTitle, String msgContent, int builderId, Map<String, Object> extra) {
        NotifyMessageParams p = new NotifyMessageParams();
        p.setReceiverType(ReceiverTypeEnum.IMEI);
        p.setReceiverValue(imei);
        return sendNotification(p, sendNo, msgTitle, msgContent, builderId, extra);
    }

    /*
     * @description 發送帶IMEI的自定義消息
     * @return MessageResult
     */
    public MessageResult sendCustomMessageWithImei(String sendNo, String imei, String msgTitle, String msgContent) {
        CustomMessageParams p = new CustomMessageParams();
        p.setReceiverType(ReceiverTypeEnum.IMEI);
        p.setReceiverValue(imei);
        return sendCustomMessage(p, sendNo, msgTitle, msgContent, null, null);
    }

    /*
     * @params msgContentType消息的類型,extra附屬JSON信息
     * @description 發送帶IMEI的自定義消息
     * @return MessageResult
     */
    public MessageResult sendCustomMessageWithImei(String sendNo, String imei, String msgTitle, String msgContent, String msgContentType, Map<String, Object> extra) {
        CustomMessageParams p = new CustomMessageParams();
        p.setReceiverType(ReceiverTypeEnum.IMEI);
        p.setReceiverValue(imei);
        return sendCustomMessage(p, sendNo, msgTitle, msgContent, msgContentType, extra);
    }

    /*
     * @description 發送帶TAG的通知
     * @return MessageResult
     */
    public MessageResult sendNotificationWithTag(String sendNo, String tag, String msgTitle, String msgContent) {
        NotifyMessageParams p = new NotifyMessageParams();
        p.setReceiverType(ReceiverTypeEnum.TAG);
        p.setReceiverValue(tag);
        return sendNotification(p, sendNo, msgTitle, msgContent, 0, null);
    }

    /*
     * @params builderId通知欄樣式
     * @description 發送帶TAG的通知
     * @return MessageResult
     */
    public MessageResult sendNotificationWithTag(String sendNo, String tag, String msgTitle, String msgContent, int builderId, Map<String, Object> extra) {
        NotifyMessageParams p = new NotifyMessageParams();
        p.setReceiverType(ReceiverTypeEnum.TAG);
        p.setReceiverValue(tag);
        return sendNotification(p, sendNo, msgTitle, msgContent, builderId, extra);
    }

    /*
     * @description 發送帶TAG的自定義消息
     * @return MessageResult
     */
    public MessageResult sendCustomMessageWithTag(String sendNo, String tag, String msgTitle, String msgContent) {
        CustomMessageParams p = new CustomMessageParams();
        p.setReceiverType(ReceiverTypeEnum.TAG);
        p.setReceiverValue(tag);
        return sendCustomMessage(p, sendNo, msgTitle, msgContent, null, null);
    }

    /*
     * @params msgContentType消息的類型,extra附屬JSON信息
     * @description 發送帶TAG的自定義消息
     * @return MessageResult
     */
    public MessageResult sendCustomMessageWithTag(String sendNo, String tag, String msgTitle, String msgContent, String msgContentType, Map<String, Object> extra) {
        CustomMessageParams p = new CustomMessageParams();
        p.setReceiverType(ReceiverTypeEnum.TAG);
        p.setReceiverValue(tag);
        return sendCustomMessage(p, sendNo, msgTitle, msgContent, msgContentType, extra);
    }

    /*
     * @description 發送帶ALIAS的通知
     * @return MessageResult
     */
    public MessageResult sendNotificationWithAlias(String sendNo, String alias, String msgTitle, String msgContent) {
        NotifyMessageParams p = new NotifyMessageParams();
        p.setReceiverType(ReceiverTypeEnum.ALIAS);
        p.setReceiverValue(alias);
        return sendNotification(p, sendNo, msgTitle, msgContent, 0, null);
    }

    /*
     * @params builderId通知欄樣式
     * @description 發送帶ALIAS的通知
     * @return MessageResult
     */
    public MessageResult sendNotificationWithAlias(String sendNo, String alias, String msgTitle, String msgContent, int builderId, Map<String, Object> extra) {
        NotifyMessageParams p = new NotifyMessageParams();
        p.setReceiverType(ReceiverTypeEnum.ALIAS);
        p.setReceiverValue(alias);
        return sendNotification(p, sendNo, msgTitle, msgContent, builderId, extra);
    }

    /*
     * @description 發送帶ALIAS的自定義消息
     * @return MessageResult
     */
    public MessageResult sendCustomMessageWithAlias(String sendNo, String alias, String msgTitle, String msgContent) {
        CustomMessageParams p = new CustomMessageParams();
        p.setReceiverType(ReceiverTypeEnum.ALIAS);
        p.setReceiverValue(alias);
        return sendCustomMessage(p, sendNo, msgTitle, msgContent, null, null);
    }

    /*
     * @params msgContentType消息的類型,extra附屬JSON信息
     * @description 發送帶ALIAS的自定義消息
     * @return MessageResult
     */
    public MessageResult sendCustomMessageWithAlias(String sendNo, String alias, String msgTitle, String msgContent, String msgContentType, Map<String, Object> extra) {
        CustomMessageParams p = new CustomMessageParams();
        p.setReceiverType(ReceiverTypeEnum.ALIAS);
        p.setReceiverValue(alias);
        return sendCustomMessage(p, sendNo, msgTitle, msgContent, msgContentType, extra);
    }

    /*
     * @description 發送帶AppKey的通知
     * @return MessageResult
     */
    public MessageResult sendNotificationWithAppKey(String sendNo, String msgTitle, String msgContent) {
        NotifyMessageParams p = new NotifyMessageParams();
        p.setReceiverType(ReceiverTypeEnum.APPKEYS);
        return sendNotification(p, sendNo, msgTitle, msgContent, 0, null);
    }

    /*
     * @params builderId通知欄樣式
     * @description 發送帶AppKey的通知
     * @return MessageResult
     */
    public MessageResult sendNotificationWithAppKey(String sendNo, String msgTitle, String msgContent, int builderId, Map<String, Object> extra) {
        NotifyMessageParams p = new NotifyMessageParams();
        p.setReceiverType(ReceiverTypeEnum.APPKEYS);
        return sendNotification(p, sendNo, msgTitle, msgContent, builderId, extra);
    }

    /*
     * @description 發送帶AppKey的自定義消息
     * @return MessageResult
     */
    public MessageResult sendCustomMessageWithAppKey(String sendNo, String msgTitle, String msgContent) {
        CustomMessageParams p = new CustomMessageParams();
        p.setReceiverType(ReceiverTypeEnum.APPKEYS);
        return sendCustomMessage(p, sendNo, msgTitle, msgContent, null, null);
    }

    /*
     * @params msgContentType消息的類型,extra附屬JSON信息
     * @description 發送帶AppKey的自定義消息
     * @return MessageResult
     */
    public MessageResult sendCustomMessageWithAppKey(String sendNo, String msgTitle, String msgContent, String msgContentType, Map<String, Object> extra) {
        CustomMessageParams p = new CustomMessageParams();
        p.setReceiverType(ReceiverTypeEnum.APPKEYS);
        return sendCustomMessage(p, sendNo, msgTitle, msgContent, msgContentType, extra);
    }

    protected MessageResult sendCustomMessage(CustomMessageParams p, String sendNo, String msgTitle, String msgContent, String msgContentType, Map<String, Object> extra) {
        if (null != msgContentType) {
            p.getMsgContent().setContentType(msgContentType);
        }
        if (null != extra) {
            p.getMsgContent().setExtra(extra);
        }
        return sendMessage(p, sendNo, msgTitle, msgContent);
    }

    protected MessageResult sendNotification(NotifyMessageParams p, String sendNo, String msgTitle, String msgContent, int builderId, Map<String, Object> extra) {
        p.getMsgContent().setBuilderId(builderId);
        if (null != extra) {
            p.getMsgContent().setExtra(extra);
        }
        return sendMessage(p, sendNo, msgTitle, msgContent);
    }

    protected MessageResult sendMessage(MessageParams p,String sendNo, String msgTitle, String msgContent) {
        p.setSendNo(sendNo);
        p.setAppKey(this.getAppKey());
        p.setMasterSecret(this.masterSecret);
        p.setTimeToLive(this.timeToLive);
        p.setSendDescription(this.getSendDescription());
        for (DeviceEnum device : this.getDevices()) {
            p.addPlatform(device);
        }

        if (null != msgTitle) {
            p.getMsgContent().setTitle(msgTitle);
        }
        p.getMsgContent().setMessage(msgContent);

        return sendMessage(p);
    }

    protected MessageResult sendMessage(MessageParams params) {
        return httpClient.post(BaseURL.ALL_PATH, this.enableSSL, params);
    }

    
    public static final int MAX = Integer.MAX_VALUE;  
    public static final int MIN = (int) MAX/2;  
  
    /** 
     * 保持 sendNo 的唯一性是有必要的 
     * It is very important to keep sendNo unique. 
     * @return sendNo 
     */  
    public static String getRandomSendNo() {  
        return String.valueOf((int) (MIN + Math.random() * (MAX - MIN)));  
    }  
}
  1 package com.bankhui.center.jpush;
  2 
  3 import java.util.ArrayList;
  4 import java.util.HashMap;
  5 import java.util.List;
  6 import java.util.Map;
  7 
  8 import org.apache.shiro.util.CollectionUtils;
  9 import org.slf4j.Logger;
 10 import org.slf4j.LoggerFactory;
 11 
 12 import cn.jpush.api.JPushClient;
 13 import cn.jpush.api.common.TimeUnit;
 14 import cn.jpush.api.common.Week;
 15 import cn.jpush.api.common.resp.APIConnectionException;
 16 import cn.jpush.api.common.resp.APIRequestException;
 17 import cn.jpush.api.push.model.Platform;
 18 import cn.jpush.api.push.model.PushPayload;
 19 import cn.jpush.api.push.model.audience.Audience;
 20 import cn.jpush.api.schedule.ScheduleListResult;
 21 import cn.jpush.api.schedule.ScheduleResult;
 22 import cn.jpush.api.schedule.model.SchedulePayload;
 23 import cn.jpush.api.schedule.model.TriggerPayload;
 24 
 25 public class JPushScheduleClient {
 26 
 27     protected static final Logger LOG = LoggerFactory.getLogger(JPushScheduleClient.class);
 28 
 29     private static final String appKey ="*********";
 30     private static final String masterSecret = "*******";
 31     /*
 32      * 保存離線的時長。秒為單位。最多支持10天(864000秒)。
 33      * 0 表示該消息不保存離線。即:用戶在線馬上發出,當前不在線用戶將不會收到此消息。
 34      * 此參數不設置則表示默認,默認為保存1天的離線消息(86400秒
 35      */
 36     private static int timeToLive =  60 * 60 * 24;
 37 
 38     public static void main(String[] args) {
 39         List<String> list = new ArrayList<String>();
 40         list.add("22");
 41 //        testGetScheduleList();
 42 //        testUpdateSchedule();
 43         String scheduleId = "***************";
 44         String time = "2017-03-07 09:55:00";
 45         String msgTitle = "push schedule jpush,TEST\"\"";
 46         String msgContent = "測試定時發送";
 47         String sysMsgId = "26";
 48         String type = "1";
 49         String url = "https://www.baidu.com";
 50         //指定接收者的定時發送
 51         scheduleId = createSingleSchedule(list,time,msgTitle,msgContent,sysMsgId,type,url);
 52         //全部用戶的定時發送
 53 //        scheduleId = createSingleSchedule(time,msgTitle,msgContent,sysMsgId,type,url);
 54         testGetSchedule(scheduleId);
 55 //        testDeleteSchedule(scheduleId);
 56     }
 57     /**
 58      * 添加指定接收者定時發送消息的
 59      * @param aliases  List<String> 接收者極光id列表
 60      * @param time 定時發送時間(yyyy-MM-dd HH:mm:ss)
 61      * @param msgTitle 標題
 62      * @param msgContent 內容
 63      * @param sysMsgId 系統保存的消息id
 64      * @param type 跳轉類型0不帶鏈接跳轉,1帶鏈接跳轉
 65      * @param url 跳轉url
 66      * @return
 67      * @author wxz
 68      * @date 2017年3月7日
 69      */
 70     public static String createSingleSchedule(List<String> aliases,
 71             String time, String msgTitle, String msgContent, 
 72             String sysMsgId, String type, String url) {
 73         if(CollectionUtils.isEmpty(aliases)){
 74             LOG.info("aliases is empty");
 75             return null;
 76         }
 77         JPushClient jpushClient = new JPushClient(masterSecret, appKey, timeToLive);
 78         String name = "schedule_"+time.replaceAll(" ", "").replaceAll(":", "").replaceAll("-", "");
 79         Map<String, String> extra = new HashMap<String, String>();
 80         extra.put("sysMsgId", sysMsgId);
 81         extra.put("type", type);//0不帶鏈接跳轉,1帶鏈接跳轉
 82         extra.put("url", url);
 83         
 84 //        Message message = new cn.jpush.api.push.model.Message.Builder()
 85 //                .setMsgContent(msgContent).addExtras(extra)
 86 //                .build();
 87 //        Audience audience = new cn.jpush.api.push.model.audience.Audience.Builder().build().alias(aliases);
 88         //初始化android消息通知
 89         cn.jpush.api.push.model.notification.AndroidNotification androidNotification = new cn.jpush.api.push.model.notification.AndroidNotification.Builder().setAlert(msgContent).setTitle(msgTitle).addExtras(extra).build();
 90         //初始化ios消息通知
 91         cn.jpush.api.push.model.notification.IosNotification iosNotification = new cn.jpush.api.push.model.notification.IosNotification.Builder().setAlert(msgContent).addExtras(extra).build();
 92         //初始化消息通知,將android和ios賦值
 93         cn.jpush.api.push.model.notification.Notification notification = new cn.jpush.api.push.model.notification.Notification.Builder()
 94               .addPlatformNotification(androidNotification)
 95                 .addPlatformNotification(iosNotification)
 96                 .build();
 97         //初始化push
 98         PushPayload push = new cn.jpush.api.push.model.PushPayload.Builder()
 99               .setPlatform(Platform.all())
100               .setAudience(Audience.alias(aliases))
101               .setNotification(notification)
102               .build();
103 //        PushPayload pucsh = PushPayload.alertAll("----test schedule example0000001111111.");
104         try {
105             ScheduleResult result = jpushClient.createSingleSchedule(name, time, push);
106             LOG.info("schedule result is " + result);
107             return result.getSchedule_id();
108         } catch (APIConnectionException e) {
109             LOG.error("Connection error. Should retry later. ", e);
110         } catch (APIRequestException e) {
111             LOG.error("Error response from JPush server. Should review and fix it. ", e);
112             LOG.info("HTTP Status: " + e.getStatus());
113             LOG.info("Error Code: " + e.getErrorCode());
114             LOG.info("Error Message: " + e.getErrorMessage());
115         }
116         return null;
117     }
118     /**
119      * 添加所有用戶定時發送消息的
120      * @param time 定時發送時間(yyyy-MM-dd HH:mm:ss)
121      * @param msgTitle 標題
122      * @param msgContent 內容
123      * @param sysMsgId 系統保存的消息id
124      * @param type 跳轉類型0不帶鏈接跳轉,1帶鏈接跳轉
125      * @param url 跳轉url
126      * @return
127      * @author wxz
128      * @date 2017年3月7日
129      */
130     public static String createSingleSchedule(String time, String msgTitle,
131             String msgContent, String sysMsgId, String type, String url) {
132         JPushClient jpushClient = new JPushClient(masterSecret, appKey, timeToLive);
133         String name = "schedule_"+time.replaceAll(" ", "").replaceAll(":", "").replaceAll("-", "");
134         Map<String, String> extra = new HashMap<String, String>();
135         extra.put("sysMsgId", sysMsgId);
136         extra.put("type", type);//0不帶鏈接跳轉,1帶鏈接跳轉
137         extra.put("url", url);
138         
139 //        Message message = new cn.jpush.api.push.model.Message.Builder()
140 //                .setMsgContent(msgContent).addExtras(extra)
141 //                .build();
142 //        PushPayload push = new cn.jpush.api.push.model.PushPayload.Builder().setPlatform(Platform.all())
143 //                .setAudience(Audience.all())
144 //                .setMessage(message)
145 ////                .setOptions(new cn.jpush.api.push.model.Options.Builder().setApnsProduction(true).build())
146 //                .build();
147         //初始化android消息通知
148         cn.jpush.api.push.model.notification.AndroidNotification androidNotification = new cn.jpush.api.push.model.notification.AndroidNotification.Builder().setAlert(msgContent).setTitle(msgTitle).addExtras(extra).build();
149         //初始化ios消息通知
150         cn.jpush.api.push.model.notification.IosNotification iosNotification = new cn.jpush.api.push.model.notification.IosNotification.Builder().setAlert(msgContent).addExtras(extra).build();
151         //初始化消息通知,將android和ios賦值
152         cn.jpush.api.push.model.notification.Notification notification = new cn.jpush.api.push.model.notification.Notification.Builder()
153               .addPlatformNotification(androidNotification)
154                 .addPlatformNotification(iosNotification)
155                 .build();
156         //初始化push
157         PushPayload push = new cn.jpush.api.push.model.PushPayload.Builder()
158               .setPlatform(Platform.all())
159               .setAudience(Audience.all())
160               .setNotification(notification)
161               .build();
162 //        PushPayload push = new cn.jpush.api.push.model.PushPayload.Builder()
163 //              .setPlatform(Platform.all())
164 //              .setAudience(Audience.all())
165 //              .setNotification(new cn.jpush.api.push.model.notification.Notification.Builder().addPlatformNotification(new cn.jpush.api.push.model.notification.AndroidNotification.Builder().setAlert(msgContent).setTitle(msgTitle).addExtras(extra).build())
166 //                      .addPlatformNotification(new cn.jpush.api.push.model.notification.IosNotification.Builder().setAlert(msgContent).addExtras(extra).build())
167 //                      .build())
168 //              .build();
169 //        PushPayload pucsh = PushPayload.alertAll("----test schedule example0000001111111.");
170         try {
171             ScheduleResult result = jpushClient.createSingleSchedule(name, time, push);
172             LOG.info("schedule result is " + result);
173             return result.getSchedule_id();
174         } catch (APIConnectionException e) {
175             LOG.error("Connection error. Should retry later. ", e);
176         } catch (APIRequestException e) {
177             LOG.error("Error response from JPush server. Should review and fix it. ", e);
178             LOG.info("HTTP Status: " + e.getStatus());
179             LOG.info("Error Code: " + e.getErrorCode());
180             LOG.info("Error Message: " + e.getErrorMessage());
181         }
182         return null;
183     }
184 
185     private static void testCreateDailySchedule() {
186         JPushClient jPushClient = new JPushClient(masterSecret, appKey);
187         String name = "test_daily_schedule";
188         String start = "2015-08-06 12:16:13";
189         String end = "2115-08-06 12:16:13";
190         String time = "14:00:00";
191         PushPayload push = PushPayload.alertAll("test daily example.");
192         try {
193             ScheduleResult result = jPushClient.createDailySchedule(name, start, end, time, push);
194             LOG.info("schedule result is " + result);
195         } catch (APIConnectionException e) {
196             LOG.error("Connection error. Should retry later. ", e);
197         } catch (APIRequestException e) {
198             LOG.error("Error response from JPush server. Should review and fix it. ", e);
199             LOG.info("HTTP Status: " + e.getStatus());
200             LOG.info("Error Code: " + e.getErrorCode());
201             LOG.info("Error Message: " + e.getErrorMessage());
202         }
203     }
204 
205     private static void testCreateWeeklySchedule() {
206         JPushClient jPushClient = new JPushClient(masterSecret, appKey);
207         String name = "test_weekly_schedule";
208         String start = "2015-08-06 12:16:13";
209         String end = "2115-08-06 12:16:13";
210         String time = "14:00:00";
211         Week[] days = {Week.MON, Week.FRI};
212         PushPayload push = PushPayload.alertAll("test weekly example.");
213         try {
214             ScheduleResult result = jPushClient.createWeeklySchedule(name, start, end, time, days, push);
215             LOG.info("schedule result is " + result);
216         } catch (APIConnectionException e) {
217             LOG.error("Connection error. Should retry later. ", e);
218         } catch (APIRequestException e) {
219             LOG.error("Error response from JPush server. Should review and fix it. ", e);
220             LOG.info("HTTP Status: " + e.getStatus());
221             LOG.info("Error Code: " + e.getErrorCode());
222             LOG.info("Error Message: " + e.getErrorMessage());
223         }
224     }
225 
226     private static void testCreateMonthlySchedule() {
227         JPushClient jPushClient = new JPushClient(masterSecret, appKey);
228         String name = "test_monthly_schedule";
229         String start = "2015-08-06 12:16:13";
230         String end = "2115-08-06 12:16:13";
231         String time = "14:00:00";
232         String[] points = {"01", "02"};
233         PushPayload push = PushPayload.alertAll("test monthly example.");
234         try {
235             ScheduleResult result = jPushClient.createMonthlySchedule(name, start, end, time, points, push);
236             LOG.info("schedule result is " + result);
237         } catch (APIConnectionException e) {
238             LOG.error("Connection error. Should retry later.", e);
239         } catch (APIRequestException e) {
240             LOG.error("Error response from JPush server. Should review and fix it. ", e);
241             LOG.info("HTTP Status: " + e.getStatus());
242             LOG.info("Error Code: " + e.getErrorCode());
243             LOG.info("Error Message: " + e.getErrorMessage());
244         }
245     }
246 
247     private static void testDeleteSchedule(String scheduleId) {
248 //        String scheduleId = "************************8";
249         JPushClient jpushClient = new JPushClient(masterSecret, appKey);
250 
251         try {
252             jpushClient.deleteSchedule(scheduleId);
253         } catch (APIConnectionException e) {
254             LOG.error("Connection error. Should retry later. ", e);
255         } catch (APIRequestException e) {
256             LOG.error("Error response from JPush server. Should review and fix it. ", e);
257             LOG.info("HTTP Status: " + e.getStatus());
258             LOG.info("Error Code: " + e.getErrorCode());
259             LOG.info("Error Message: " + e.getErrorMessage());
260         }
261     }
262 
263     private static void testGetScheduleList() {
264         int page = 1;
265         JPushClient jpushClient = new JPushClient(masterSecret, appKey);
266 
267         try {
268             ScheduleListResult list = jpushClient.getScheduleList(page);
269             LOG.info("total " + list.getTotal_count());
270             for(ScheduleResult s : list.getSchedules()) {
271                 LOG.info(s.toString());
272             }
273         } catch (APIConnectionException e) {
274             LOG.error("Connection error. Should retry later. ", e);
275         } catch (APIRequestException e) {
276             LOG.error("Error response from JPush server. Should review and fix it. ", e);
277             LOG.info("HTTP Status: " + e.getStatus());
278             LOG.info("Error Code: " + e.getErrorCode());
279             LOG.info("Error Message: " + e.getErrorMessage());
280         }
281     }
282 
283     private static void testUpdateSchedule() {
284         String scheduleId = "*******************";
285         JPushClient jpushClient = new JPushClient(masterSecret, appKey);
286         String[] points = {Week.MON.name(), Week.FRI.name()};
287         TriggerPayload trigger = TriggerPayload.newBuilder()
288                 .setPeriodTime("2015-08-01 12:10:00", "2015-08-30 12:12:12", "15:00:00")
289                 .setTimeFrequency(TimeUnit.WEEK, 2, points)
290                 .buildPeriodical();
291         SchedulePayload payload = SchedulePayload.newBuilder()
292                 .setName("test_update_schedule")
293                 .setEnabled(false)
294                 .setTrigger(trigger)
295                 .build();
296         try {
297             jpushClient.updateSchedule(scheduleId, payload);
298         } catch (APIConnectionException e) {
299             LOG.error("Connection error. Should retry later. ", e);
300         } catch (APIRequestException e) {
301             LOG.error("Error response from JPush server. Should review and fix it. ", e);
302             LOG.info("HTTP Status: " + e.getStatus());
303             LOG.info("Error Code: " + e.getErrorCode());
304             LOG.info("Error Message: " + e.getErrorMessage());
305         }
306     }
307 
308     private static void testGetSchedule(String scheduleId) {
309 //        String scheduleId = "************************";
310         JPushClient jpushClient = new JPushClient(masterSecret, appKey);
311 
312         try {
313             ScheduleResult result = jpushClient.getSchedule(scheduleId);
314             LOG.info("schedule " + result);
315         } catch (APIConnectionException e) {
316             LOG.error("Connection error. Should retry later. ", e);
317         } catch (APIRequestException e) {
318             LOG.error("Error response from JPush server. Should review and fix it. ", e);
319             LOG.info("HTTP Status: " + e.getStatus());
320             LOG.info("Error Code: " + e.getErrorCode());
321             LOG.info("Error Message: " + e.getErrorMessage());
322         }
323     }
324 
325     /**
326      * 組建push,若發送全部,則aliases傳null
327      * @param aliases  List<String> 接收者極光id列表
328      * @param msgTitle 標題
329      * @param msgContent 內容
330      * @param sysMsgId 系統保存的消息id
331      * @param type 跳轉類型0不帶鏈接跳轉,1帶鏈接跳轉
332      * @param url 跳轉url
333      * @return
334      * @author wxz
335      * @date 2017年3月7日
336      */
337     private static PushPayload buildPush(List<String> aliases,String msgTitle, String msgContent,
338             String sysMsgId, String type, String url) {
339         Map<String, String> extra = new HashMap<String, String>();
340         extra.put("sysMsgId", sysMsgId);
341         extra.put("type", type);//0不帶鏈接跳轉,1帶鏈接跳轉
342         extra.put("url", url);
343         //初始化android消息通知
344         cn.jpush.api.push.model.notification.AndroidNotification androidNotification = new cn.jpush.api.push.model.notification.AndroidNotification.Builder().setAlert(msgContent).setTitle(msgTitle).addExtras(extra).build();
345         //初始化ios消息通知
346         cn.jpush.api.push.model.notification.IosNotification iosNotification = new cn.jpush.api.push.model.notification.IosNotification.Builder().setAlert(msgContent).addExtras(extra).build();
347         //初始化消息通知,將android和ios賦值
348         cn.jpush.api.push.model.notification.Notification notification = new cn.jpush.api.push.model.notification.Notification.Builder()
349               .addPlatformNotification(androidNotification)
350                 .addPlatformNotification(iosNotification)
351                 .build();
352         //初始化push
353         PushPayload push = new cn.jpush.api.push.model.PushPayload.Builder()
354               .setPlatform(Platform.all())
355               .setAudience(CollectionUtils.isEmpty(aliases)?Audience.all():Audience.alias(aliases))
356               .setNotification(notification)
357               .build();
358         return push;
359     }
360 }

 


免責聲明!

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



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