fuxubing 3 年 前
コミット
2b8aaa164d

+ 25 - 0
jz-crm-admin-api/src/main/java/org/linlinjava/jz/admin/web/AdminSmsController.java

@@ -0,0 +1,25 @@
+package org.linlinjava.jz.admin.web;
+
+import io.swagger.annotations.Api;
+import org.apache.commons.httpclient.URIException;
+import org.linlinjava.jz.core.util.ResponseUtil;
+import org.linlinjava.jz.core.util.sms.HttpJsonExample;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author fuxubing
+ */
+@Api(value = "Admin-Skill-Group-Controller", description = "技能组维护")
+@RestController
+@RequestMapping("/admin/sms")
+@Validated
+public class AdminSmsController {
+
+    @GetMapping("/send")
+    public Object list() throws URIException {
+        return ResponseUtil.ok(HttpJsonExample.send());
+    }
+}

+ 6 - 0
jz-crm-core/pom.xml

@@ -125,6 +125,12 @@
 			<artifactId>jz-crm-db</artifactId>
 		</dependency>
 
+		<dependency>
+			<groupId>commons-httpclient</groupId>
+			<artifactId>commons-httpclient</artifactId>
+			<version>3.1</version>
+		</dependency>
+
 
 	</dependencies>
 

+ 31 - 0
jz-crm-core/src/main/java/org/linlinjava/jz/core/util/sms/EncryptUtil.java

@@ -0,0 +1,31 @@
+package org.linlinjava.jz.core.util.sms;
+
+import java.security.MessageDigest;
+
+/**
+ * @author Designer
+ */
+public class EncryptUtil {
+	public static String MD5Encode(String sourceString) {
+		String resultString = null;
+		try {
+			resultString = new String(sourceString);
+			MessageDigest md = MessageDigest.getInstance("MD5");
+			resultString = byte2hexString(md.digest(resultString.getBytes()));
+		} catch (Exception localException) {
+		}
+		return resultString;
+	}
+
+	private static final String byte2hexString(byte[] bytes) {
+		StringBuffer bf = new StringBuffer(bytes.length * 2);
+		for (int i = 0; i < bytes.length; i++) {
+			if ((bytes[i] & 0xFF) < 16) {
+				bf.append("0");
+			}
+			bf.append(Long.toString(bytes[i] & 0xFF, 16));
+		}
+		return bf.toString();
+	}
+
+}

+ 45 - 0
jz-crm-core/src/main/java/org/linlinjava/jz/core/util/sms/HttpJsonExample.java

@@ -0,0 +1,45 @@
+package org.linlinjava.jz.core.util.sms;
+
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.linlinjava.jz.core.util.sms.json.JSONHttpClient;
+
+import java.util.*;
+
+public class HttpJsonExample {
+    private static final Log LOG = LogFactory.getLog(HttpJsonExample.class);
+    private static String account = "dh44209";        // 用户名(必填)
+    private static String password = "e8eO481E";        // 密码(必填)
+    private static String phone = "15294264365";    // 手机号码(必填,多条以英文逗号隔开,国际短信要+国别号)
+    private static String a = "鲸致商城";
+    private static String content = "您申请的保姆查询结果已出,请访问 https://uat.jzlives.cn/bjdc 获取详细信息,如有疑问,请拨打400-920-8718";        // 短信内容(必填)
+    public static String sign = "【鲸致商城】";        // 短信签名(必填,格式如【大汉三通】)
+    public static String subcode = "786271";        // 子号码(选填)
+    public static String msgid = UUID.randomUUID().toString().replace("-", "");    // 短信id,(可选,不传我们生成一个返回)
+    public static String sendtime = null;    // 定时发送时间(可选)
+    public static Map<String, Object> template = new HashMap<>();
+
+    public static String send() {
+        String sendhRes = "";
+        try {
+            JSONHttpClient jsonHttpClient = new JSONHttpClient("http://www.dh3t.com");
+            jsonHttpClient.setRetryCount(1);
+            Map<String, Object> map = new HashMap<>();
+            map.put("id", "2c90888973c3585f0174488b75a32346");
+            List<Map<String, String>> mlist = new ArrayList<>();
+            Map<String, String> m = new HashMap<>();
+            m.put("name", "1");
+            m.put("value", "100000");
+            mlist.add(m);
+            map.put("variables", mlist);
+            template = map;
+            System.out.println(template);
+            sendhRes = jsonHttpClient.sendSms(account, password, phone, template, sign, subcode);
+        } catch (Exception e) {
+            LOG.error("应用异常", e);
+        }
+
+        return sendhRes;
+    }
+}

