import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.HttpVersion;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.log4j.Logger;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import sun.misc.BASE64Decoder;
/**
* 短信箱实现发短信功能
*<p>Title:NoteBoxSendNote.java</p>
*<p>Description:</p>
*<p>Copyright:Copyright (c) 2014</p>
*<p>Company:湖南科创</p>
*@author pingan.liu
*@version 1.0
*Feb 8, 2014
*/
public class NoteBoxSendNote implements SendNote{
private HttpClient client = null;
private PostMethod method = null;
private static final Logger LOG = Logger.getLogger(NoteBoxSendNote.class);
private String post_url = "";//请求的URL地址
private String username = "";//信箱用户名
private String password="";//信箱用户密码
private String corpcode="";//信箱号
private String box_send_max_num="1";//最大发送数
HostConfiguration hcf = null;
public NoteBoxSendNote(){
}
@Override
public void afterSend() {
}
@Override
public void beforeSend() throws Exception {
}
@Override
public void init() {
client = new HttpClient(new MultiThreadedHttpConnectionManager() );
//设置代理开始
if(StringUtil.isBlank(CacheCommonManageProxy.getSystemParam("box_proxy_ip"))){//如果代理ip不为空
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(CacheCommonManageProxy.getSystemParam("box_proxy_username"),CacheCommonManageProxy.getSystemParam("box_proxy_password"));
client.getState().setProxyCredentials(AuthScope.ANY, creds);
this.hcf = new HostConfiguration();
try{
this.hcf.setProxy(CacheCommonManageProxy.getSystemParam("box_proxy_ip"), Integer.valueOf(CacheCommonManageProxy.getSystemParam("box_proxy_port")));
} catch(NumberFormatException e){
LOG.error("代理端口号非法"+e.getMessage(), e);
}
}
//设置代理结束
client.getHttpConnectionManager().getParams().setConnectionTimeout(20000);//设置超时毫秒数
client.getParams().setParameter("content_charset", "UTF-8");//设置编码
client.getParams().setParameter("content-type", "application/x-www-form-urlencoded;charset=UTF-8");//设置响应类型
client.getParams().setParameter("content-encoding", "UTF-8");//设置编码
client.getParams().setParameter("content-encoding", "UTF-8");//设置编码
client.getParams().setParameter("version", HttpVersion.HTTP_1_1);//设置版本为1.1
this.post_url= CacheCommonManageProxy.getSystemParam("post_url");//短信箱请求的URL
this.username= CacheCommonManageProxy.getSystemParam("box_username");//短信箱用户名
this.password= CacheCommonManageProxy.getSystemParam("box_password");//短信箱用户密码
this.corpcode= CacheCommonManageProxy.getSystemParam("box_corpcode");//短信箱号
this.box_send_max_num= CacheCommonManageProxy.getSystemParam("box_send_max_num");//最大发送数 //this.username= CacheCommonManage.getInstance().getSystemParam("box_username");
//main方法测试
this.post_url="";//短信箱请求的URL
this.username= "";//短信箱用户名
this.password= "";//短信箱用户密码
this.corpcode= "";//短信箱号
this.box_send_max_num= "3";//最大发送数
}
/**
*
* <b>Summary: </b>
* 复写方法 sending
* @throws Exception
* @see com.chinacreator.xtbg.anyang.notebox.note.SendNote#sending()
*/
@Override
public void sending() throws Exception{
NoteBoxSendService service = new NoteBoxSendServiceImpl();//获得待发送短信的service
NoteBoxSendBean search_bean = new NoteBoxSendBean();
List<NoteBoxSendBean> result_list = new ArrayList<NoteBoxSendBean>();//发送成功list
int i =0;//用记录第几条出错误了
List<NoteBoxSendBean> send_task_list = service.list(search_bean, this.box_send_max_num);//获得待发送的短信
NoteBoxSendBean bean = null;//
try {
for(;i<send_task_list.size();i++){//一条一条的群发短信
bean = send_task_list.get(i);//获得发送的短信实体Bean
//获得加密之后的xml文档
String pocketXml = this.getEncodeBase64(this.CreateSendPuk(this.username, this.password, this.corpcode, bean.getBox_message_content(), bean.getPhone_nums()));
int statusCode = -1;
method = new PostMethod(post_url);//post方法请求连接
//设置要传送的参数
RequestEntity requestEntity = new StringRequestEntity(pocketXml);
method.setRequestEntity(requestEntity);
if(hcf != null){//如果代理为空
statusCode = client.executeMethod(hcf,method);
} else {
statusCode = client.executeMethod(method);
}
if(statusCode != HttpStatus.SC_OK){
System.out.println("远程访问失败!");
bean.setStatus(NoteConstant.FAIL);
bean.setFailure_reason("远程访问失败");//失败原因
result_list.add(bean);//添加发送失败的记录
break;//远程范围失败,退出发送短信
} else {
String result = method.getResponseBodyAsString();//获得响应的结果
method.releaseConnection();
result = this.getDecodeBase64(result);//进行转码
System.out.println("+++++++++++++++++>>>>>>"+result);
if(StringUtil.isBlank(result)){//判断是否有返回
System.out.println("返回错误!");
bean.setFailure_reason("返回结果为null");
return ;
}
org.dom4j.Document doc = DocumentHelper.parseText(result);//转换为 document对象
//如果返回值不是xml格式的,表示传送的对象有问题
if(doc == null){
String temp_result = this.getDecodeBase64(result);
bean.setStatus(NoteConstant.FAIL);
bean.setFailure_reason(temp_result);
result_list.add(bean);//添加发送失败的记录
throw new Exception("数据格式不正确,返回值为("+temp_result+")");
}
org.dom4j.Element root = doc.getRootElement();//获得根元素
if(root == null){
bean.setStatus(NoteConstant.FAIL);
bean.setFailure_reason("短信根节点不存在!");
result_list.add(bean);//添加发送失败的记录
throw new Exception("短信根节点不存在!");
}
if(root.element("SMS") == null){
bean.setStatus(NoteConstant.FAIL);
bean.setFailure_reason("短信MMS节点不存在!");
result_list.add(bean);//添加发送失败的记录
throw new Exception("短信MMS节点不存在!");
}
if(root.element("SMS").element("Return") == null){
bean.setStatus(NoteConstant.FAIL);
bean.setFailure_reason("短信Return节点不存在!");
result_list.add(bean);//添加发送失败的记录
throw new Exception("短信Return节点不存在!");
}
org.dom4j.Element rtn = root.element("SMS").element("Return");
if(rtn.attributeValue("State").equals(NoteConstant.OK)){//发送成功
bean.setStatus(NoteConstant.OK);
result_list.add(bean);//添加发送成功的记录
} else if(rtn.attributeValue("State").equals(NoteConstant.FAIL)){//发送失败
bean.setStatus(NoteConstant.FAIL);
bean.setFailure_reason(this.getDecodeBase64(rtn.getText()));
result_list.add(bean);//添加发送失败的记录
} else if(rtn.attributeValue("State").equals(NoteConstant.USER_NAME_OR_PASSWORD_ERROR)){//用户名或者密码错误
bean.setStatus(NoteConstant.FAIL);
bean.setFailure_reason(this.getDecodeBase64(rtn.getText()));
result_list.add(bean);//添加发送失败的记录
throw new Exception("短信信箱用户名或者密码错误!");
}
System.out.println("=========state="+rtn.attributeValue("State"));
System.out.println("===========text = "+this.getDecodeBase64(rtn.getText()));
}
System.out.println(method.getStatusCode());
System.out.println(method.getResponseBodyAsString());
}
} catch (HttpException e) {
LOG.error("短信网络连接超时:"+e.getMessage(), e);
bean.setStatus(NoteConstant.FAIL);
bean.setFailure_reason("短信网络连接超时");
result_list.add(bean);//添加发送失败的记录
} catch (IOException e) {
LOG.error("短信IO错误:"+e.getMessage(), e);
bean.setStatus(NoteConstant.FAIL);
bean.setFailure_reason("短信IO错误");
result_list.add(bean);//添加发送失败的记录
} catch (DocumentException e) {
LOG.error("短信返回信息转换为Document对象错误:"+e.getMessage(), e);
bean.setStatus(NoteConstant.FAIL);
bean.setFailure_reason("短信返回信息转换为Document对象错误");
result_list.add(bean);//添加发送失败的记录
} catch (Exception e) {
LOG.error("生成短信数据包失败:"+e.getMessage(), e);
bean.setStatus(NoteConstant.FAIL);
bean.setFailure_reason("生成短信数据包失败");
result_list.add(bean);//添加发送失败的记录
} finally{
//((SimpleHttpConnectionManager)client.getHttpConnectionManager()).closeIdleConnections(0);//将idleTimeout设为0可以确保链接被关闭
((MultiThreadedHttpConnectionManager)client.getHttpConnectionManager()).shutdownAll();//关闭所有连接
//如果网络连接失败,更新短信箱表的数据,改变状态为未发送
int j =i;
//添加发送失败的记录s
for(;j<send_task_list.size();j++){
NoteBoxSendBean temp_bean = send_task_list.get(j);
temp_bean.setStatus(NoteConstant.FAIL);
result_list.add(temp_bean);//添加发送失败的记录
}
for(int k=0;k<result_list.size();k++){
service.updateSendStatus(result_list.get(k));//更新发送之后的结果,不管是失败还是成功
}
//method.abort();
}
}
/// <summary>
/// 生成发送数据包
/// </summary>
/// <param name="UserName">用户名</param>
/// <param name="PWD">密码</param>
/// <param name="CorpCode">信箱号</param>
/// <param name="Message">待发送的消息体</param>
/// <param name="Dest">发送的目标号码</param>
/// <returns>生成的发送数据包</returns>
/**
*
*<b>Summary: </b>
* CreateSendPuk(创建发送的xml文件)
* @param userName
* @param PWD
* @param corpCode
* @param message
* @param dest
* @return
* @throws Exception
*/
private String CreateSendPuk(String userName, String PWD,
String corpCode, String message, String dest) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();//
Element root = null;
// 写根节点
root = doc.createElement("Root");
doc.appendChild(root);// 添加根节点
root.setAttribute("version", "2.0");// 设置属性值
root.setAttribute("User", userName);// 设置属性值
root.setAttribute("PWD", PWD);// 设置属性值
root.setAttribute("UserType", "8");// 设置属性值
root.setAttribute("CorpCode", corpCode);// 设置属性值
Element sms = doc.createElement("SMS");
root.appendChild(sms);
Element m = doc.createElement("M");
m.setTextContent(this.getEncodeBase64(new String(message.getBytes("UTF-8"),"GBK")));// 设置内容并把内容进行转码,并进行Base64的转码
sms.appendChild(m);
Element h = doc.createElement("H");
h.setAttribute("M", dest);// 发送的号码
sms.appendChild(h);
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
transformer.setOutputProperty("encoding","UTF-8");//设置成UTF-8的编码格式
DOMSource source = new DOMSource(doc);
StringWriter out = new StringWriter();
// ByteArrayOutputStream bos = new ByteArrayOutputStream();
StreamResult result = new StreamResult(out);
// StreamResult result = new StreamResult(bos);
transformer.transform(source, result);
out.flush();
out.close();
// bos.close();
System.out.println("##################################@@@"+out.toString());
return out.toString();
// return bos.toString("UTF-8");
}
/// <summary>
/// 生成发送数据包
/// </summary>
/// <param name="UserName">用户名</param>
/// <param name="PWD">密码</param>
/// <param name="CorpCode">信箱号</param>
/// <param name="Message">待发送的消息体</param>
/// <param name="Dest">发送的目标号码</param>
/// <returns>生成的发送数据包</returns>
/**
*
*<b>Summary: </b>
* CreateSendPuk2(创建发送的xml文件)
* @param userName
* @param PWD
* @param corpCode
* @param message
* @param dest
* @return
* @throws Exception
*/
private String CreateSendPuk2(String userName, String PWD,
String corpCode, String message, String dest) throws Exception {
//StringBuilder pokcetXML = new StringBuilder();
org.dom4j.Document doc = org.dom4j.DocumentHelper.createDocument(); //创建文档
org.dom4j.Element root = null;
// 写根节点
root = doc.addElement("Root");// 添加根节点
root.addAttribute("version", "2.0");// 设置属性值
root.addAttribute("User", userName);// 设置属性值
root.addAttribute("PWD", PWD);// 设置属性值
root.addAttribute("UserType", "8");// 设置属性值
root.addAttribute("CorpCode", corpCode);// 设置属性值
org.dom4j.Element sms = root.addElement("SMS");
org.dom4j.Element m = sms.addElement("M");
m.setText(this.getEncodeBase64(message));// 设置内容,并进行Base64的转码
org.dom4j.Element h = sms.addElement("H");
h.addAttribute("M", dest);// 发送的号码
System.out.println(doc.asXML());
return doc.toString();
}
/**
* 进行Base64的加密 base64 encode arithmetic
*
* @param s
* @return
* @throws UnsupportedEncodingException
*/
public String getEncodeBase64(String s) throws UnsupportedEncodingException {
if (s == null)
return null;
return (new sun.misc.BASE64Encoder()).encode(s.getBytes());
}
/**
* 进行Base64的解密 base64 decode arithmetic
*
* @param s
* @return
*/
public String getDecodeBase64(String s) {
if (s == null)
return null;
BASE64Decoder decoder = new BASE64Decoder();
try {
byte[] b = decoder.decodeBuffer(s);
return new String(b,"UTF-8");
} catch (Exception e) {
return null;
}
}
public static void main(String[] args) throws Exception{
// String decode = "鏁版嵁鍖呮牸寮忎笉姝g‘";
// String decode="绌虹殑璇锋眰銆?";
// String r = new String(decode.getBytes(),"UTF-8");
// System.out.println(r);
System.out.println("*******************************************"+System.setProperty("file.encoding", "UTF-8"));
System.out.println("com.chinacreator.xtbg.anyang.notebox.note.impl.NoteBoxSendNote[短信箱发送短信开始]");
NoteBoxSendNote sendNote = new NoteBoxSendNote();
//sendNote.CreateSendPuk2("userName", "PWD", "corpCode", "message", "dest");
// String result = sendNote.getEncodeBase64("<?xml version=\"1.0\" encoding=\"utf-8\"?><Root><MMS><Return State=\"0\">"+sendNote.getEncodeBase64("提交成功")+"</Return></MMS></Root>");
// System.out.println(result);
sendNote.init(); //发短信初始化
try {
sendNote.beforeSend(); //发短信前操作
sendNote.sending(); //发短信操作
} catch (Exception e) {
LOG.error(e.getMessage(),e);
System.out.println("com.chinacreator.xtbg.anyang.notebox.note.impl.NoteBoxSendNote[短信箱发送短信异常]");
//System.setProperty("file.encoding", "GBK");
}
sendNote.afterSend(); //发短信后操作
System.out.println("com.chinacreator.xtbg.anyang.notebox.note.impl.NoteBoxSendNote[短信箱发送短信结束]");
System.setProperty("file.encoding", "GBK");
//编码测试
// System.out.println(sendNote.getEncodeBase64("短信功能测试---222222221111111"));
// System.out.println(sendNote.getEncodeBase64(new String("短信功能测试---222222221111111".getBytes("UTF-8"),"GBK")));
// System.out.println(new String(sendNote.getDecodeBase64("56eR5Yib55+t5L+h5Yqf6IO95rWL6K+VLS0tMjIyMjIyMjIxMTExMTEx").getBytes("GBK"),"UTF-8"));
// 56eR5Yib55+t5L+h5Yqf6IO95rWL6K+VLS0tMjIyMjIyMjIxMTExMTEx
}
}