价格不是我们的优势,品质永远是我们的追求!
当前位置:首页行业快讯 > 如何用java实现触发短信提醒
如何用java实现触发短信提醒
来源:动力思维乐信  时间:2017-12-20 17:16

    如何用java实现触发短信提醒?这个是很多利用短信接口要实现的一个功能,如一个监控项目,其中当达到警告要求就要发送短信提醒,下面就介绍下具体的实现步骤,和接入的时部分代码供大家参考:

    首先需要注册动力思维乐信短信接口平台账号,注册地址:https://www.lx598.com/acc/x5?i=110792

    其次,完善该账户企业信息,申请sdk接口试用。

    第三,就是下载乐信短信接口的API文档和对应语言的demo示例,然后进行对接。

    最后,就是进行测试。

    下面是有关短信接口接入的部分代码示例,供大家参考。

    1、通过定时任务对要监控的项目进行定时扫描通知

package com.jeeplus.modules.jk.service;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import me.chanjar.weixin.cp.bean.WxCpMessage.Textcard;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import com.jeeplus.common.utils.IdGen;
import com.jeeplus.common.utils.SpringContextHolder;
import com.jeeplus.modules.jk.dao.JkListMapper;
import com.jeeplus.modules.jk.dao.JkNoticeLogMapper;
import com.jeeplus.modules.jk.entity.JkList;
import com.jeeplus.modules.jk.entity.JkNoticeLog;

@Service
@Lazy(false)
public class DlswScanService {
	@Autowired
	private JkListMapper jkListMapper;
	@Autowired
	private JkNoticeLogMapper jkNoticeLogMapper;

	private final static Logger LOGGER=Logger.getLogger(DlswScanService.class);
	
	@Scheduled(cron = "0/3 * * * * ?")
	public void scan(){
		
		//查询所有可用的监控项目
		List<JkList> jkList=jkListMapper.selectByExample(null);
		for(JkList jkItem:jkList){
			DlswJkInterface djsDlswJkInterface=SpringContextHolder.getBean(jkItem.getFclassname());
			LOGGER.info("scan:"+jkItem.getFname()+" begin");
			
			if(djsDlswJkInterface==null){//如果得不到实例
				LOGGER.info("scan:"+jkItem.getFname()+" can't getInstance");
				continue;
			}
			if(!djsDlswJkInterface.hasFinish(jkItem)){//如果上次未完成 
				LOGGER.info("scan:"+jkItem.getFname()+" didn't finish");
				continue;
			}
			JkList jkList2=new JkList();
			jkList2.setFid(jkItem.getFid());
			String scanResult=null;
			//需要扫描的项目
			if(djsDlswJkInterface.needScan(jkItem)){
				LOGGER.info("scan:"+jkItem.getFname()+" scanBegin");
				scanResult=djsDlswJkInterface.scan(jkItem);
				jkList2.setFlastScanTime(new Date());
				LOGGER.info("scan:"+jkItem.getFname()+" scan fisnish :"+scanResult);
			}
			//需要通知
			if(djsDlswJkInterface.needNotice(jkItem, scanResult)){
				String noticeResult=sendNotice(jkItem, scanResult);//发送短信通知
				LOGGER.info("scan:"+jkItem.getFname()+" sendNotice fisnish:"+noticeResult);
				jkList2.setFlastnottime(new Date());
				saveNoticeLog(jkItem,noticeResult,scanResult);//保存通知日志
			}
			jkListMapper.updateByPrimaryKeySelective(jkList2);
			LOGGER.info("scan:"+jkItem.getFname()+" end");
		}
		
	}
	//保存通知日志
	private void saveNoticeLog(JkList jkItem, String noticeResult,
			String scanResult) {
		JkNoticeLog jkNoticeLog = new JkNoticeLog();
		jkNoticeLog.setFid(IdGen.uuid());
		jkNoticeLog.setFlistId(jkItem.getFid());
		jkNoticeLog.setFnoticeContent(scanResult);
		jkNoticeLog.setFnoticeDate(new Date());
		jkNoticeLog.setFnoticeResult(noticeResult!=null?"0":"1");
		jkNoticeLog.setFnoticeMsg(noticeResult);
		jkNoticeLog.setFnoticeUser(jkItem.getFnoticeRole());
		jkNoticeLog.setFnoticeType(jkItem.getFnoticeType());
		jkNoticeLogMapper.insert(jkNoticeLog);
	}
	调用第三方接口发送短信通知
	/**
	 * 调用第三方接口发送短信通知
	 * @param accName 第三方接口用户名
	 * @param accPwd 第三方接口密码
	 * @param seed 当前时间 格式:YYYYMMDD HHMISS 例如:20130806102030
	 * @param aimcodes 手机号多个手机号之间英文半角逗号隔开
	 * @param content 内容后加签名
	 * @param schTime 定时时间格式如:2010-01-01 08:00:00
	 * @return 服务端返回的结果 ok:业务id 或者 错误代码
	 */
	private String sendNotice(JkList jkItem,String scanResult,String accName,String accPwd,String schTime){
		StringBuffer sb = new StringBuffer("https://sdk.lx198.com/sdk/send2?");
		try {
			//获得要通知角色的电话号码
			String role=jkItem.getFnoticeRole();
			List<User> user = userDao.findByRoleCode(role);
			accName = user.getAccMob();
			String roles=jkItem.getFnoticeRole();
			String[] roleArr=roles.split(",");
			Set<User> userSet=new HashSet<User>();
			for(String role:roleArr){
				userSet.addAll(userDao.findByRoleCode(role));
				}
			StringBuffer sb=new StringBuffer();
			for(User user:userSet){
				sb.append(user.getAccMob()).append(",");
			}

			String seed=new SimpleDateFormat(dateFormatStr).format(new Date());
			sb.append("&accName="+accName); 
			sb.append("&seed="+seed);
			sb.append("&accPwd="+MD5.getMd5String(MD5.getMd5String(accPwd)+seed)); 
			sb.append("&aimcodes="+sb.toString());
			sb.append("&schTime="+URLEncoder.encode(schTime,"UTF-8")); //空格标点符号做encode转换
			sb.append("&content="+URLEncoder.encode(scanResult,"UTF-8")); //中文做encode转换
			URL url = new URL(sb.toString());
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setRequestMethod("POST");
			BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
			return in.readLine();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}		

}