+ 110 - 0
jz-crm-core/src/main/java/org/linlinjava/jz/core/util/sms/MySecureProtocolSocketFactory.java

@@ -0,0 +1,110 @@
+package org.linlinjava.jz.core.util.sms;
+
+import org.apache.commons.httpclient.ConnectTimeoutException;
+import org.apache.commons.httpclient.HttpClientError;
+import org.apache.commons.httpclient.params.HttpConnectionParams;
+import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory;
+import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
+import org.springframework.stereotype.Service;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+/**
+ * @author Designer
+ */
+@Service
+public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory {
+
+	private SSLContext sslContext = null;
+
+	/**
+	 * Constructor for MySecureProtocolSocketFactory.
+	 */
+	public MySecureProtocolSocketFactory() {
+	}
+
+	/**
+	 * @return
+	 */
+	private static SSLContext createEasySSLContext() {
+		try {
+			SSLContext context = SSLContext.getInstance("SSL");
+			context.init(null, new TrustManager[] { new MyX509TrustManager() }, null);
+			return context;
+		} catch (Exception e) {
+			throw new HttpClientError(e.toString());
+		}
+	}
+
+	/**
+	 * @return
+	 */
+	private SSLContext getSSLContext() {
+		if (this.sslContext == null) {
+			this.sslContext = createEasySSLContext();
+		}
+		return this.sslContext;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket
+	 * (java.lang.String, int, java.net.InetAddress, int)
+	 */
+	@Override
+	public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException, UnknownHostException {
+
+		return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket
+	 * (java.lang.String, int, java.net.InetAddress, int,
+	 * org.apache.commons.httpclient.params.HttpConnectionParams)
+	 */
+	@Override
+	public Socket createSocket(final String host, final int port, final InetAddress localAddress, final int localPort, final HttpConnectionParams params)
+			throws IOException, UnknownHostException, ConnectTimeoutException {
+		if (params == null) {
+			throw new IllegalArgumentException("Parameters may not be null");
+		}
+		int timeout = params.getConnectionTimeout();
+		if (timeout == 0) {
+			return createSocket(host, port, localAddress, localPort);
+		} else {
+			return ControllerThreadSocketFactory.createSocket(this, host, port, localAddress, localPort, timeout);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
+	 */
+	@Override
+	public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
+		return getSSLContext().getSocketFactory().createSocket(host, port);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String
+	 * ,int,boolean)
+	 */
+	@Override
+	public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
+		return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
+	}
+}

+ 43 - 0
jz-crm-core/src/main/java/org/linlinjava/jz/core/util/sms/MyX509TrustManager.java

@@ -0,0 +1,43 @@
+package org.linlinjava.jz.core.util.sms;
+
+import javax.net.ssl.X509TrustManager;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+public class MyX509TrustManager implements X509TrustManager {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.
+	 * X509Certificate[], java.lang.String)
+	 */
+	@Override
+	public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.
+	 * X509Certificate[], java.lang.String)
+	 */
+	@Override
+	public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
+	 */
+	@Override
+	public X509Certificate[] getAcceptedIssuers() {
+		return null;
+	}
+
+}

+ 356 - 0
jz-crm-core/src/main/java/org/linlinjava/jz/core/util/sms/json/JSONHttpClient.java

