存放調度器(Job 和 Trigger)信息的xml配置文件:
這是某個指定的要實現的定時任務:
<!-- 每天給項目經理發送短信避免短信服務掛了 定時每天08:30執行--> <job> <name>SendToManagerJob</name> <job-class>com.xxx.cscns.sms.SendToManagerJob</job-class> </job> <trigger> <cron> <name>SendToManagerJob</name> <job-name>SendToManagerJob</job-name> <cron-expression>0 30 8 * * ?</cron-expression> </cron> </trigger>
這是一個實時執行的任務服務,負責推送系統數據庫短信信息表中的數據給運營商的接口完成發送短信操作:
<!-- 實時掃描短信數據表,沒有發送的調用運營商給的接口推送,完成發送短信操作 --> <job> <name>ReceiveMessageJob</name> <job-class>com.xxx.cscns.sms.ReceiveMessageJob</job-class> </job> <trigger> <simple> <name>ReceiveMessageJob</name> <job-name>ReceiveMessageJob</job-name> <repeat-count>-1</repeat-count> <repeat-interval>1</repeat-interval> </simple> </trigger>
上面配置的實時執行的意思就是間隔1毫秒執行無數次,由這個服務配合才能實現其他的任務服務,其他的任務就是完成插入指定的一些信息進入系統的數據表中,再由這個實時的推送服務第一時間推送給運營商接口完成發送操作,發送給指定的手機號;
所以發送短信必要要有合作的運營商的參數,ip,端口,賬號和密碼;
實時執行的任務服務job實現類:
package com.xxx.cscns.sms; import java.util.Date; import java.util.List; import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import com.xxx.cert.basic.certinfo.inter.ICertInfo; import com.xxx.core.grammar.Record; import com.xxx.core.utils.config.ConfigUtil; import com.xxx.core.utils.container.ContainerFactory; import com.xxx.core.utils.string.StringUtil; import com.xxx.cscns.impl.SMSReceiveImpl; import com.xxx.cscns.service.MessageService; import com.xxx.cscns.utils.ConstValue; import com.xxx.database.jdbc.connection.DataSourceConfig; import com.xxx.frame.service.metadata.code.api.ICodeItemsService; import com.xxx.frame.service.metadata.code.entity.CodeItems; import com.esotericsoftware.minlog.Log; import com.linkage.netmsg.NetMsgclient; import com.linkage.netmsg.server.ReceiveMsg; /** * 短信接收服務 * @author wmqiang * @see [相關類/方法] * @since [產品/模塊版本] */ @DisallowConcurrentExecution public class ReceiveMessageJob implements Job {
// 封裝的獲取運營商的參數,ip,端口,賬號和密碼 private static String ip = ConstValue.QXT_IP; private static int port = Integer.parseInt(ConstValue.QXT_PORT); private static String userName = ConstValue.QXT_USERNAME; private static String pwd = ConstValue.QXT_PWD; //升級系統數據庫連接配置信息 public static String sjUrl = ConstValue.sjUrl; public static String sjUsername = ConstValue.sjUsername; public static String sjPassword = ConstValue.sjPassword; @Override public void execute(JobExecutionContext arg0) throws JobExecutionException { try { try { System.out.println("------------進入短信發送服務-----------\r\n"); MessageService messgeService = new MessageService(); MessageService sjmessgeService = new MessageService(sjUrl,sjUsername,sjPassword); NetMsgclient client = new NetMsgclient(); ReceiveMsg receiveMsg = new SMSReceiveImpl(); client = client.initParameters(ip, port, userName, pwd, receiveMsg); /* 登錄認證 */ boolean isLogin = client.anthenMsg(client); Log.info("------------receive " + isLogin + " loginsucess------------\r\n"); if (isLogin) { String phone = ""; String content = ""; String rowguid = ""; //獲取分表表名,找到數據表就行,不用管 ICodeItemsService iCodeItemsService = ContainerFactory.getContainInfo().getComponent(ICodeItemsService.class); List<CodeItems> codeItemsList = iCodeItemsService.listCodeItemsByCodeName("短信分表"); if(codeItemsList != null){ for(CodeItems codeitem : codeItemsList){ //分表表名 String tablename = codeitem.getItemText(); // 調用方法找出系統數據表中沒有發送的短信 List<Record> listInfo = messgeService.getSendMessage(tablename); for (Record info : listInfo) { phone = info.get("MessageTarget"); content = info.get("Content"); rowguid = info.get("MessageItemGuid"); if (StringUtil.isNotBlank(content) && StringUtil.isNotBlank(phone)) { System.out.println(new Date() + "【xxx項目】短信發送服務已發送短信:" + phone + " 內容:" + content + "\r\n"); client.sendMsg(client, 0, phone, content, 1); messgeService.updateMessageCenterByRowguid(rowguid,tablename); } } //升級項目短信發送 List<Record> SJlistInfo = sjmessgeService.getSendMessage(tablename); for (Record info : SJlistInfo) { phone = info.get("MessageTarget"); content = info.get("Content"); rowguid = info.get("MessageItemGuid"); if (StringUtil.isNotBlank(content) && StringUtil.isNotBlank(phone)) { client.sendMsg(client, 0, phone, content, 1); sjmessgeService.updateMessageCenterByRowguid(rowguid,tablename); System.out.println(new Date() + "【升級項目】短信發送服務已發送短信:" + phone + " 內容:" + content + "\r\n"); } } } } client.closeConn(); Thread.sleep(5000); } } catch (Exception e1) { e1.printStackTrace(); } finally { } } catch (Exception e) { e.printStackTrace(); } } }
其中// 封裝的獲取運營商的參數,ip,端口,賬號和密碼,在一個配置文件中配置參數,
// 調用方法找出系統數據表中沒有發送的短信messgeService.getSendMessage(tablename):
public class MessageService { /** * 找出未發送短信 * @return * @exception/throws [違例類型] [違例說明] * @see [類、類#方法、類#成員] */ public List<Record> getSendMessage(String tablename) { List<Record> list = new ArrayList<>(); // 獲取到短信表中需要發送短信的信息即可 /*String strSql = "SELECT * FROM Messages_Center WHERE SendMode=1 and ((IsSchedule=1 and ScheduleSendDate< NOW() ) or ( IsSchedule=0) ) ";*/ String strSql = "SELECT * FROM "+tablename+" WHERE SendMode=1 and ((IsSchedule=1 and ScheduleSendDate< NOW() )" + " or ( IsSchedule=0) ) " + " and GENERATEDATE >= (select date_sub(now(), interval 2 hour)) "; try { list = dao.findList(strSql, Record.class); } catch (Exception e) { e.printStackTrace(); } finally { if (dao != null){ dao.close(); } } return list; } }
以上后台代碼就是實現了實時發送短信的任務;
接下來有需要發送特定短信內容的業務場景中,只要往存儲短信的這張數據表中插數據即可;
有需要發送特定短信內容的定時任務實現,也就是配置特定的調度完成往存儲短信的這張數據表中插數據操作就行;
如上面的那個配置
每天給項目經理發送短信避免短信服務掛了 定時每天08:30執行
實例后台代碼:
根據配置的調度信息,找到job的實現類和其業務邏輯實施層方法,如下實例:
job實現類的代碼:
package com.xxx.cscns.sms; import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import com.xxx.core.xxxFrameDsManager; import com.xxx.cscns.service.MessageService; @DisallowConcurrentExecution public class SendToManagerJob implements Job{ @Override public void execute(JobExecutionContext arg0) throws JobExecutionException { try { xxxFrameDsManager.begin(null); MessageService messageService = new MessageService(); // 調用業務邏輯實施層方法,實現發短信操作 messageService.sendToManger(); System.out.println("上班前半小時發送一次短信給項目經理成功!"); } catch (Exception e) { xxxFrameDsManager.rollback(); e.printStackTrace(); System.out.println("上班前半小時發送一次短信給項目經理異常:"+e.toString()); } finally { xxxFrameDsManager.close(); } } }
封裝的業務邏輯實施層的方法:
/* * * 每天給項目經理發送短信避免短信服務掛了 */ public void sendToManger() { try { //系統參數配置項目經理手機號碼,這兒是封裝的方法,只要能獲取到項目經理手機號就行 String messageTarget = new FrameConfigService9().getFrameConfigValue("ASP_MESSAGE_TEST_TEL"); //時間格式化 SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String sql = "insert into Messages_center ( MessageItemGuid, Content, GenerateDate, IsSchedule, MessageTarget, sendMode,messagetype)"; sql += "values( '" + UUID.randomUUID().toString() + "', '【XXX項目】短信服務正常。', to_date('" + sdf2.format(new Date())+ "', 'yyyy-mm-dd hh24:mi:ss'), 0, '" + messageTarget + "', 1,'短信')"; if(StringUtil.isNotBlank(messageTarget)){ dao.execute(sql); } } catch (Exception e) { e.printStackTrace(); dao.rollBackTransaction(); } finally { if (dao != null){ dao.close(); } } }
其中最后的業務邏輯實施層的方法中,就是完成了定時往特定的存儲短信內容的數據表中,插入相應的數據的操作;