    2、具体监控类实现代码如下

    /**实现类代码如下:

    *这是对通道一定时间内数据数的监控

    *在特定时间内超过特定值达到次数要求就会触发发送短信通知

    *

    */

package com.jeeplus.modules.jk.service.imp;

import java.util.HashMap;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.jeeplus.modules.jk.dao.SmsQueueMapper;
import com.jeeplus.modules.jk.entity.JkList;
import com.jeeplus.modules.jk.service.DlswJkAbstractImp;
import com.jeeplus.modules.jk.service.DlswJkInterface;
import com.jeeplus.modules.jk.service.DlswJkSysConfService;
@Service
public class DlswJkRealTimeQueueImp  extends DlswJkAbstractImp implements DlswJkInterface {

	private static HashMap<String,Integer> gchHashMap=new  HashMap<String, Integer>();
	private static HashMap<String,Long> gchHashLastTimeMap=new  HashMap<String,Long>();
	
	@Autowired
	private DlswJkSysConfService dlswJkSysConfService;
	
	@Autowired
	private SmsQueueMapper smsQueueMapper;

	/**
	 * 即时队列通道数据扫描
	 * @param jkItem 监控项目
	 */

	@Override
	public String scan(JkList jkItem) {
		String scanResult=null;
		StringBuffer sbf = new StringBuffer();
		
		List<HashMap<String, Object>> slist =smsQueueMapper.selectByExample2();//有效通道 即时队列数集合
		//查询	
		int Confvalue  = dlswJkSysConfService.getSysConf1("RQ_COUNT");
		int redCount  = dlswJkSysConfService.getSysConf1("RED_COUNT");	
		
		for (HashMap<String, Object> statusMap : slist) {
			int recordCount = gchHashMap.get(String.valueOf(statusMap.get("GCHID"))==null?0:Integer.parseInt(String.valueOf(statusMap.get("GCHID"))));
			if(Integer.parseInt(statusMap.get("QUEUECOUNT").toString())>=Confvalue){
				if(!gchHashLastTimeMap.containsKey(String.valueOf(statusMap.get("GCHID")))){
					gchHashLastTimeMap.put(String.valueOf(statusMap.get("GCHID")), System.currentTimeMillis());
				}
				recordCount++;
				gchHashMap.put(String.valueOf(statusMap.get("GCHID")),recordCount);
			}else{
				recordCount = 0;
				gchHashLastTimeMap.remove(String.valueOf(statusMap.get("GCHID")));
				gchHashMap.put(String.valueOf(statusMap.get("GCHID")),recordCount);
				continue;
			}
			
			if(recordCount>=redCount&&(System.currentTimeMillis()-gchHashLastTimeMap.get(String.valueOf(statusMap.get("GCHID"))))>60*1000){
				//触发通知,发送短信	
				scanResult= statusMap.get("GCHNAME")+"通道,1分钟内即时队列数据无变化,请关注处理##";
				sbf.append(scanResult);
			}	
		}
		return sbf.toString();
	}	
}

