定时群发主要分为两部分:定时任务和群发任务java
定时任务能够经过前台传递过来的时间参数,来启动定时器,并在指定的时间,启动群发任务。json
定时任务设置代码以下服务器
/** * 在某个时间点执行一次 * @Title SimpleRun * @Description * @author Administrator * @param * @return void * @throws ParseException */ private void SimpleRun(Record record) { //获取到前台传递过来的时间参数 String send_time = record.getStr("send_time"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); SchedulerFactory factory = new StdSchedulerFactory(); Scheduler schedule; Date send_date = null; int time = 0; try { send_date = sdf.parse(send_time); //获取任务调度器 schedule = factory.getScheduler(); //此对象用来像job传递参数 JobDataMap dataMap = new JobDataMap(); dataMap.put("msg_record", record); //定义job对象,并绑定自定义WXArticleSendJob类 //真正执行job的任务,并非实现了Job接口的WXArticleSendJob类,而是经过反射的方式实例化的一个JobDetail的对象 JobDetail jobDetail = JobBuilder.newJob(WXArticleSendJob.class).withIdentity(send_time, Constants.WX_GROUP).usingJobData(dataMap).build(); // Date start_time = DateBuilder.nextGivenSecondDate(null, 10); SimpleTrigger simpleTrigger = (SimpleTrigger) TriggerBuilder.newTrigger(). withIdentity("simpleTrigger", "wx_trigger_group").withDescription("定时群发微信") /* .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(10)//重复间隔 .withRepeatCount(5))//重复次数 */ .startAt(send_date).build(); Date df = schedule.scheduleJob(jobDetail, simpleTrigger); log.info("job id 为"+jobDetail.getKey().getName()+ "的任务,将在"+sdf.format(df)+"运行. 而且基于描述: "+simpleTrigger.getDescription()); MsgSendService service = new MsgSendService(); //群发信息入库 boolean flag = service.saveMsg(record); schedule.start(); } catch (SchedulerException e) { time++; System.out.println("time --------"+time); e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); log.error(e.getMessage()); } } /** * 定时群发job * 此job的主要功能是向粉丝发送消息 * 因为微信服务器将会在群发任务即将完成的时候,就推送群发结果,此时的推送人数数据将会与实际情形存在必定偏差 * @author Administrator * * 2015-12-10 */ @DisallowConcurrentExecution//保存在JobDataMap传递的参数 @PersistJobDataAfterExecution//保证多个任务间不会同时执行.因此在多任务执行时最好加上 public class WXArticleSendJob implements Job{ public static final Logger log = Logger.getLogger(WXArticleSendJob.class); @Override public void execute(JobExecutionContext context) { JobDataMap dataMap = context.getJobDetail().getJobDataMap(); Record msg_record = (Record) dataMap.get("msg_record"); //token String token = AccessTokenApi.getAccessToken().getAccessToken(); String data = processSendMsgData(msg_record); JSONObject jsonObj = null; int count = 0; //像微信服务器发送群发任务,最多尝试三次 while(count < Constants.TOTAL_COUNT){ //群发 String result = HttpKit.post(Constants.SEND_MSG+token, data); //解析群发结果 jsonObj = JSONObject.parseObject(result); int errcode = jsonObj.getIntValue("errcode"); //说明报错了 if(0 != errcode){ count++; log.error(jsonObj.getString("errmsg")); }else{ break; } } //说明没有请求成功 if(count == Constants.TOTAL_COUNT){ msg_record.set("errmsg", jsonObj.getString("errmsg")); msg_record.set("type", 2); }else{ String msg_id = jsonObj.getString("msg_id"); String msg_data_id = jsonObj.getString("msg_data_id"); msg_record.set("msg_id", msg_id); msg_record.set("msg_data_id", msg_data_id); } MsgSendService service = new MsgSendService(); //群发信息入库 try { service.updateMsg(msg_record); } catch (ParseException e) { e.printStackTrace(); log.error(e.getMessage()); } // 任务执行的时间 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy 年 MM 月 dd 日 HH 时 mm 分 ss 秒"); String jobRunTime = dateFormat.format(Calendar.getInstance().getTime()); String jobName = context.getJobDetail().getKey().getName(); log.info("任务"+jobName+"在"+jobRunTime+"执行了"); } /** * * @Title processSendMsgData * @Description 拼接群发须要的字符串 * @author Administrator * @param * @date 2016-1-27 * @return String */ private String processSendMsgData(Record record){ String msg_type = record.getStr("msg_type"); StringBuffer sb = new StringBuffer("{"); if("news".equalsIgnoreCase(msg_type)){ sb.append("\"filter\":").append("{").append("\"is_to_all\":").append(record.getInt("is_to_all")).append(",\"group_id\":").append(record.getInt("group_id")).append("},"); sb.append("\"mpnews\":").append("{").append("\"media_id\":\"").append(record.getStr("media_id")).append("\"").append("},"); sb.append("\"msgtype\":").append("\"mpnews\""); }else if("voice".equalsIgnoreCase(msg_type)){ sb.append("\"filter\":").append("{").append("\"is_to_all\":").append(record.getInt("is_to_all")).append(",\"group_id\":").append(record.getInt("group_id")).append("},"); sb.append("\"voice\":").append("{").append("\"media_id\":\"").append(record.getStr("media_id")).append("\"").append("},"); sb.append("\"msgtype\":").append("\"voice\""); }else if("text".equalsIgnoreCase(msg_type)){ sb.append("\"filter\":").append("{").append("\"is_to_all\":").append(record.getInt("is_to_all")).append(",\"group_id\":").append(record.getInt("group_id")).append("},"); sb.append("\"text\":").append("{").append("\"content\":\"").append(record.getStr("content")).append("\"").append("},"); sb.append("\"msgtype\":").append("\"text\""); }else if("image".equalsIgnoreCase(msg_type)){ sb.append("\"filter\":").append("{").append("\"is_to_all\":").append(record.getInt("is_to_all")).append(",\"group_id\":").append(record.getInt("group_id")).append("},"); sb.append("\"image\":").append("{").append("\"media_id\":\"").append(record.getStr("media_id")).append("\"").append("},"); sb.append("\"msgtype\":").append("\"image\""); }else if("video".equalsIgnoreCase(msg_type)){ } sb.append("}"); return sb.toString(); }