1.1調用參數
1.2簽名算法

2服務端代碼,Java舉例
2.1接口入口代碼
2.2業(yè)務邏輯層
2.3基礎工具類

3.SDK代碼,Java舉例

4.集成SDK,代" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

18143453325 在線咨詢 在線咨詢
18143453325 在線咨詢
所在位置: 首頁 > 營銷資訊 > 網站運營 > 仿京東開放平臺框架,開發(fā)自己的開放平臺(包含需求,服務端代碼,SDK代碼)

仿京東開放平臺框架,開發(fā)自己的開放平臺(包含需求,服務端代碼,SDK代碼)

時間:2023-04-21 01:48:01 | 來源:網站運營

時間:2023-04-21 01:48:01 來源:網站運營

仿京東開放平臺框架,開發(fā)自己的開放平臺(包含需求,服務端代碼,SDK代碼):

目錄

1開放平臺需求
1.1調用參數
1.2簽名算法

2服務端代碼,Java舉例
2.1接口入口代碼
2.2業(yè)務邏輯層
2.3基礎工具類

3.SDK代碼,Java舉例

4.集成SDK,代碼舉例

現在開放平臺越來越多了,下面針對仿京東開放平臺框架,封裝自己的開放平臺,分享給大家。

先感謝一下京東開放平臺的技術大佬們,下面從開放平臺需求,服務端代碼,SDK代碼三大塊進行分享,有不足之處,歡迎在評論區(qū)留言。

1開放平臺需求

用戶需要按照開放平臺的協(xié)議規(guī)范拼裝一個正確的URL,通過Https請求到開放平臺既能夠獲取到所需數據。主要流程包含:填寫參數、生成簽名、拼裝HTTPS請求、發(fā)起請求、得到響應結果、解析結果。

1.1調用參數

系統(tǒng)參數:調用任何一個API都需要傳入的參數,目前支持的系統(tǒng)參數是:

應用級參數(更多API應用參數參考 接口文檔)

1.2簽名算法

為了防止API在調用過程中被惡意者攔截隨意篡改,調用API是需要傳入簽名參數,開放平臺服務端會根據請求參數對簽名進行驗證,判斷請求參數是否合法。開放平臺簽名規(guī)則過程如下:

將所有請求參數按照字母先后順序排列,例如:access_token,app_key,method,timestamp,v,360buy_param_json ,

排序為360buy_param_json,access_token,app_key,method,timestamp,v

把所有參數名和參數值進行拼接,例如360buy_param_jsonxxxaccess_tokenxxxapp_keyxxxmethodxxxxxxtimestampxxxxxxvx

把appSecret夾在字符串(上一步拼接串)的兩端,例如:appSecret+XXXX+appSecret

使用MD5進行加密,再轉化成大寫。

2服務端代碼,Java舉例

服務端基于SpringBoot框架編寫,入口放在Controller,業(yè)務邏輯寫在Service。同時考慮安全性和方便排查問題,會加入輸入性校驗和訪問日志。

2.1接口入口代碼

接口只有一個入口,即Controller代碼如下:

