`
liufei.fir
  • 浏览: 685174 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

短信发送

阅读更多
package com.smp.sev.sms;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.smp.bean.MsgSubmit;
import com.smp.sev.cache.OperatorInfo;
import com.smp.sev.service.MsgService;
import com.smp.util.MsgUtil;
import com.smp.util.SmpProperty;
import com.smp.util.Tools;

/**
 * @author xml
 *
 */
@Service
public class MsgSender {
	
	@Autowired
	private MsgService ms;
	@Autowired
	private OperatorInfo op;
	
	private static final Logger logger = Logger.getLogger(MsgSender.class);
	private Timer msgTimer = new Timer("msgTimer");
	
	public MsgSender() {
		setSno(SmpProperty.getInstance().getStartSno(), SmpProperty.getInstance().getEndSno());
	}
	/**
	 * 短信服务器请求地址
	 */
	private static int msgid = 0;
	/**
	 * 当前的短号
	 */
	private int curShortNo = 0;
	/**
	 * 短号的开始号码--字符串形式,方便上行时匹配
	 */
	private static String STARTSHORTNO_STR = "0";
	/**
	 * 短号的开始号码-
	 */
	private int STARTSHORTNO = 0;
	/**
	 * 短号的结束号码
	 */
	private int ENDSHORTNO = 0;
	private synchronized int getShortNo() {
		if(curShortNo==0) {
			curShortNo = ms.getMaxShortNo();
		}
		if(curShortNo<STARTSHORTNO||curShortNo>=ENDSHORTNO)curShortNo=STARTSHORTNO+10;
		curShortNo++;
		return curShortNo;
	}
	public synchronized int getMsgid() {
		if(msgid==0) {
			msgid = ms.getMaxMsgid();
			if(msgid==-1)msgid = 0;
		}
		msgid++;
		return msgid;
	}
	
	public void setSno(int startSno, int endSno) {
		STARTSHORTNO = startSno;
		STARTSHORTNO_STR = String.valueOf(startSno);
		ENDSHORTNO = endSno;
	}
	
	public static String getStartSno() {
		return STARTSHORTNO_STR;
	}
	
	public MsgSubmit setIdAndShortNo(MsgSubmit ms) {
		ms.setMsId(getMsgid());
		if("选项调查".equals(ms.getMsType())){
			ms.setMsShortno(String.valueOf(getShortNo()));
		}else ms.setMsShortno(STARTSHORTNO_STR);
		return ms;
	}
	
	private void send(final MsgSubmit msg, final List<String[]> users,  String phones, final boolean isSaveLog,final boolean issavemsg){
		if(msg==null||users==null||(users!=null&&users.size()==0)) {
			return;
		}
		//判断手机号是那个运营商,分别调用不同的网关
		Map<String, String> operator=op.getHeNanYiDong();
		final StringBuffer yidong=new StringBuffer();
		final StringBuffer other=new StringBuffer();
		for(String[] u:users){
			String phone=u[1];
			if(phone!=null&&phone.length()>6){
				if(operator.containsKey(phone.substring(0, 7))){
					yidong.append(phone+",");
				}else{
					other.append(phone+",");
				}
			}
			
		}
		if(yidong.length()>0){
			yidong.deleteCharAt(yidong.length()-1);
		}
		if(other.length()>0){
			other.deleteCharAt(other.length()-1);
		}
		
		System.out.println(yidong.length()+":"+other.length());
		
		new Thread(new Runnable(){
			public void run() {
				long spendtime = 0;
				if (logger.isDebugEnabled()) {
					spendtime = System.currentTimeMillis();
					logger.debug("$MsgSenderRunnable.run() - start");
				}
				DefaultHttpClient httpclient = new DefaultHttpClient();
				HttpPost httppost = new HttpPost(SmpProperty.getInstance().getSendMessageUrl());
				List <NameValuePair> nvps = new ArrayList <NameValuePair>();
				
		        if("立即发送".equals(msg.getMsTimer())) {
		        	msg.setMsSendtime(new Timestamp(System.currentTimeMillis()));
				}
		        String state = "发送成功";
		        try {
		        	if(other.length()>0){
		        		//其它网关发送
		        		//添加签名【掌上校园】
		        		String sMsg = msg.getMsContent()+MsgUtil.QM_YYS;
			        	httpclient = new DefaultHttpClient();
			        	nvps.add(new BasicNameValuePair("id",SmpProperty.getInstance().getSendMessageId()));
						nvps.add(new BasicNameValuePair("MD5_td_code",SmpProperty.getInstance().getSendMessageMD5_td_code()));
						nvps.add(new BasicNameValuePair("mesg_id",String.valueOf(msg.getMsId())));
				        nvps.add(new BasicNameValuePair("mobile",other.toString()));
				        nvps.add(new BasicNameValuePair("msg_content", sMsg));
				        
				        if(Tools.isNotEmpty(msg.getMsShortno()))
				        	nvps.add(new BasicNameValuePair("extend", msg.getMsShortno()));
				        
						httppost = new HttpPost(SmpProperty.getInstance().getSendMessageUrl());
						httppost.setEntity(new UrlEncodedFormEntity(nvps, "GBK"));
						HttpResponse response = httpclient.execute(httppost);
						HttpEntity entity = response.getEntity();
						String entitys = EntityUtils.toString(entity, "GBK");
//						String entitys = "ok:3";
						if (logger.isDebugEnabled()) {
							logger.debug("entitys:"+entitys);
						}
						entitys = entitys.toLowerCase();
						int okIndex = entitys.indexOf("ok:");
						if(okIndex==-1){
							if(logger.isInfoEnabled())
								logger.info("其它:发送失败,状态码"+entitys+"用户数"+other.toString().split(",").length+":"+sMsg);
							state = "发送失败";
						}
						if(logger.isInfoEnabled()) {
							if(okIndex!=-1) {
								logger.info("其它:发送消息成功,用户数:"+other.toString().split(",").length+":"+sMsg);
								state="发送成功";
							}
						}
					}else if(yidong.length()>0){
						
					}
					
		        }
		        catch (UnsupportedEncodingException e) {
					logger.error("UnsupportedEncodingException", e);
					state = "发送失败";
				}
		        catch (ClientProtocolException e) {
					logger.error("ClientProtocolException", e);
					state = "发送失败";
				} 
				catch (IOException e) {
					logger.error("IOException", e);
					state = "发送失败";
				}
				
				if(yidong.length()>0){
					try {
						//移动  网关发送
				        nvps = new ArrayList <NameValuePair>();
				        nvps.add(new BasicNameValuePair("msgid",String.valueOf(msg.getMsId())));
				        nvps.add(new BasicNameValuePair("phone",yidong.toString()));
				        nvps.add(new BasicNameValuePair("msg", msg.getMsContent()));
				        if("长短信".equals(msg.getMsLongmsg())) {
				        	nvps.add(new BasicNameValuePair("longmsg","1"));
				        }else {
				        	nvps.add(new BasicNameValuePair("longmsg","0"));
				        }
				        if(Tools.isNotEmpty(msg.getMsShortno()))
				        	nvps.add(new BasicNameValuePair("sno", msg.getMsShortno()));
				        httppost = new HttpPost(SmpProperty.getInstance().getYidong());
				        httppost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
				        HttpResponse response = httpclient.execute(httppost);
				        HttpEntity entity = response.getEntity();
						String entitys = EntityUtils.toString(entity, "UTF-8");
//				        String entitys = "0";
						if("0".equals(entitys)){
							logger.info("移动:发送消息成功,用户数:"+yidong.toString().split(",").length+":"+msg.getMsContent());
							state="发送成功";		//标记发送状态
							if("回执确认".equals(msg.getMsType())) state = "接收回执";
						}else if("-1".equals(entitys)){
							logger.info("移动:发送消息失败,用户数"+yidong.toString().split(",").length+":"+msg.getMsContent());
							state = "发送失败";
						}else {
							logger.info("移动:短信服务器返回未知状态:<"+entitys+"> 用户数:"+yidong.toString().split(",").length+":"+msg.getMsContent());
							state = "未知状态";
						}
					}catch (UnsupportedEncodingException e) {
						logger.error("UnsupportedEncodingException", e);
						state = "发送失败";
					} 
			        catch (ClientProtocolException e) {
						logger.error("ClientProtocolException", e);
						state = "发送失败";
					} 
					catch (IOException e) {
						logger.error("IOException", e);
						state = "发送失败";
					}
				}
				
				msg.setMsState(state);
				if("定时发送".equals(msg.getMsTimer())) {
					ms.updateSubmitState(msgid, state,true,true,true);	//更新信息发送状态,包括信息详细 每条状态
				}
				if(isSaveLog)ms.addSubmit(msg, users,issavemsg);
				
				
				if (logger.isDebugEnabled()) {
					spendtime = System.currentTimeMillis()-spendtime;
					logger.debug("$MsgSenderRunnable.run() - end  spendtime:"+spendtime);
				}
			}
		}).start();
	}

	 /**发送短信通知,短信内容不能超过500字
	 * @param users 用户手机号和uid的集合,不能为空
	 * @param msgSubmit 发送的短信内容,不能为空。如果为普通短信msSendtime和msSendtime不用填写
	 */
	public void sendMsg(MsgSubmit msg, List<String[]> users,String sendtype) {
		List<String[]> vUser = new ArrayList<String[]>();
		StringBuffer phones = new StringBuffer();
		for(String[] user: users) {
			if(user.length!=2) {
				String[] eru = {user[0],"","手机号为空"};
				vUser.add(eru);
			}else {
				String pho = user[1];
				if(Tools.isEmpty(pho)||pho.length()!=11) {
					String[] eru = {user[0],user[1],"手机号格式错误"};
					vUser.add(eru);
				}else {
					//检查运营商
					//加入发送号码
					phones.append(",").append(user[1]);
					vUser.add(user);
				}
			}
		}
		//去除第一个手机号前的逗号
		if(phones.length()>0)phones.deleteCharAt(0);
		
		if(phones.length()==0) {
			msg.setMsState("发送失败");
			ms.addSubmit(msg, vUser,true);
		}else {
			
			//超时后修改发送状态为 "调查结束"
			if(msg.getMsOvertime()!=null) {
				final OverMsgTask overTask = new OverMsgTask(msg, ms);
				msgTimer.schedule(overTask, msg.getMsOvertime());
			}
			
			if("定时发送".equals(msg.getMsTimer())) {
				msg.setMsState("未发送");
				String ct = msg.getMsContent();
				ms.addSubmit(msg, vUser,true);
				msg.setMsContent(ct);
				final SendMsgTask msgTask = new SendMsgTask(msg, vUser, phones.toString(), this);
				msgTimer.schedule(msgTask , msg.getMsSendtime());
			}else {
				if("resend".equals(sendtype)){	//如果是重新发送,则不进行记录
					sendLongMsg(msg, vUser, phones.toString(), false);
				}else{
					sendLongMsg(msg, vUser, phones.toString(), true);
				}
			}
		}
	}
	
	public void sendMsgFromServer(MsgSubmit msg, List<String[]> users,String sendtype) {
		List<String[]> vUser = new ArrayList<String[]>();
		StringBuffer phones = new StringBuffer();
		for(String[] user: users) {
			if(user.length!=2) {
				String[] eru = {user[0],"","手机号为空"};
				vUser.add(eru);
			}else {
				String pho = user[1];
				if(Tools.isEmpty(pho)||pho.length()!=11) {
					String[] eru = {user[0],user[1],"手机号格式错误"};
					vUser.add(eru);
				}else {
					//检查运营商
					//加入发送号码
					phones.append(",").append(user[1]);
					vUser.add(user);
				}
			}
		}
		//去除第一个手机号前的逗号
		if(phones.length()>0)phones.deleteCharAt(0);
		
		if(phones.length()==0) {
			msg.setMsState("发送失败");
			ms.addSubmit(msg, vUser,true);
		}else {
			
			if("定时发送".equals(msg.getMsTimer())) {
				final SendMsgTask msgTask = new SendMsgTask(msg, vUser, phones.toString(), this);
				msgTimer.schedule(msgTask , msg.getMsSendtime());
			}else {
				if("resend".equals(sendtype)){	//如果是重新发送,则不进行记录
					sendLongMsg(msg, vUser, phones.toString(), false);
				}else{
					sendLongMsg(msg, vUser, phones.toString(), true);
				}
			}
		}
	}
	
	class SendMsgTask extends TimerTask {
		private MsgSubmit msg;
		private List<String[]> users;
		String phones;
		private MsgSender sender;
		SendMsgTask(MsgSubmit msg, final List<String[]> users, String phones, MsgSender sender) {
			this.msg = msg;
			this.users = users;
			this.sender = sender;
			this.phones = phones;
		}
		@Override
		public void run() {
			this.sender.sendLongMsg(msg, users, phones, false);
		}
	}
	class OverMsgTask extends TimerTask {
		private MsgSubmit msg;
		private MsgService ms;
		OverMsgTask(MsgSubmit msg, MsgService ms) {
			this.msg = msg;
			this.ms = ms;
		}
		@Override
		public void run() {
			//修改MsgSubmit的state为调查结束 
			ms.updateSubmitState(msg.getMsId(), "调查结束");
		}
	}
	
	private void sendLongMsg(MsgSubmit msg, List<String[]> users, String phones, boolean isSaveLog) {
		//首先保存msg信息    然后发送信息,如果超过100条,则进行分隔100发送,
		if("立即发送".equals(msg.getMsTimer())) {
        	msg.setMsSendtime(new Timestamp(System.currentTimeMillis()));
		}
//		if("定时发送".equals(msg.getMsTimer())) {
//			ms.updateSubmitState(msgid, "发送成功");
//		}
		if(isSaveLog){
			msg.setMsState("发送成功");
			String ct = msg.getMsContent();
			ms.addSub(msg);
			msg.setMsContent(ct);
		}
		
		
		//百悟网关自动判断是否使用长短信发送, 字数不能超过500字
		//判断人数是否超过100,如果超过100条则,分次数发完。
		int count=users.size();
		
		int maxsize=90;
		
		if (count <= maxsize) {
			logger.debug("第" + 1 + "次/共 1 次发送...");
			System.out.println("第" + 1 + "次/共 1 次发送...");
			send(msg, users, phones, isSaveLog,false);
		} else {
			for (int i = 0; i < count / maxsize; i++) {
				logger.debug("第" + (i + 1) + "次发送...");
				System.out.println("第" + (i + 1) + "次发送...");
				List myusers=users.subList(i * maxsize, (i + 1) * maxsize);
				logger.debug("用户数:"+myusers.size());
				send(msg, myusers, phones, isSaveLog,false);
				try {
					Thread.sleep (500);				//发送程序暂停1秒
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			if (count % maxsize != 0) {
				logger.debug("第" + (count / maxsize + 1) + "次发送...");
				System.out.println("第" + (count / maxsize + 1) + "次发送...");
				List myusers=users.subList((count - count % maxsize), users.size());
				logger.debug("用户数:"+myusers.size());
				send(msg, myusers, phones, isSaveLog,false);
			}
		}
		/*if(msg.getMsContent().length()<192) {
			send(msg, users, isSaveLog);
		}else {
//TODO 此处设计有问题,当字数多时,只要全部发送成功才算成功。
			while(true) {
				String message = msg.getMsContent();
				if(message.length()>192) {
					String str = message.substring(0, 192);
					msg.setMsContent(str);
					send(msg, users, isSaveLog);
					message = message.substring(192);
				}else {
					send(msg, users, isSaveLog);
					break;
				}
			}
		}*/
	}
}

分享到:
评论
1 楼 Chinesejunbo 2012-05-22  
你好,你这里面的东西很实用,我现在继续这方面的代码,可否将代码中引用的其他包发给我可以吗?先谢谢了啊! QQ:1072173141

相关推荐

    短信发送模块制作

    在IT行业中,短信发送模块是通信系统中的一个重要组成部分,它主要负责通过串行接口(Serial Port)发送短信。本文将详细讲解如何制作一个短信发送模块,包括串口短信的发送指令、格式、编解码类型以及参数设置等...

    泛微e-office短信插件_泛微短信接口开发_e-office短信发送设置

    在泛微e-office V10.0版本中,设置短信发送功能需要通过泛微短信接口进行开发。下面将详细介绍泛微e-office短信插件的设置步骤和泛微短信接口的开发过程。 一、泛微e-office短信插件设置 泛微e-office短信插件是...

    中国电信SMGP协议短信发送

    本主题主要探讨的是如何使用Java来实现SMGP协议进行短信发送,以及相关的开发资源。 首先,`zjtelecom-1.0.jar`是一个Java库文件,它包含了实现SMGP协议所需的各种类和方法。这个库可能包含了对SMGP报文构造、解析...

    最新版匿名短信发送系统源码 匿名信卡密版本源码可对接代刷或社区卖卡.zip

    匿名短信发送源码,成本0.1一条65字源码限制了120字最大,卡密版本,可自己后台生成卡密 可自己对接代刷或者社区卖卡!表白祝福啥的 1.系统环境 -php要求 5.6 过高部分函数会失效无法使用 -mysql 无要求,数据库...

    实用的asp短信发送代码.rar

    在本压缩包“实用的asp短信发送代码.rar”中,包含的是一个基于ASP的短信发送接口程序,适用于开发者集成到自己的Web系统中,以便实现短信通知、验证等功能。以下是对这个短信发送代码的知识点详细解释: 1. ASP...

    FastAdmin短信插件_FastAdmin短信接口开发_FastAdmin短信发送设置

    本文将深入探讨“FastAdmin短信插件”、“FastAdmin短信接口开发”以及“FastAdmin短信发送设置”这三个核心知识点。 1. FastAdmin短信插件: FastAdmin的短信插件是用于实现系统与用户之间通过短信进行交互的重要...

    U3D调动短信发送功能

    在Unity3D游戏开发中,有时需要集成短信发送功能,以实现用户验证、通知推送等服务。"U3D调动短信发送功能"是指在Unity3D项目中集成并调用短信SDK来实现实时发送短信的功能。这个压缩包"SMSSDK-for-Unity3D-master...

    简单的安卓短信发送程序

    【Android短信发送程序详解】 在Android开发中,创建一个简单的短信发送程序是常见的实践,尤其对于初学者来说,这是理解Android系统服务和权限管理的重要环节。这个程序的实现基于老师的指导,通过实际操作并测试...

    阿里云/腾讯云短信发送(C#版)

    阿里云和腾讯云短信发送服务是企业级应用中常见的通讯工具,主要用于验证码、通知消息以及营销推广等场景。本文将详细讲解如何使用C#语言在.NET 4.5框架下集成这两个云服务进行短信发送。 首先,我们需要了解阿里云...

    Android 实现发短信 监听短信发送状态

    在Android平台上,开发人员可以利用系统的短信服务API来实现发送短信以及监听短信发送的状态。这一功能对于构建一些需要确认信息传递的应用,如验证码发送、通知提醒等,是至关重要的。以下将详细介绍如何在Android...

    免费发送短信(无需登陆)

    而“中文短信免费发1.2”则表明有专门针对中文短信发送的软件版本。 在这个专题下,可以涵盖的知识点包括: 1. **免费短信服务的工作原理**:解释这些服务如何通过广告支持、合作推广或者其他商业模式来维持运营,...

    【Android】短信发送

    在Android平台上,短信发送是移动应用开发中常见的一项功能,特别是在构建通信或通知类应用时。这个【Android】短信发送的示例(Demo)旨在帮助开发者理解如何在Android应用程序中集成短信发送的功能。通过分析提供...

    基于Java封装短信协议CMPP/SGIP/SMGP/SMPP的http接口短信发送设计源码

    该项目为Java语言编写的短信发送解决方案,采用CMPP、SGIP、SMGP、SMPP等多种短信协议进行封装,通过提供简单的HTTP接口,实现短信的快速发送。项目包含512个Java源文件,2个XML配置文件,以及1个Git忽略文件、1个...

    短信发送sdk包

    【短信发送SDK包】是一种专为开发者设计的软件开发工具包,它允许应用程序轻松地集成短信发送功能。SDK(Software Development Kit)通常包含了一系列API(Application Programming Interface)、文档、示例代码、库...

    短信发送界面,非常漂亮的

    当我们谈论"短信发送界面,非常漂亮的"时,这显然涉及到一个应用或系统中用于发送短信的功能模块,而且该模块在视觉设计上具有较高的美学价值。在C#编程语言中,我们可以利用.NET Framework或更现代的.NET Core平台...

    java 短信发送程序

    Java 短信发送程序是一种基于Java编程语言开发的应用,用于向移动设备发送文本消息。在信息技术领域,这种程序常用于验证码验证、通知服务、营销推广等场景。本篇文章将详细探讨Java实现短信发送功能的核心技术和...

    短信发送demo

    【短信发送Demo】是一个专为Android开发者设计的实践项目,旨在教授如何在Android实体设备上实现短信发送功能。这个Demo工程包含了一系列的代码示例和配置文件,帮助开发者理解和掌握Android系统中的短信发送机制。...

    用java实现的短信发送

    Java 实现短信发送 Java 实现短信发送是指利用 Java 语言编写程序来实现服务器向手机发送短信的过程。在这里,我们将使用 Java 语言来实现这个功能,并且使用了 Apache 的 Commons HttpClient 库来发送 HTTP 请求。...

    Node.js-阿里云短信发送接口nodejs版本

    在本文中,我们将深入探讨如何使用Node.js与阿里云短信服务接口进行集成,以便实现高效、可靠的短信发送功能。阿里云短信服务是一个强大的云通信平台,提供了多种API和SDK,帮助开发者快速构建短信发送功能。在Node....

Global site tag (gtag.js) - Google Analytics