生成环境:
OS: Mac OSX 10.5.6
DB: Oracle 9i
Java:dev on JDK 5 run on JDK6
JAVA IDE : netbeans6.5 path 1
Java framework : Spring 2.5 Hibernate 3 with JPA Open-CMPP
注:
关于Open_CMPP,本来用的短信库是华为那个,可是上头给我的库有问题,构造发送短信的时候死活有问题.还好找到了一个反编译的类库,用法完全跟华为的一样.作者还改了一些BUG.特别感谢他
他的blog
小结一下主要技术:
呃,主要是想学习一下在注解的支持下开发 Spring+JPA,还有用到JDK5 的多线程技术 的开发.
分多页写
- 半桶水开发 CMPP2.0 with Spring + JPA 1
- 半桶水开发 CMPP2.0 with Spring + JPA 2
- 半桶水开发 CMPP2.0 with Spring + JPA 3
首先看一下结构:
引用
- Send 表 短信待发送表
- Log 表 短信发送日志表
- Deliver 表 短信网关下发的短信表
我要负责的业务就是扫描短信发送表,查找到符合条件的记录(比如发送到移动的),接发送到短信网关,如果成功就插入记录到Log表.还有一个线程是一直监听移动短信网关的下发短信,收到后记录到Rec表中
这样目前我就有2个Service
SendThreadService.java
/** * * @author rikugun */ public class SendThreadService implements Runnable { @Autowired SendDao sendDao; //Send表的Dao @Autowired LogDao logDao; //Log表的Dao @Autowired CMPPProxy CMPPProxy; //短信代理 private Logger log = Logger.getLogger(SendThreadService.class.getName()); private final int sendinterval = 1; //puase seconds 每次发送后等待时间(秒) private final int Max_sms = 10; //每次最多从Send 表中取记录的条数 //TODO 以后改成从配置文件中读取 /* * 发送成功后插入到Log表中,然后将Send中那条记录删掉 * @param SpSmsSend 要发送的短信 */ @Transactional void insertLog(SpSmsSend sms) throws PreexistingEntityException, Exception { //将SpSmsSend转换成SpSmsLog后保存 SpSmsLog sms_log = (SpSmsLog) sms; sms_log.setSendTime(new Date(System.currentTimeMillis())); logDao.create(sms_log); sendDao.destroy(sms.getId()); } @Override public void run() { while (true) { //获取业务类型是移动的短信 smsOperator为业务类型(移动) Listorder_to_send = sendDao.findCMPPEntities(Max_sms, 0); log.log(Level.INFO, "Start to Send " + order_to_send.size() + " Messages..."); for (int i = 0; i < order_to_send.size(); i++) { SpSmsSend sms = order_to_send.get(i); log.log(Level.INFO, "Sending [" + sms.getSmsLsh() + "]"); //将SpSmsSend 转换为 华为CMPP包的格式 CMPPSubmitRepMessage result = CMPPProxy.sendWithRep(TypeConv.toCMPP(order_to_send.get(i))); if (result.getResult() == 0) { try { insertLog(sms); } catch (PreexistingEntityException ex) { Logger.getLogger(SendThreadService.class.getName()).log(Level.SEVERE, null, ex); } catch (Exception ex) { Logger.getLogger(SendThreadService.class.getName()).log(Level.SEVERE, null, ex); } log.log(Level.INFO, "Success Sended!"); } else { log.log(Level.WARNING, "Send Failed!"); log.log(Level.WARNING, "Error code = " + result.getResult()); } try { Thread.sleep(1000 * sendinterval); } catch (Exception exception) { exception.printStackTrace(); } } try { Thread.sleep(1000); } catch (InterruptedException ex) { log.log(Level.SEVERE, null, ex); } } } }
收取下发的短信的线程
DeliverThreadService.java
/** * * @author rikugun */ public class DeliverThreadService implements Runnable { private final int sleeptime = 1; private Logger log = Logger.getLogger(DeliverThreadService.class.getName()); @Autowired CMPPProxy CMPPProxy; @Autowired DeliverDao deliverDao; BlockingQueuequeue; private SpSmsDeliver deliver = null; @Override public void run() { queue = CMPPProxy.getDeliveMsgs(); while (true) { log.log(Level.INFO, "Waiting for Deliver.."); try { //从队列中取得下发短信 CMPPDeliverMessage msg = queue.take(); deliver = new SpSmsDeliver(msg.getDestnationId()); deliver.setContent(msg.getMsgContent().toString()); deliver.setResTime(new Date(System.currentTimeMillis())); deliver.setSmsOperator(1); deliver.setMobileNo(msg.getSrcterminalId()); try { deliverDao.create(deliver); } catch (PreexistingEntityException ex) { log.log(Level.SEVERE, null, ex); } catch (Exception ex) { log.log(Level.SEVERE, null, ex); } log.log(Level.FINE, msg.toString()); Thread.sleep(1000 * sleeptime); } catch (InterruptedException ex) { log.log(Level.SEVERE, null, ex); } log.log(Level.FINE, "Still Waiting..."); } } }