@@ -0,0 +1,356 @@
+package org.linlinjava.jz.core.util.sms.json;
+
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.commons.httpclient.*;
+import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.RequestEntity;
+import org.apache.commons.httpclient.params.HttpClientParams;
+import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
+import org.apache.commons.httpclient.params.HttpMethodParams;
+import org.apache.commons.httpclient.protocol.Protocol;
+import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.HttpStatus;
+import org.apache.http.conn.ConnectTimeoutException;
+import org.linlinjava.jz.core.util.sms.EncryptUtil;
+import org.linlinjava.jz.core.util.sms.MySecureProtocolSocketFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.ConnectException;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class JSONHttpClient {
+    private static final Log LOG = LogFactory.getLog(JSONHttpClient.class);
+    private static final AtomicBoolean isSwitch = new AtomicBoolean(false);
+    private static final String SEND_URL = "/json/sms/Submit";
+    private static final String GET_REPORT_URL = "/json/sms/Report";
+    private static final String DELIVER_URL = "/json/sms/Deliver";
+    private static final String BATCH_SEND_URL = "/json/sms/BatchSubmit";
+    private static final String BALANCE_URL = "/json/sms/Balance";
+    private static final String DEFAULT_RESPONSE = "{\"response\":{result:\"21\",desc:\"数据包/短信内容为空\"}}";
+    private int conTimeOut = 30000;
+    private int readTimeOut = 30000;
+    private int retryCount = 3;
+    private String masterUrl = "";
+    private String slaveUrl = "";
+    boolean isHttps = false;
+
+    public JSONHttpClient(String masterURL) throws URIException {
+        this(masterURL, null);
+    }
+
+    public JSONHttpClient(String masterURL, String slaveURL) throws URIException {
+        masterUrl = getSchemaHost(masterURL);
+        if (masterUrl == null || "".equals(masterUrl.trim())) {
+            throw new URIException("master URL 地址必须输入");
+        }
+        slaveUrl = getSchemaHost(slaveURL);
+    }
+
+    private String getSchemaHost(String host) {
+
+        if (host != null) {
+            if (host.indexOf("http://") != -1) {
+                return host;
+            } else if (host.indexOf("https://") != -1) {
+                this.isHttps = true;
+                return host;
+            } else {
+                return "http://" + host;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 发送短信
+     *
+     * @param account  帐号(必填)
+     * @param password 密码 (必填)
+     * @param msgid    msgId(可选,长度最长32位)
+     * @param phones   手机号码(必填)
+     * @param content  发送内容(长度最长1000)
+     * @param sign     短信签名(必填)
+     * @param subcode  子号码(必填,大汉提供子号码+(用户扩展码,可选))
+     * @param sendtime 定时发送时间(可选,格式:yyyyMMddHHmmss)
+     */
+    public String sendSms(String account, String password, String phones, String content, String sign, String subcode, String msgid, String sendtime) {
+        JSONObject param = new JSONObject();
+        param.put("account", account);
+        param.put("password", EncryptUtil.MD5Encode(password));
+        param.put("msgid", msgid);
+        param.put("phones", phones);
+        param.put("template", content);
+        param.put("sign", sign);
+        param.put("subcode", subcode);
+        param.put("sendtime", sendtime);
+        String requestData = param.toString();
+        String resp = doPost(SEND_URL, requestData, false);
+        return resp;
+    }
+
+    public String sendSms(String account, String password, String phones, Map<String, Object> template, String sign, String subcode, String msgid, String sendtime) {
+        JSONObject param = new JSONObject();
+        param.put("account", account);
+        param.put("password", EncryptUtil.MD5Encode(password));
+        param.put("msgid", msgid);
+        param.put("phones", phones);
+        param.put("template", template);
+        param.put("sign", sign);
+        param.put("subcode", subcode);
+        param.put("sendtime", sendtime);
+        String requestData = param.toString();
+        System.out.println("短信参数为:" + requestData);
+        LOG.info("短信参数为:" + requestData);
+        String resp = doPost(SEND_URL, requestData, false);
+        return resp;
+    }
+
+    public String sendBatchSms(String account, String password, List<SmsData> list) {
+        String resp = DEFAULT_RESPONSE;
+        if (list != null && !list.isEmpty()) {
+            JSONObject param = new JSONObject();
+            param.put("account", account);
+            param.put("password", EncryptUtil.MD5Encode(password));
+            JSONArray array = new JSONArray();
+            for (SmsData data : list) {
+                JSONObject paramData = new JSONObject();
+                paramData.put("msgid", data.getMsgid());
+                paramData.put("phones", data.getPhones());
+                paramData.put("content", data.getContent());
+                paramData.put("sign", data.getSign());
+                paramData.put("subcode", data.getSubcode());
+                paramData.put("sendtime", data.getSendtime());
+                array.add(paramData);
+            }
+            param.put("data", array);
+            String requestData = param.toString();
+            resp = doPost(BATCH_SEND_URL, requestData, false);
+        }
+
+        return resp;
+
+    }
+
+    public String sendSms(String account, String password, String phones, String content, String sign, String subcode, String msgid) {
+        return sendSms(account, password, phones, content, sign, subcode, msgid, "");
+    }
+
+    public String sendSms(String account, String password, String phones, String content, String sign, String subcode) {
+        return sendSms(account, password, phones, content, sign, subcode, "", "");
+    }
+
+    public String sendSms(String account, String password, String phones, Map<String, Object> template, String sign, String subcode) {
+        return sendSms(account, password, phones, template, sign, subcode, "", "");
+    }
+
+    /**
+     * 获取状态报告
+     *
+     * @param account  帐号(必填)
+     * @param password 密码(必填)
+     * @param msgid    msgid(可选)
+     * @param phone    手机号码(可选)
+     */
+    public String getReport(String account, String password, String msgid, String phone) {
+
+        JSONObject param = new JSONObject();
+        param.put("account", account);
+        param.put("password", EncryptUtil.MD5Encode(password));
+        param.put("msgid", msgid);
+        param.put("phone", phone);
+        String requestData = param.toString();
+        String resp = doPost(GET_REPORT_URL, requestData, false);
+        return resp;
+    }
+
+    public String getReport(String account, String password) {
+        return getReport(account, password, "", "");
+    }
+
+    /**
+     * 获取上行短信
+     *
+     * @param account  帐号(必填)
+     * @param password 密码(必填)
+     */
+    public String getSms(String account, String password) {
+
+        JSONObject param = new JSONObject();
+        param.put("account", account);
+        param.put("password", EncryptUtil.MD5Encode(password));
+        String requestData = param.toString();
+        String resp = doPost(DELIVER_URL, requestData, false);
+        return resp;
+    }
+
+    /**
+     * 获取余额
+     *
+     * @param account  帐号(必填)
+     * @param password 密码(必填)
+     */
+    public String getBalance(String account, String password) {
+        JSONObject param = new JSONObject();
+        param.put("account", account);
+        param.put("password", EncryptUtil.MD5Encode(password));
+        String requestData = param.toString();
+        String resp = doPost(BALANCE_URL, requestData, false);
+        return resp;
+    }
+
+    /**
+     * HTTP POST 请求
+     *
+     * @param url  请求地址
+     * @param data 提交数据
+     * @return
+     */
+    public String doPost(String url, String data, boolean isReconn) {
+        String response = null;
+        String requestURL = null;
+        try {
+            if (isSwitch.get()) {
+                if (slaveUrl != null && !"".equals(slaveUrl.trim())) {
+                    requestURL = slaveUrl + url;
+                    response = request(requestURL, data);
+                }
+            } else {
+                requestURL = masterUrl + url;
+                response = request(requestURL, data);
+            }
+        } catch (ConnectTimeoutException e) {
+            redirectURL(url, data, isReconn, requestURL, e);
+        } catch (ConnectException e) {
+            redirectURL(url, data, isReconn, requestURL, e);
+        } catch (Exception e) {
+            LOG.error("访问:" + requestURL + " 异常:", e);
+            System.err.println(e);
+        }
+        return response;
+    }
+
+    private String redirectURL(String url, String data, boolean isReconn, String lastRequestURL, Exception e) {
+
+        if (!isSwitch.get()) {
+            if (!isReconn && slaveUrl != null && !"".equals(slaveUrl.trim())) {
+                isSwitch.set(true);
+                LOG.info("访问:" + lastRequestURL + " 异常,地址已经已被自动切换到从地址");
+                return doPost(url, data, true);
+            } else {
+                LOG.error("访问:" + lastRequestURL + " 异常:", e);
+            }
+
+        } else {
+            if (!isReconn) {
+                isSwitch.set(false);
+                LOG.info("访问:" + lastRequestURL + " 异常,地址已经已被自动切换到主地址");
+                return doPost(url, data, true);
+            } else {
+                LOG.error("访问:" + lastRequestURL + " 异常:", e);
+            }
+        }
+        return null;
+    }
+
+    private String request(String url, String data) throws HttpException, IOException {
+        String response = null;
+        PostMethod postMethod = null;
+        LOG.info("访问:" + url + " 请求数据:" + data);
+        try {
+            if (isHttps) {
+                ProtocolSocketFactory fcty = new MySecureProtocolSocketFactory();
+                Protocol.registerProtocol("https", new Protocol("https", fcty, 443));
+            }
+            HttpClient client = new HttpClient(new HttpClientParams(), new SimpleHttpConnectionManager(true));
+            postMethod = new PostMethod(url);
+            postMethod.setRequestHeader("Connection", "close");
+            postMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8");
+            byte[] byteData = data.getBytes("utf-8");
+            RequestEntity requestEntity = new ByteArrayRequestEntity(byteData);
+            postMethod.setRequestEntity(requestEntity);
+            HttpConnectionManagerParams managerParams = client.getHttpConnectionManager().getParams();
+            postMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(retryCount, false));
+            managerParams.setConnectionTimeout(conTimeOut);
+            managerParams.setSoTimeout(readTimeOut);
+            client.executeMethod(postMethod);
+            if (postMethod.getStatusCode() == HttpStatus.SC_OK) {
+                InputStream inputStream = postMethod.getResponseBodyAsStream();
+                response = this.getResponseString(inputStream);
+                LOG.info("访问:" + url + " 响应数据:" + response);
+            } else {
+                LOG.error("访问:" + url + "异常,响应状态码:" + postMethod.getStatusCode() + ",响应内容:" + postMethod.getResponseBodyAsString());
+            }
+        } finally {
+            if (postMethod != null) {
+                postMethod.releaseConnection();
+            }
+        }
+        return response;
+    }
+
+    private String getResponseString(InputStream inputStream) {
+        String response = null;
+        if (inputStream != null) {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            try {
+                int len = 0;
+                byte[] by = new byte[1024];
+                while ((len = inputStream.read(by)) != -1) {
+                    out.write(by, 0, len);
+                }
+                out.flush();
+                byte[] data = out.toByteArray();
+                if (data != null) {
+                    response = new String(data, "utf-8");
+                }
+            } catch (Exception e) {
+                LOG.error("读取文件流异常:", e);
+            } finally {
+                try {
+                    if (out != null) {
+                        out.close();
+                    }
+                } catch (Exception e) {
+                    LOG.error("关闭文件流异常:", e);
+                }
+            }
+
+        }
+
+        return response;
+    }
+
+    public int getConTimeOut() {
+        return conTimeOut;
+    }
+
+    public void setConTimeOut(int conTimeOut) {
+        this.conTimeOut = conTimeOut;
+    }
+
+    public int getReadTimeOut() {
+        return readTimeOut;
+    }
+
+    public void setReadTimeOut(int readTimeOut) {
+        this.readTimeOut = readTimeOut;
+    }
+
+    public void setRetryCount(int retryCount) {
+        this.retryCount = retryCount;
+    }
+
+    public int getRetryCount() {
+        return retryCount;
+    }
+
+}

+ 73 - 0
jz-crm-core/src/main/java/org/linlinjava/jz/core/util/sms/json/SmsData.java

@@ -0,0 +1,73 @@
+package org.linlinjava.jz.core.util.sms.json;
+
+public class SmsData {
+	private String msgid;
+	private String phones;
+	private String content;
+	private String sign;
+	private String subcode;
+	private String sendtime;
+
+	public SmsData(String phones, String content, String msgid, String sign, String subcode, String sendtime) {
+		super();
+		this.phones = phones;
+		this.content = content;
+		this.msgid = msgid;
+		this.sign = sign;
+		this.subcode = subcode;
+		this.sendtime = sendtime;
+	}
+
+	public SmsData() {
+		super();
+	}
+
+	public String getMsgid() {
+		return msgid;
+	}
+
+	public void setMsgid(String msgid) {
+		this.msgid = msgid;
+	}
+
+	public String getPhones() {
+		return phones;
+	}
+
+	public void setPhones(String phones) {
+		this.phones = phones;
+	}
+
+	public String getContent() {
+		return content;
+	}
+
+	public void setContent(String content) {
+		this.content = content;
+	}
+
+	public String getSign() {
+		return sign;
+	}
+
+	public void setSign(String sign) {
+		this.sign = sign;
+	}
+
+	public String getSubcode() {
+		return subcode;
+	}
+
+	public void setSubcode(String subcode) {
+		this.subcode = subcode;
+	}
+
+	public String getSendtime() {
+		return sendtime;
+	}
+
+	public void setSendtime(String sendtime) {
+		this.sendtime = sendtime;
+	}
+
+}