    3、短信接口

package com.jeeplus.modules.jk.service;
import org.springframework.stereotype.Service;
import com.jeeplus.modules.jk.entity.JkList;

@Service
public interface DlswJkInterface {
	
	/**
	 * 判断上次扫描是否结束
	 * @param lock
	 * @param jkItem
	 * @return
	 */
	public boolean hasFinish(JkList jkItem);
	
	/**
	 * 结束扫描
	 * @param lock
	 * @param jkItem
	 */
	public void finishItem(JkList jkItem);
	
	/**
	 * 是否需要扫描
	 * @param jkItem 监控项目
	 * @return true 为需要
	 */
	public boolean needScan(JkList jkItem);
	
	/**
	 * 是否需要通知
	 * @param jkItem
	 * @return 
	 */
	public boolean needNotice(JkList jkItem,String scanResult);
	
	
	/**
	 * 扫描
	 * @param jkItem
	 * @return 如果不需要通知返回null 否则返回通知内容
	 */
	public String scan(JkList jkItem);
	
}

// 判断是否需要扫描或通知
package com.jeeplus.modules.jk.service;

import java.util.Date;
import java.util.concurrent.locks.ReentrantLock;
import com.jeeplus.modules.jk.entity.JkList;
import com.jeeplus.modules.jk.utils.NoticeUtil;

public abstract class DlswJkAbstractImp implements DlswJkInterface{
	
	protected ReentrantLock lock=new ReentrantLock();

	
	public boolean hasFinish(JkList jkItem){
		return lock.tryLock();
	}
	
	public void finishItem(JkList jkItem){
		lock.unlock();
	}
	/**
	 * 是否需要扫描 默认实现为扫描间隔达到上次扫描时间后
	 * @param jkItem 监控项目
	 * @return true 为需要
	 */
	public boolean needScan(JkList jkItem){
		return System.currentTimeMillis()-jkItem.getFlastScanTime().getTime()>jkItem.getFcron().doubleValue()*1000;
	}
	
	/**
	 * 是否需要通知 默认实现为达到通知间隔,且扫描结果为需要通知,通知时间符合当前时间
	 * @param jkItem
	 * @return 
	 */
	public boolean needNotice(JkList jkItem,String scanResult){
		return scanResult!=null&&System.currentTimeMillis()-jkItem.getFlastnottime().getTime()>jkItem.getFtzjg().doubleValue()*1000&&NoticeUtil.isNoticeTime(new Date(),jkItem);
	}	
	
}

    4、//只列举jklist类的属性,get,set方法以及构造函数就不放了,可以根据自己业务需要设置类

package com.jeeplus.modules.jk.entity;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

public class JkList implements Serializable {
    private String fid;

    private String fname;//监控名称

    private BigDecimal fcron;//监控频率

    private BigDecimal ftzjg;//通知间隔时间

    private String fnoticeRole;// 通知角色

    private String ftitle;//标题

    private String fnoticeType;//通知类型

    private String fnoticeTime;//通知时间

    private String fclassname;//监控实现类

    private Date flastnottime;//最后通知时间

    private String fcreateuser;

    private Date fcreatedate;

    private BigDecimal forder;

    private Date flastScanTime;