1841c0d2dfff4575ead276eb2f0966a57408fc31.svn-base 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. package com.iamberry.app.service;
  2. import static com.iamberry.app.config.ImberryConfig.INTER_SMS_KEY;
  3. import static com.iamberry.app.config.ImberryConfig.SMS_PASSWORD;
  4. import static com.iamberry.app.config.ImberryConfig.SMS_TEXT;
  5. import static com.iamberry.app.config.ImberryConfig.SMS_URL;
  6. import static com.iamberry.app.config.ImberryConfig.SMS_USERNAME;
  7. import static com.iamberry.app.config.ImberryConfig.INTER_SMS_KEY;
  8. import static com.iamberry.app.config.ImberryConfig.INTER_SMS_TEXT;
  9. import static com.iamberry.app.config.ImberryConfig.INTER_SMS_URL;
  10. import java.text.MessageFormat;
  11. import java.util.ArrayList;
  12. import java.util.Date;
  13. import java.util.HashMap;
  14. import java.util.List;
  15. import java.util.Map;
  16. import net.sf.json.JSONObject;
  17. import org.apache.commons.lang3.StringUtils;
  18. import org.apache.http.HttpEntity;
  19. import org.apache.http.NameValuePair;
  20. import org.apache.http.client.entity.UrlEncodedFormEntity;
  21. import org.apache.http.client.methods.CloseableHttpResponse;
  22. import org.apache.http.client.methods.HttpPost;
  23. import org.apache.http.impl.client.CloseableHttpClient;
  24. import org.apache.http.impl.client.HttpClients;
  25. import org.apache.http.message.BasicNameValuePair;
  26. import org.apache.http.util.EntityUtils;
  27. import org.springframework.beans.factory.annotation.Autowired;
  28. import org.springframework.stereotype.Service;
  29. import com.iamberry.app.core.entity.CodeValid;
  30. import com.iamberry.app.face.CodeService;
  31. import com.iamberry.app.mapper.CodeMapper;
  32. import com.iamberry.app.tool.util.Result;
  33. import com.iamberry.app.ulitity.Utility;
  34. import com.iamberry.wechat.tools.ResponseJson;
  35. import com.thoughtworks.xstream.XStream;
  36. import com.thoughtworks.xstream.io.xml.StaxDriver;
  37. /**
  38. * @company 深圳爱贝源科技有限公司
  39. * @website www.iamberry.com
  40. * @author 献
  41. * @tel 18271840547
  42. * @date 2016年11月1日
  43. * @explain 验证码业务实现类
  44. */
  45. @SuppressWarnings("unused")
  46. @Service
  47. public class CodeServiceImpl implements CodeService {
  48. @Autowired
  49. private CodeMapper codeMapper;
  50. private static String ENCODING = "UTF-8";
  51. @Override
  52. public ResponseJson sendCode(String phone, int codeScenario) {
  53. // TODO Auto-generated method stub
  54. // 第一步,判断使用通道,如果是+86开头,优先使用国内通道,否则默认使用国外通道
  55. ResponseJson json = new ResponseJson();
  56. if (StringUtils.isEmpty(phone)) {
  57. json.setReturnCode(404);
  58. json.addResponseKeyValue("Phone Empty!");
  59. return json;
  60. }
  61. String phones = StringUtils.substringAfter(phone, ","); //截取
  62. // 第二步,如果是国内,判断是否存在
  63. CodeValid codeValid = codeMapper.getLast(phones);
  64. // 通道是否是中国的
  65. boolean IS_CHANNEL_ZH = false;
  66. if (StringUtils.startsWith(phone, "86,")) {
  67. IS_CHANNEL_ZH = true;
  68. } else {
  69. IS_CHANNEL_ZH = false;
  70. }
  71. // 判断通道
  72. Date now = new Date();
  73. if (IS_CHANNEL_ZH && codeValid != null) {
  74. // ** 切换通道需求:每次请求验证码,如果上一次验证码在一分钟以后,三分钟以内没有使用,那么切换通道 **//
  75. if (now.getTime() <= (codeValid.getCodeValidDate().getTime()) &&
  76. (now.getTime() - 60000) >= codeValid.getCodeSendDate().getTime() && codeValid.getCodeUse() == 2 && codeValid.getCodeScenario() == codeScenario) {
  77. // 如果等待三分钟后,那么切换通道
  78. IS_CHANNEL_ZH = false;
  79. }
  80. }
  81. // 获取验证码
  82. String code = Utility.getRandomCode(4);
  83. json = sendCMS(phone, code, IS_CHANNEL_ZH ? 1 : 2);
  84. if (json.getReturnCode() != 200) {
  85. json = sendCMS(phone, code, IS_CHANNEL_ZH ? 1 : 2);
  86. }
  87. // 保存发送记录
  88. codeValid = new CodeValid();
  89. codeValid.setCodeChannel(IS_CHANNEL_ZH ? 1 : 2);
  90. codeValid.setCodeMsg(json.getReturnMsg().get("returnMsg").toString());
  91. codeValid.setCodePhone(phones);
  92. codeValid.setCodeScenario(codeScenario);
  93. codeValid.setCodeSendDate(now);
  94. codeValid.setCodeValidDate(new Date(now.getTime() + 180000));
  95. codeValid.setCodeStatus(json.getReturnCode() == 200 ? 3 : 4);
  96. codeValid.setCodeUse(2);
  97. codeValid.setCodeValue(Integer.parseInt(code));
  98. codeMapper.save(codeValid);
  99. return json;
  100. }
  101. /**
  102. * @param phone 手机号码
  103. * @param code 短信验证码
  104. * @param channel 通道 1:主通道;2:备用通道(国外的电话通通使用此)
  105. * @return
  106. */
  107. private ResponseJson sendCMS(String phone, String code, int channel) {
  108. // 国内号码
  109. ResponseJson json = new ResponseJson();
  110. json.setReturnCode(500);
  111. String result = null;
  112. try {
  113. if (channel == 1) {
  114. phone = StringUtils.substringAfter(phone, ","); //截取
  115. // 使用主通道
  116. result = sendZHCMS(phone, code);
  117. } else {
  118. phone = StringUtils.replace(phone,",",""); //替换
  119. // 使用备用通道
  120. result = sendOtherCMS(phone, code);
  121. }
  122. } catch (Exception e) {
  123. result = e.getMessage();
  124. }
  125. if (StringUtils.equals(result, "SUCCESS")) {
  126. json.setReturnCode(200);
  127. }
  128. json.addResponseKeyValue(result);
  129. return json;
  130. }
  131. private String sendOtherCMS(String phone, String code) {
  132. String text = MessageFormat.format(INTER_SMS_TEXT, code);
  133. String results = sendSms(text, "+"+phone);
  134. JSONObject json = JSONObject.fromObject(results);
  135. String resultcod = json.get("code").toString();
  136. if(resultcod.equals("0")){
  137. System.out.println("使用备用通道,发送验证码成功!" + code);
  138. return "SUCCESS";
  139. }else{
  140. System.out.println("使用备用通道,发送失败...!" + code);
  141. return results;
  142. }
  143. }
  144. public static String sendSms(String text, String mobile) {
  145. Map<String, String> params = new HashMap<String, String>();
  146. params.put("apikey", INTER_SMS_KEY);
  147. params.put("text", text);
  148. params.put("mobile", mobile);
  149. return post(INTER_SMS_URL, params);
  150. }
  151. /** 基于HttpClient 4.3的通用POST方法
  152. * @param url 提交的URL
  153. * @param paramsMap 提交<参数,值>Map
  154. * @return 提交响应
  155. */
  156. public static String post(String url, Map<String, String> paramsMap) {
  157. CloseableHttpClient client = HttpClients.createDefault();
  158. String responseText = "";
  159. CloseableHttpResponse response = null;
  160. try {
  161. HttpPost method = new HttpPost(url);
  162. if (paramsMap != null) {
  163. List<NameValuePair> paramList = new ArrayList<NameValuePair>();
  164. for (Map.Entry<String, String> param : paramsMap.entrySet()) {
  165. NameValuePair pair = new BasicNameValuePair(param.getKey(), param.getValue());
  166. paramList.add(pair);
  167. }
  168. method.setEntity(new UrlEncodedFormEntity(paramList, ENCODING));
  169. }
  170. response = client.execute(method);
  171. HttpEntity entity = response.getEntity();
  172. if (entity != null) {
  173. responseText = EntityUtils.toString(entity);
  174. }
  175. } catch (Exception e) {
  176. e.printStackTrace();
  177. } finally {
  178. try {
  179. response.close();
  180. } catch (Exception e) {
  181. e.printStackTrace();
  182. }
  183. }
  184. return responseText;
  185. }
  186. private String sendZHCMS(String phone, String code) throws Exception {
  187. CloseableHttpClient client = HttpClients.createDefault();
  188. Map<String, String> params = new HashMap<String, String>();
  189. CloseableHttpResponse response = null;
  190. params.put("username", SMS_USERNAME);
  191. params.put("password", SMS_PASSWORD);
  192. params.put("mobile", phone);
  193. params.put("content", MessageFormat.format(SMS_TEXT, code));
  194. HttpPost method = new HttpPost(SMS_URL);
  195. if (params != null) {
  196. List<NameValuePair> paramList = new ArrayList<NameValuePair>();
  197. for (Map.Entry<String, String> param : params.entrySet()) {
  198. NameValuePair pair = new BasicNameValuePair(param.getKey(), param.getValue());
  199. paramList.add(pair);
  200. }
  201. method.setEntity(new UrlEncodedFormEntity(paramList, "UTF-8"));
  202. }
  203. response = client.execute(method);
  204. HttpEntity entity = response.getEntity();
  205. if (entity != null) {
  206. String result = EntityUtils.toString(entity);
  207. XStream xs = new XStream(new StaxDriver());
  208. xs.alias("result", Result.class);
  209. Result object = (Result)xs.fromXML(result);
  210. response.close();
  211. if (0 == object.getResultcode()) {
  212. return "SUCCESS";
  213. } else {
  214. return object.getResultcode() + ":" + object.getErrordescription();
  215. }
  216. }
  217. return null;
  218. }
  219. @Override
  220. public ResponseJson validCode(String phone, String code, int codeScenario) {
  221. ResponseJson json = new ResponseJson();
  222. // 校验
  223. CodeValid codeValid = codeMapper.getLast(phone);
  224. if (codeValid == null) {
  225. // 操作有误
  226. json.setReturnCode(404);
  227. json.addResponseKeyValue("Wrong operation");
  228. return json;
  229. }
  230. Date now = new Date();
  231. if (now.getTime() >= codeValid.getCodeValidDate().getTime()) {
  232. // 验证码无效
  233. json.setReturnCode(404);
  234. json.addResponseKeyValue("Verification code is invalid");
  235. return json;
  236. }
  237. // 必须 验证码正确,并且场景正确
  238. if (!(codeValid.getCodeValue() == (Integer.parseInt(code))
  239. && codeScenario == codeValid.getCodeScenario())) {
  240. // 验证码错误
  241. json.setReturnCode(404);
  242. json.addResponseKeyValue("Verification code error");
  243. return json;
  244. }
  245. // 只要校验,表示本次验证码使用
  246. codeMapper.update(codeValid.getCodeId());
  247. json.setReturnCode(200);
  248. json.addResponseKeyValue("SUCCESS");
  249. return json;
  250. }
  251. }