存放调度器(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(); } } }
其中最后的业务逻辑实施层的方法中,就是完成了定时往特定的存储短信内容的数据表中,插入相应的数据的操作;