`
liufei.fir
  • 浏览: 678571 次
  • 性别: 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

相关推荐

Global site tag (gtag.js) - Google Analytics