本文主要阐述其他系统如何对接用ecos框架的系统,下面用java请求ecos为例展开说明:
1 package cn.shopex.renee.common.utils; 2 3 import sun.applet.Main; 4 5 import javax.crypto.Mac; 6 import javax.crypto.SecretKey; 7 import javax.crypto.spec.SecretKeySpec; 8 import java.io.*; 9 import java.net.HttpURLConnection; 10 import java.net.URL; 11 import java.net.URLDecoder; 12 import java.net.URLEncoder; 13 import java.security.GeneralSecurityException; 14 import java.security.MessageDigest; 15 import java.util.HashMap; 16 import java.util.Map; 17 import java.util.Map.Entry; 18 import java.util.Set; 19 import java.util.TreeMap; 20 21 public abstract class WebUtils { 22 23 public static final String DEFAULT_CHARSET = "UTF-8"; 24 25 private static final String METHOD_POST = "POST"; 26 27 private static final String METHOD_GET = "GET"; 28 29 public static void main(String[] args) { 30 String secret = "mysecret0000001";//签名密钥,就是token,也就是 /config/certi.php 中的token值 //如果系统需要走公有矩阵,则token不能自定义,必须使用certi.php中的值 31 Map<String,String> params = new HashMap<>(); 32 params.put("direct","true"); 33 params.put("method","b2c.payment.create");//请求的接口名称,ecstore接口列表请参考文档:http://www.ec-os.net/ecstore/append-a/index.html 34 params.put("date","2008-01-25 20:23:30"); 35 params.put("format","json"); 36 params.put("sign",WebUtils.getShopexSign(secret,params));//签名 37 try { 38 String postResult = WebUtils.doPost("http://网店地址/index.php/api",params,3000,3000);//POST请求,url为例子,网店地址需要改成自己的域名 39 System.out.println(postResult); 40 } catch (IOException e) { 41 e.printStackTrace(); 42 } 43 } 44 private WebUtils() { 45 } 46 47 /** 48 * 执行HTTP POST请求。 49 * 50 * @param url 51 * 请求地址 52 * @param params 53 * 请求参数 54 * @return 响应字符串 55 * @throws java.io.IOException 56 */ 57 public static String doPost(String url, Map<String, String> params, int connectTimeout, int readTimeout) throws IOException { 58 return doPost(url, params, DEFAULT_CHARSET, connectTimeout, readTimeout); 59 } 60 61 /** 62 * 执行HTTP POST请求。 63 * 64 * @param url 65 * 请求地址 66 * @param params 67 * 请求参数 68 * @param charset 69 * 字符集,如UTF-8, GBK, GB2312 70 * @return 响应字符串 71 * @throws java.io.IOException 72 */ 73 public static String doPost(String url, Map<String, String> params, String charset, int connectTimeout, int readTimeout) 74 throws IOException { 75 String ctype = "application/x-www-form-urlencoded;charset=" + charset; 76 String query = buildQuery(params, charset); 77 byte[] content = {}; 78 if (query != null) { 79 content = query.getBytes(charset); 80 } 81 return doPost(url, ctype, content, connectTimeout, readTimeout); 82 } 83 84 public static String doPost(String url, String queryParams, int connectTimeout, int readTimeout) throws IOException { 85 String ctype = "application/x-www-form-urlencoded;charset=" + DEFAULT_CHARSET; 86 byte[] content = {}; 87 if (queryParams != null) { 88 content = queryParams.getBytes(DEFAULT_CHARSET); 89 } 90 return doPost(url, ctype, content, connectTimeout, readTimeout); 91 } 92 93 /** 94 * 执行HTTP POST请求。 95 * 96 * @param url 97 * 请求地址 98 * @param ctype 99 * 请求类型 100 * @param content 101 * 请求字节数组 102 * @return 响应字符串 103 * @throws java.io.IOException 104 */ 105 public static String doPost(String url, String ctype, byte[] content, int connectTimeout, int readTimeout) throws IOException { 106 HttpURLConnection conn = null; 107 OutputStream out = null; 108 String rsp = null; 109 try { 110 try { 111 conn = getConnection(new URL(url), METHOD_POST, ctype); 112 conn.setConnectTimeout(connectTimeout); 113 conn.setReadTimeout(readTimeout); 114 } catch (IOException e) { 115 throw e; 116 } 117 try { 118 out = conn.getOutputStream(); 119 out.write(content); 120 rsp = getResponseAsString(conn); 121 } catch (IOException e) { 122 throw e; 123 } 124 125 } finally { 126 if (out != null) { 127 out.close(); 128 } 129 if (conn != null) { 130 conn.disconnect(); 131 } 132 } 133 134 return rsp; 135 } 136 137 /** 138 * 执行HTTP GET请求。 139 * 140 * @param url 141 * 请求地址 142 * @param params 143 * 请求参数 144 * @return 响应字符串 145 * @throws java.io.IOException 146 */ 147 public static String doGet(String url, Map<String, String> params) throws IOException { 148 return doGet(url, params, DEFAULT_CHARSET); 149 } 150 151 /** 152 * 执行HTTP GET请求。 153 * 154 * @param url 155 * 请求地址 156 * @param params 157 * 请求参数 158 * @param charset 159 * 字符集,如UTF-8, GBK, GB2312 160 * @return 响应字符串 161 * @throws java.io.IOException 162 */ 163 public static String doGet(String url, Map<String, String> params, String charset) throws IOException { 164 HttpURLConnection conn = null; 165 String rsp = null; 166 167 try { 168 String ctype = "application/x-www-form-urlencoded;charset=" + charset; 169 String query = buildQuery(params, charset); 170 try { 171 conn = getConnection(buildGetUrl(url, query), METHOD_GET, ctype); 172 } catch (IOException e) { 173 throw e; 174 } 175 176 try { 177 rsp = getResponseAsString(conn); 178 } catch (IOException e) { 179 throw e; 180 } 181 182 } finally { 183 if (conn != null) { 184 conn.disconnect(); 185 } 186 } 187 188 return rsp; 189 } 190 191 private static HttpURLConnection getConnection(URL url, String method, String ctype) throws IOException { 192 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 193 conn.setRequestMethod(method); 194 conn.setDoInput(true); 195 conn.setDoOutput(true); 196 conn.setRequestProperty("Accept", "text/xml,text/javascript,text/html"); 197 conn.setRequestProperty("User-Agent", "shopEx"); 198 conn.setRequestProperty("Content-Type", ctype); 199 return conn; 200 } 201 202 private static URL buildGetUrl(String strUrl, String query) throws IOException { 203 URL url = new URL(strUrl); 204 if (isEmpty(query)) { 205 return url; 206 } 207 208 if (isEmpty(url.getQuery())) { 209 if (strUrl.endsWith("?")) { 210 strUrl = strUrl + query; 211 } else { 212 strUrl = strUrl + "?" + query; 213 } 214 } else { 215 if (strUrl.endsWith("&")) { 216 strUrl = strUrl + query; 217 } else { 218 strUrl = strUrl + "&" + query; 219 } 220 } 221 222 return new URL(strUrl); 223 } 224 225 public static String buildQuery(Map<String, String> params, String charset) throws IOException { 226 if (params == null || params.isEmpty()) { 227 return null; 228 } 229 230 StringBuilder query = new StringBuilder(); 231 Set<Entry<String, String>> entries = params.entrySet(); 232 boolean hasParam = false; 233 // 忽略参数名或参数值为空的参数 234 for (Entry<String, String> entry : entries) { 235 String name = entry.getKey(); 236 String value = entry.getValue(); 237 if (!isBlank(name)) { 238 if (hasParam) { 239 query.append("&"); 240 } else { 241 hasParam = true; 242 } 243 if(value==null){ 244 value=""; 245 } 246 query.append(name).append("=").append(URLEncoder.encode(value, charset)); 247 } 248 } 249 250 return query.toString(); 251 } 252 253 protected static String getResponseAsString(HttpURLConnection conn) throws IOException { 254 String charset = getResponseCharset(conn.getContentType()); 255 InputStream es = conn.getErrorStream(); 256 if (es == null) { 257 return getStreamAsString(conn.getInputStream(), charset); 258 } else { 259 String msg = getStreamAsString(es, charset); 260 if (isEmpty(msg)) { 261 throw new IOException(conn.getResponseCode() + ":" + conn.getResponseMessage()); 262 } else { 263 throw new IOException(msg); 264 } 265 } 266 } 267 268 private static String getStreamAsString(InputStream stream, String charset) throws IOException { 269 try { 270 BufferedReader reader = new BufferedReader(new InputStreamReader(stream, charset)); 271 StringWriter writer = new StringWriter(); 272 273 char[] chars = new char[256]; 274 int count = 0; 275 while ((count = reader.read(chars)) > 0) { 276 writer.write(chars, 0, count); 277 } 278 279 return writer.toString(); 280 } finally { 281 if (stream != null) { 282 stream.close(); 283 } 284 } 285 } 286 287 private static String getResponseCharset(String ctype) { 288 String charset = DEFAULT_CHARSET; 289 290 if (!isEmpty(ctype)) { 291 String[] params = ctype.split(";"); 292 for (String param : params) { 293 param = param.trim(); 294 if (param.startsWith("charset")) { 295 String[] pair = param.split("=", 2); 296 if (pair.length == 2) { 297 if (!isEmpty(pair[1])) { 298 charset = pair[1].trim(); 299 } 300 } 301 break; 302 } 303 } 304 } 305 306 return charset; 307 } 308 309 /** 310 * 使用默认的UTF-8字符集反编码请求参数值。 311 * 312 * @param value 313 * 参数值 314 * @return 反编码后的参数值 315 */ 316 public static String decode(String value) { 317 return decode(value, DEFAULT_CHARSET); 318 } 319 320 /** 321 * 使用默认的UTF-8字符集编码请求参数值。 322 * 323 * @param value 324 * 参数值 325 * @return 编码后的参数值 326 */ 327 public static String encode(String value) { 328 return encode(value, DEFAULT_CHARSET); 329 } 330 331 /** 332 * 使用指定的字符集反编码请求参数值。 333 * 334 * @param value 335 * 参数值 336 * @param charset 337 * 字符集 338 * @return 反编码后的参数值 339 */ 340 public static String decode(String value, String charset) { 341 String result = null; 342 if (!isEmpty(value)) { 343 try { 344 result = URLDecoder.decode(value, charset); 345 } catch (IOException e) { 346 throw new RuntimeException(e); 347 } 348 } 349 return result; 350 } 351 352 /** 353 * 使用指定的字符集编码请求参数值。 354 * 355 * @param value 356 * 参数值 357 * @param charset 358 * 字符集 359 * @return 编码后的参数值 360 */ 361 public static String encode(String value, String charset) { 362 String result = null; 363 if (!isEmpty(value)) { 364 try { 365 result = URLEncoder.encode(value, charset); 366 } catch (IOException e) { 367 throw new RuntimeException(e); 368 } 369 } 370 return result; 371 } 372 373 // private static Map<String, String> getParamsFromUrl(String url) { 374 // Map<String, String> map = null; 375 // if (url != null && url.indexOf(‘?‘) != -1) { 376 // map = splitUrlQuery(url.substring(url.indexOf(‘?‘) + 1)); 377 // } 378 // if (map == null) { 379 // map = new HashMap<String, String>(); 380 // } 381 // return map; 382 // } 383 384 /** 385 * 从URL中提取所有的参数。 386 * 387 * @param query 388 * URL地址 389 * @return 参数映射 390 */ 391 public static Map<String, String> splitUrlQuery(String query) { 392 Map<String, String> result = new HashMap<String, String>(); 393 394 String[] pairs = query.split("&"); 395 if (pairs != null && pairs.length > 0) { 396 for (String pair : pairs) { 397 String[] param = pair.split("=", 2); 398 if (param != null && param.length == 2) { 399 result.put(param[0], param[1]); 400 } 401 } 402 } 403 404 return result; 405 } 406 407 private static boolean isEmpty(final String str) { 408 return str == null || str.length() == 0; 409 } 410 411 private static boolean isBlank(final String str) { 412 int length; 413 414 if (str == null || (length = str.length()) == 0) { 415 return true; 416 } 417 418 for (int i = 0; i < length; i++) { 419 if (!Character.isWhitespace(str.charAt(i))) { 420 return false; 421 } 422 } 423 424 return true; 425 } 426 427 /** 428 * 得到shopex体系签名 429 * @param secret 密钥 430 * @param paramMap 请求参数 431 * @return 432 */ 433 public static String getShopexSign(String secret, Map<String, String> paramMap) { 434 String mixParam = SignTools.mixRequestParams(paramMap); 435 String sign = null; 436 try { 437 String signTemp = SignTools.byte2hex(SignTools.encryptMD5(mixParam), true); 438 sign = SignTools.byte2hex(SignTools.encryptMD5(signTemp + secret), true); 439 } catch (IOException e) { 440 e.printStackTrace(); 441 } 442 return sign; 443 } 444 445 /** 446 * 使用HMAC加密 447 * @param data 加密前字符串 448 * @param secret 密钥 449 * @return 450 * @throws java.io.IOException 451 */ 452 public static byte[] encryptHMAC(String data, String secret) throws IOException { 453 byte[] bytes = null; 454 try { 455 SecretKey secretKey = new SecretKeySpec(secret.getBytes("utf-8"), "HmacMD5"); 456 Mac mac = Mac.getInstance(secretKey.getAlgorithm()); 457 mac.init(secretKey); 458 bytes = mac.doFinal(data.getBytes("utf-8")); 459 } catch (GeneralSecurityException gse) { 460 String msg = getStringFromException(gse); 461 throw new IOException(msg); 462 } 463 return bytes; 464 } 465 466 /** 467 * 使用HmacSHA256加密 468 * @param data 加密前字符串 469 * @param secret 密钥 470 * @return 471 * @throws java.io.IOException 472 */ 473 public static byte[] encryptHmacSHA256(String data, String secret) throws IOException { 474 byte[] bytes = null; 475 try { 476 SecretKey secretKey = new SecretKeySpec(secret.getBytes("utf-8"), "HmacSHA256"); 477 Mac mac = Mac.getInstance(secretKey.getAlgorithm()); 478 mac.init(secretKey); 479 bytes = mac.doFinal(data.getBytes("utf-8")); 480 } catch (GeneralSecurityException gse) { 481 throw new IOException(gse); 482 } 483 return bytes; 484 } 485 486 /** 487 * 使用MD5加密 488 * @param data 加密前字符串 489 * @return 490 * @throws java.io.IOException 491 */ 492 public static byte[] encryptMD5(String data) throws IOException { 493 byte[] bytes = null; 494 try { 495 MessageDigest md = MessageDigest.getInstance("MD5"); 496 bytes = md.digest(data.getBytes("utf-8")); 497 } catch (GeneralSecurityException gse) { 498 String msg=getStringFromException(gse); 499 throw new IOException(msg); 500 } 501 return bytes; 502 } 503 504 /** 505 * 把二进制数据转化为十六进制 506 * @param bytes 507 * @param isToUpper 是否大写 508 * @return 509 */ 510 public static String byte2hex(byte[] bytes, boolean isToUpper) { 511 StringBuilder sign = new StringBuilder(); 512 for (int i = 0; i < bytes.length; i++) { 513 String hex = Integer.toHexString(bytes[i] & 0xFF); 514 if (hex.length() == 1) { 515 sign.append("0"); 516 } 517 if (isToUpper) 518 sign.append(hex.toUpperCase()); 519 else 520 sign.append(hex); 521 } 522 return sign.toString(); 523 } 524 525 /** 526 * <p>根据参数名称将你的所有请求参数按照字母先后顺序排序:key + value .... key + value</p> 527 * <p>对除签名和图片外的所有请求参数按key做的升序排列, value无需编码。 528 * 例如:将foo=1,bar=2,baz=3 排序为bar=2,baz=3,foo=1 529 * 参数名和参数值链接后,得到拼装字符串bar2baz3foo1</p> 530 * @param sysParams 系统级参数 531 * @param appParams 应用级参数 532 * @param isFilterParamOfNullValue 是否过滤值为NULL的参数,若不过滤则以""空字符串代替 533 * @return 拼装字符串 534 */ 535 public static String mixRequestParams(Map<String, Object> sysParams, Map<String, Object> appParams,boolean isFilterParamOfNullValue) { 536 // 第一步:把字典按Key的字母顺序排序 537 Map<String, Object> sortedParams = new TreeMap<String, Object>(); 538 sortedParams.putAll(sysParams); 539 sortedParams.putAll(appParams); 540 Set<Map.Entry<String, Object>> paramSet = sortedParams.entrySet(); 541 542 // 第二步:把所有参数名和参数值串在一起 543 StringBuilder query = new StringBuilder(); 544 for (Map.Entry<String, Object> param : paramSet) { 545 if (StringUtils.areNotEmpty(param.getKey())) { 546 if (!StringUtils.isBlank(param.getKey()) && !"sign".equals(param.getKey())) { 547 if(param.getValue()==null||StringUtils.isEmpty(param.getValue().toString())) { 548 if(!isFilterParamOfNullValue) { 549 query.append(param.getKey()).append(""); 550 } 551 }else { 552 query.append(param.getKey()).append(param.getValue().toString()); 553 } 554 } 555 } 556 } 557 return query.toString(); 558 } 559 560 public static String mixRequestParams(Map<String, String> params) { 561 Map<String, String> sortedParams = new TreeMap<>(params); 562 Set<Map.Entry<String, String>> paramSet = sortedParams.entrySet(); 563 StringBuilder query = new StringBuilder(); 564 for (Map.Entry<String, String> param : paramSet) { 565 if (!StringUtils.isBlank(param.getKey()) && !"sign".equals(param.getKey())) { 566 query.append(param.getKey()).append(param.getValue()); 567 } 568 } 569 return query.toString(); 570 } 571 572 private static String getStringFromException(Throwable e) { 573 String result = ""; 574 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 575 PrintStream ps = new PrintStream(bos); 576 e.printStackTrace(ps); 577 try { 578 result = bos.toString("utf-8"); 579 } catch (UnsupportedEncodingException e1) { 580 e1.printStackTrace(); 581 } 582 return result; 583 } 584 585 }
对接ECOS框架(含ecstore、ocs、erp等产品)的方法【其他系统请求ecos的api接口】,布布扣,bubuko.com