@Controllerpublic class RouterController { @Resource private RouterService routerService; @Resource private OpenApiLogService openApiLogService; /** * API接口路由器,接口入口 * * @param request * @param zrsc_param_json * @return */ @RequestMapping(value = "routerjson", method = RequestMethod.POST) @ResponseBody public String routerjson(HttpServletRequest request, String zrsc_param_json) { if (zrsc_param_json==null||"".equals(zrsc_param_json)) { return JsonUtils.objToJson(APIMessageVo.fail(APIErrorEnum.FAIL_PARA_LOSE.getCode(), APIErrorEnum .FAIL_PARA_LOSE.getName())); } APIMessageVo aPIMessageVo=openApiLogService.secrityCheck(request); if(aPIMessageVo.isSuccess()){//安全檢測成功 aPIMessageVo=routerService.router(request, zrsc_param_json); openApiLogService.insert(request,aPIMessageVo); } return JsonUtils.objToJson(aPIMessageVo); }}

2.2業(yè)務邏輯層

業(yè)務邏輯層,簡單舉例說明,不同業(yè)務有所不同。

public APIMessageVo router(HttpServletRequest request, String zrsc_param_json) { String access_token = request.getParameter("access_token"); String app_key = request.getParameter("app_key"); String method = request.getParameter("method"); String sign = request.getParameter("sign"); APIMessageVo checkResult=this.routerParaCheck(request, zrsc_param_json,access_token,app_key,method,sign); if(!checkResult.isSuccess()){//入參檢測失敗 return checkResult; } if (APPInterfaceNameEnum.API_ADDRESS_ADDRESS2PROVICECITY_GET.getName().equals(method)) {//獲取省市區(qū)街道 return this.address2provincecity(zrsc_param_json); } else {//接口不存在 return APIMessageVo.fail(APIErrorEnum.FAIL_NOT_FOUND_INTERFACE.getCode(), APIErrorEnum.FAIL_NOT_FOUND_INTERFACE.getName()); } } private APIMessageVo routerParaCheck(HttpServletRequest request, String zrsc_param_json, String access_token, String app_key, String method, String sign){ //***************參數校驗*************** if (StringUtils.isBlank(access_token) || StringUtils.isBlank(app_key) || StringUtils.isBlank(method) || StringUtils.isBlank(sign)) { return APIMessageVo.fail(APIErrorEnum.FAIL_PARA_LOSE.getCode(), APIErrorEnum.FAIL_PARA_LOSE.getName()); } if(!APP_KEY.equals(app_key)){ return APIMessageVo.fail(APIErrorEnum.FAIL_NOT_EXIST_APP_ID.getCode(), APIErrorEnum.FAIL_NOT_EXIST_APP_ID.getName()); } //***************sign校驗*************** try { //獲取request中的參數 Map<String, String> sysParams = getSysParams(request, zrsc_param_json); //SDK參數加密 String signNew = SDKSignUtils.sign(sysParams, APP_SECRET); //判斷參數是否被更改 if (!sign.equals(signNew)) { return APIMessageVo.fail(APIErrorEnum.FAIL_ERR_APP_SECRET.getCode(), APIErrorEnum.FAIL_ERR_APP_SECRET.getName()); } } catch (Exception e) { return APIMessageVo.fail(APIErrorEnum.FAIL_EXCEPTION.getCode(), APIErrorEnum.FAIL_EXCEPTION.getName()); } return APIMessageVo.success(); }2.3基礎工具類
APIErrorEnum

public enum APIErrorEnum { FAIL_NOTAUTH(201,"沒有授權"), FAIL_TOKEN_EXPIRE(202,"Token過期"), FAIL_PARA_LOSE(203,"缺少參數"), FAIL_NOT_REALAUTH(204,"沒有實名認證通過"), FAIL_NOT_METHOD(205,"沒有權限訪問這個接口"), FAIL_PARA_ERR(206,"參數的值,不正確"), FAIL_NOT_EXIST_ACCOUNT(207,"用戶賬號不存在"), FAIL_NOT_FOUND_APPLY(208,"應用不存在"), FAIL_NOT_PASS_APPROVAL_APPLY(209,"應用審批未通過"), FAIL_NOT_EXIST_APP_ID(210,"APP_ID不存在"), FAIL_NOT_FOUND_INTERFACE(211,"接口不存在"), FAIL_ERR_APP_SECRET(212,"appSecret錯誤"), FAIL_CALL_FREQUENTLY(214,"調用太頻繁"), FAIL_EXCEPTION(290,"未知錯誤"); private int code; private String name; APIErrorEnum(int code,String name) { this.code = code; this.name = name; } public int getCode() { return code; } public String getName() { return name; } public void setCode(int code) { this.code = code; } public void setName(String name) { this.name = name; }}APIMessageVo

public class APIMessageVo { public static final Integer SUCCESS = 100;//成功 private boolean success;// 處理是否成功 private Integer code = SUCCESS;//狀態(tài)碼 private String message = "成功";// 附加消息, 如處理結果失敗時的原因等 private Object data="";// 可以附帶返回一些結果數據 public APIMessageVo() { //default } public APIMessageVo(boolean success, Integer code) { this(success, code, "成功", null); } public APIMessageVo(boolean success, Integer code, String message) { this(success, code, message, null); } public APIMessageVo(boolean success, String message, Object data) { this.success = success; this.message = message; this.data = data; } public APIMessageVo(boolean success, Integer code, String message, Object data) { this.success = success; this.code = code; this.message = message; this.data = data; } public APIMessageVo(boolean success, Object data) { this.success = success; this.data = data; } public static APIMessageVo fail(Integer code) { return new APIMessageVo(false, code); } public static APIMessageVo fail(Integer code,String message) { return new APIMessageVo(false,code, message); } public static APIMessageVo fail(Integer code,String message, Object data) { return new APIMessageVo(false,code, message, data); } public static APIMessageVo success() { return new APIMessageVo(true, SUCCESS); } public static APIMessageVo success(String message) { return new APIMessageVo(true, message); } public static APIMessageVo success(String message, Object data) { return new APIMessageVo(true, SUCCESS, message, data); } public static APIMessageVo success(Object data) { return new APIMessageVo(true, "成功", data); }}JsonUtils
···
public class JsonUtils {

// 定義jackson對象 private static final ObjectMapper MAPPER = new ObjectMapper();/** * 對象轉Json * * @param obj 對象 * @return json串 */public static String objToJson(Object obj) { try { return MAPPER.writeValueAsString(obj); } catch (JsonProcessingException e) { log.error("Json轉換異常:{}", e); } return "Json轉換異常";}/** * json轉對象 * @param jsonData json串 * @param beanType 對象 * @return 對象 */public static <T> T jsonToPojo(String jsonData, Class<T> beanType) { try { T obj = MAPPER.readValue(jsonData, beanType); return obj; } catch (Exception e) { log.error("Json轉換異常:{}", e); } return null;}}
···

3.SDK代碼,Java舉例

DefaultZrscClient

public class DefaultZrscClient implements ZrscClient { private String serverUrl; private String accessToken; private int connectTimeout; private int readTimeout; private String appKey; private String fuzz; private String appSecret; public DefaultZrscClient(String serverUrl, String accessToken, String appKey, String appSecret) { this.connectTimeout = 8000; this.readTimeout = 8000; this.serverUrl = serverUrl; this.accessToken = accessToken; this.appKey = appKey; this.appSecret = appSecret; } public <T extends AbstractResponse> T execute(ZrscRequest<T> request) throws ZrscException { try { String url = this.buildUrl(request); Map<String, String> params = new HashMap(); String json = request.getAppJsonParams(); params.put("zrsc_param_json", json); if (request.getOtherParams() != null) { params.put("other", request.getOtherParams()); } String rsp = HttpUtil.doPost(url, params, this.connectTimeout, this.readTimeout,this.accessToken); T resp = this.parse(rsp, request.getResponseClass()); StringBuffer sb = new StringBuffer(); sb.append(url).append("&").append("zrsc_param_json").append("=").append(json); resp.setUrl(sb.toString()); return resp; } catch (Exception var8) { var8.printStackTrace(); throw new ZrscException("出現異常,請重試"); } } private <T extends AbstractResponse> String buildUrl(ZrscRequest<T> request) throws Exception { Map<String, String> sysParams = request.getSysParams(); Map<String, String> pmap = new TreeMap(); pmap.put("zrsc_param_json", request.getAppJsonParams()); sysParams.put("method", request.getApiMethod()); sysParams.put("access_token", this.accessToken); sysParams.put("app_key", this.appKey); pmap.putAll(sysParams); String sign = this.sign(pmap, this.appSecret); sysParams.put("sign", sign); StringBuilder sb = new StringBuilder(this.serverUrl); sb.append("?"); sb.append(HttpUtil.buildQuery(sysParams, "UTF-8")); return sb.toString(); } private <T extends AbstractResponse> T parse(String rsp, Class<T> responseClass) throws ZrscException { Parser parser; if (this.serverUrl.endsWith("json")) { parser = ParserFactory.getJsonParser(); } else { parser = ParserFactory.getXmlParser(); } return parser.parse(rsp, responseClass); } private String sign(Map<String, String> pmap, String appSecret) throws Exception { StringBuilder sb = new StringBuilder(appSecret); Iterator i$ = pmap.entrySet().iterator(); while(i$.hasNext()) { Map.Entry<String, String> entry = (Map.Entry)i$.next(); String name = (String)entry.getKey(); String value = (String)entry.getValue(); if (StringUtil.areNotEmpty(new String[]{name, value})) { sb.append(name).append(value); } } sb.append(appSecret); String result = CodecUtil.md5(sb.toString()); return result; }}HttpUtil

public class HttpUtil { public static final String DEFAULT_CHARSET = "UTF-8"; private static final String METHOD_POST = "POST"; private HttpUtil() { throw new UnsupportedOperationException(); } public static String buildQuery(Map<String, String> params, String charset) throws Exception { if (params != null && !params.isEmpty()) { StringBuilder query = new StringBuilder(); Set<Entry<String, String>> entries = params.entrySet(); boolean hasParam = false; Iterator i$ = entries.iterator(); while(i$.hasNext()) { Entry<String, String> entry = (Entry)i$.next(); String name = (String)entry.getKey(); String value = (String)entry.getValue(); if (StringUtil.areNotEmpty(new String[]{name, value})) { if (hasParam) { query.append("&"); } else { hasParam = true; } query.append(name).append("=").append(URLEncoder.encode(value, charset)); } } return query.toString(); } else { return null; } } public static String doPost(String url, Map<String, String> params, int connectTimeout, int readTimeout,String token) throws Exception { return doPost(url, params, "UTF-8", connectTimeout, readTimeout,token); } public static String doPost(String url, Map<String, String> params, String charset, int connectTimeout, int readTimeout,String token) throws Exception { String ctype = "application/x-www-form-urlencoded;charset=" + charset; //String ctype = "application/json;charset=" + charset; String query = buildQuery(params, charset); byte[] content = new byte[0]; if (query != null) { content = query.getBytes(charset); } return doPost(url, ctype, content, connectTimeout, readTimeout,token); } public static String doPost(String url, String ctype, byte[] content, int connectTimeout, int readTimeout,String token) throws IOException { HttpURLConnection conn = null; OutputStream out = null; String rsp = null; try { conn = getConnection(new URL(url), "POST", ctype,token); conn.setConnectTimeout(connectTimeout); conn.setReadTimeout(readTimeout); out = conn.getOutputStream(); out.write(content); rsp = getResponseAsString(conn); } finally { if (out != null) { out.close(); } if (conn != null) { conn.disconnect(); } } return rsp; } private static HttpURLConnection getConnection(URL url, String method, String ctype,String token) throws IOException { HttpURLConnection conn = null; if ("https".equals(url.getProtocol())) { SSLContext ctx = null; try { ctx = SSLContext.getInstance("TLS"); ctx.init(new KeyManager[0], new DefaultTrustManager[]{new DefaultTrustManager()}, new SecureRandom()); } catch (Exception var6) { throw new IOException(var6); } HttpsURLConnection connHttps = (HttpsURLConnection)url.openConnection(); connHttps.setSSLSocketFactory(ctx.getSocketFactory()); connHttps.setHostnameVerifier(new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }); conn = connHttps; } else { conn = (HttpURLConnection)url.openConnection(); } ((HttpURLConnection)conn).setRequestMethod(method); ((HttpURLConnection)conn).setDoInput(true); ((HttpURLConnection)conn).setDoOutput(true); ((HttpURLConnection)conn).setRequestProperty("Accept", "text/xml,text/javascript,text/html"); ((HttpURLConnection)conn).setRequestProperty("User-Agent", "kcb-sdk-java"); ((HttpURLConnection)conn).setRequestProperty("Content-Type", ctype); ((HttpURLConnection)conn).setRequestProperty("Authorization", token); return (HttpURLConnection)conn; } protected static String getResponseAsString(HttpURLConnection conn) throws IOException { String charset = getResponseCharset(conn.getContentType()); InputStream es = conn.getErrorStream(); if (es == null) { return getStreamAsString(conn.getInputStream(), charset); } else { String msg = getStreamAsString(es, charset); if (StringUtil.isEmpty(msg)) { throw new IOException(conn.getResponseCode() + ":" + conn.getResponseMessage()); } else { throw new IOException(msg); } } } private static String getStreamAsString(InputStream stream, String charset) throws IOException { try { BufferedReader reader = new BufferedReader(new InputStreamReader(stream, charset)); StringWriter writer = new StringWriter(); char[] chars = new char[256]; boolean var5 = false; int count; while((count = reader.read(chars)) > 0) { writer.write(chars, 0, count); } String var6 = writer.toString(); return var6; } finally { if (stream != null) { stream.close(); } } } private static String getResponseCharset(String ctype) { String charset = "UTF-8"; if (!StringUtil.isEmpty(ctype)) { String[] params = ctype.split(";"); String[] arr$ = params; int len$ = params.length; for(int i$ = 0; i$ < len$; ++i$) { String param = arr$[i$]; param = param.trim(); if (param.startsWith("charset")) { String[] pair = param.split("=", 2); if (pair.length == 2 && !StringUtil.isEmpty(pair[1])) { charset = pair[1].trim(); } break; } } } return charset; } private static byte[] getTextEntry(String fieldName, String fieldValue, String charset) throws IOException { StringBuilder entry = new StringBuilder(); entry.append("Content-Disposition:form-data;name=/""); entry.append(fieldName); entry.append("/"/r/nContent-Type:text/plain/r/n/r/n"); entry.append(fieldValue); return entry.toString().getBytes(charset); } private static byte[] getFileEntry(String fieldName, String fileName, String mimeType, String charset) throws IOException { StringBuilder entry = new StringBuilder(); entry.append("Content-Disposition:form-data;name=/""); entry.append(fieldName); entry.append("/";filename=/""); entry.append(fileName); entry.append("/"/r/nContent-Type:"); entry.append(mimeType); entry.append("/r/n/r/n"); return entry.toString().getBytes(charset); }}

4.集成SDK,代碼舉例

@Test void getAddress() throws IOException { Address2provicecityRequest request=new Address2provicecityRequest(); request.setAddress("阿膠街東首路北"); ZrscClient client = new DefaultZrscClient(serverUrl, accessToken, appKey, appSecret); try { Address2provicecityResponse response= client.execute(request); System.out.println("data="+JsonUtil.toJson(response.getData())); } catch (Exception e) { e.printStackTrace(); } }運行結果:

data={"source":"阿膠街東首路北","province":"山東省","city":"聊城市","area":"東阿縣","street":"新城街道","addressInfo":"阿膠街東首路北"}
京東開放平臺中的傳參和簽名算法比較有代表性,此博客,只是分享開放平臺開放的主要組成部分,供大家學習,后期有時間,我把項目代碼整理一下,分享給大家。

轉自:秋九

關鍵詞:平臺,需求,包含,服務

74
73
25
news

版權所有? 億企邦 1997-2025 保留一切法律許可權利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點擊下載Chrome瀏覽器
關閉