客户端请求代码
Java
import java.io.IOException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
import com.alibaba.fastjson.JSON;
import junit.framework.TestCase;
public class PostTest extends TestCase {
@Test
public void testPost() throws IOException {
String appKey = "test";
String secret = "123456";
// 业务参数
Map<String, String> jsonMap = new HashMap<String, String>();
jsonMap.put("goodsName", "iphoneX");
String json = JSON.toJSONString(jsonMap);
json = URLEncoder.encode(json, "utf-8");
// 系统参数
Map<String, Object> param = new HashMap<String, Object>();
param.put("name", "goods.get");
param.put("app_key", appKey);
param.put("data", json);
param.put("timestamp", getTime());
param.put("version", "");
String sign = buildSign(param, secret);
param.put("sign", sign);
System.out.println("=====请求数据=====");
System.out.println(JSON.toJSON(param));
}
/**
* 构建签名
*
* @param paramsMap
* 参数
* @param secret
* 密钥
* @return
* @throws IOException
*/
public static String buildSign(Map<String, ?> paramsMap, String secret) throws IOException {
Set<String> keySet = paramsMap.keySet();
List<String> paramNames = new ArrayList<String>(keySet);
Collections.sort(paramNames);
StringBuilder paramNameValue = new StringBuilder();
for (String paramName : paramNames) {
paramNameValue.append(paramName).append(paramsMap.get(paramName));
}
String source = secret + paramNameValue.toString() + secret;
return md5(source);
}
/**
* 生成md5,全部大写
*
* @param message
* @return
*/
public static String md5(String message) {
try {
// 1 创建一个提供信息摘要算法的对象,初始化为md5算法对象
MessageDigest md = MessageDigest.getInstance("MD5");
// 2 将消息变成byte数组
byte[] input = message.getBytes();
// 3 计算后获得字节数组,这就是那128位了
byte[] buff = md.digest(input);
// 4 把数组每一字节(一个字节占八位)换成16进制连成md5字符串
return byte2hex(buff);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 二进制转十六进制字符串
*
* @param bytes
* @return
*/
private static String byte2hex(byte[] bytes) {
StringBuilder sign = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xFF);
if (hex.length() == 1) {
sign.append("0");
}
sign.append(hex.toUpperCase());
}
return sign.toString();
}
public String getTime() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
}
}
JavaScript
/**
//需要发布到服务器上运行,并且server端需要处理跨域
//在IndexController.java上加@CrossOrigin(origins={"*"})
sdk.config({
url : 'http://localhost:8080/api'
,app_key : 'test'
,secret : '123456'
,jwt : 'xxx'
});
sdk.post({
name : 'goods.get' // 接口名
// ,version:'1.0'
// ,access_token:''
,data : {'goods_name':'iphone'} // 请求参数
,callback:function(resp) { // 成功回调
console.log(resp)
}
});
sdk.post({
name : 'goods.get' // 接口名
,data : {'goods_name':'iphone'} // 请求参数
,callback:function(resp) { // 成功回调
console.log(resp)
}
});
*/
;(function(){
var config = {
url : 'http://127.0.0.1:8080/api'
,app_key : 'test'
,secret : '123456'
,default_version : ''
,api_name : "name"
,version_name : "version"
,app_key_name : "app_key"
,data_name : "data"
,timestamp_name : "timestamp"
,sign_name : "sign"
,format_name : "format"
,access_token_name : "access_token"
,jwt : ''
}
var DEFAULT_FORMAT = 'json';
var UPLOAD_FORM_DATA_NAME = 'body_data';
var CONTENT_TYPE_JSON = 'application/json';
var CONTENT_TYPE_KEY = 'Content-Type';
var POST_TYPE = 'POST';
var GET_TYPE = 'GET';
function copy(source, target) {
if (target && source && typeof source == 'object') {
for (var p in source) {
target[p] = source[p];
}
}
return target;
}
function add0(m){return m<10?'0'+m:m }
function formatDate(time)
{
var y = time.getFullYear();
var m = time.getMonth()+1;
var d = time.getDate();
var h = time.getHours();
var mm = time.getMinutes();
var s = time.getSeconds();
return y+'-'+add0(m)+'-'+add0(d)+' '+add0(h)+':'+add0(mm)+':'+add0(s);
}
/** 构建签名 */
function buildSign(postData,secret) {
var paramNames = [];
for(var key in postData) {
paramNames.push(key);
}
paramNames.sort();
var paramNameValue = [];
for(var i=0,len=paramNames.length;i<len;i++) {
var paramName = paramNames[i];
paramNameValue.push(paramName);
paramNameValue.push(postData[paramName]);
}
var source = secret + paramNameValue.join('') + secret;
// MD5算法参见http://pajhome.org.uk/crypt/md5/
return hex_md5(source).toUpperCase();
}
var ajax = {
/**
* 提交请求
* @param opts.url 请求url
* @param opts.params 请求参数json
* @param opts.headers 请求header,json
* @param opts.form 表单dom对象
* @param opts.callback 回调
* @param opts.error 错误回调
*/
request:function(opts) {
var url = opts.url;
var params = opts.params;
var headers = opts.headers;
var form = opts.form;
var callback = opts.callback;
var error = opts.error || function(e){alert('数据请求失败')};
var method = opts.method;
var paramStr = JSON.stringify(params);
var xhr = this.createXhrObject();
xhr.onreadystatechange = function() {
var jsonData = '';
if (xhr.readyState == 4){
var status = xhr.status;
if ((status >= 200 && status < 300) || status == 304){
jsonData = JSON.parse(xhr.responseText);
callback(jsonData, paramStr);
} else {
jsonData = JSON.parse('{"message":"后台请求错误(status:' + status + ')"}');
console.log(xhr.responseText)
error(jsonData, paramStr);
}
}
};
// 添加header
if(headers) {
for (var key in headers) {
xhr.setRequestHeader(key,headers[key]);
}
}
if(method == GET_TYPE) {
var queryString = [];
for (var key in params) {
var p = key + '=' + encodeURIComponent(params[key]);
queryString.push(p);
}
url = url + '?' + queryString.join('&');
xhr.open(method, url, true);
xhr.send();
} else if(method == POST_TYPE) {
xhr.open(method, url, true);
if(form) {
var formData = new FormData(form);
// 添加json
formData.append(UPLOAD_FORM_DATA_NAME, paramStr);
xhr.send(formData);
} else {
xhr.setRequestHeader(CONTENT_TYPE_KEY, CONTENT_TYPE_JSON);
xhr.send(paramStr);
}
} else {
throw new Error('不支持的method:' + method);
}
}
/**
* 创建XHR对象
* @private
*/
,createXhrObject:function() {
var methods = [
function(){ return new XMLHttpRequest();}
,function(){ return new ActiveXObject('Msxml2.XMLHTTP');}
,function(){ return new ActiveXObject('Microsoft.XMLHTTP');}
];
var xhr = null;
for(var i=0,len=methods.length; i<len; i++) {
try {
xhr = methods[i]();
} catch (e) {
continue;
}
this.createXhrObject = methods[i];
return xhr;
}
throw new Error("创建XHR对象失败");
}
}
/**
* 请求
* @param opts.name 接口名
* @param opts.version 版本号
* @param opts.method 请求方式
* @param opts.data 请求数据,json对象
* @param opts.access_token
* @param opts.form 表单dom
* @param opts.callback 响应回调
* @param opts.jwt jwt
*/
function request(opts) {
var name = opts.name,
version = opts.version || config.default_version,
data = opts.data || {},
callback = opts.callback,
accessToken = opts.access_token,
url = opts.url || config.url;
var headers = {};
var postData = {};
postData[config.api_name] = name;
postData[config.version_name] = version;
postData[config.app_key_name] = config.app_key;
postData[config.data_name] = encodeURIComponent(JSON.stringify(data));
postData[config.timestamp_name] = formatDate(new Date());
postData[config.format_name] = DEFAULT_FORMAT;
if(accessToken) {
postData[config.access_token_name] = accessToken;
}
postData[config.sign_name] = buildSign(postData,config.secret);
var jwt = opts.jwt || config.jwt; // 优先使用opts中的jwt
if(jwt) {
headers['Authorization'] = 'Bearer ' + jwt;
}
ajax.request({
url:url
,method:opts.method
,params:postData
,headers:headers
,form:opts.form
,callback:callback
,error:opts.error
});
}
var sdk = {
config:function(cfg) {
copy(cfg,config);
}
/**
* post请求
* @param opts.name 接口名
* @param opts.version 版本号
* @param opts.data 请求数据,json对象
* @param opts.access_token
* @param opts.form 表单dom
* @param opts.callback 响应回调
* @param opts.jwt jwt
*/
,post:function(opts) {
opts.method = POST_TYPE;
request(opts);
}
/**
* get请求
* @param opts.name 接口名
* @param opts.version 版本号
* @param opts.data 请求数据,json对象
* @param opts.access_token
* @param opts.callback 响应回调
* @param opts.jwt jwt
*/
,get:function(opts) {
if(opts.form) {
throw new Error('get方式不支持上传功能');
}
opts.method = GET_TYPE;
request(opts);
}
}
window.sdk = sdk;
})();