目录

1开放平台需求
1.1调用参数
1.2签名算法

2服务端代码,Java举例
2.1接口入口代码
2.2业务逻辑层
2.3基础工具类

3.SDK代码,Java举例

4.集成SDK,代码举例

现在开放平台越来越多了,下面针对仿京东开放平台框架,封装自己的开放平台,分享给大家。

先感谢一下京东开放平台的技术大佬们,下面从开放平台需求,服务端代码,SDK代码三大块进行分享,有不足之处,欢迎在评论区留言。

1开放平台需求

用户需要按照开放平台的协议规范拼装一个正确的URL,通过Https请求到开放平台既能够获取到所需数据。主要流程包含:填写参数、生成签名、拼装HTTPS请求、发起请求、得到响应结果、解析结果。

1.1调用参数

系统参数:调用任何一个API都需要传入的参数,目前支持的系统参数是:

应用级参数(更多API应用参数参考 接口文档)

1.2签名算法

为了防止API在调用过程中被恶意者拦截随意篡改,调用API是需要传入签名参数,开放平台服务端会根据请求参数对签名进行验证,判断请求参数是否合法。开放平台签名规则过程如下:

将所有请求参数按照字母先后顺序排列,例如: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,业务逻辑写在Service。同时考虑安全性和方便排查问题,会加入输入性校验和访问日志。

2.1接口入口代码

接口只有一个入口,即Controller代码如下:

@Controller
public class RouterController {@Resourceprivate RouterService routerService;@Resourceprivate OpenApiLogService openApiLogService;/*** API接口路由器,接口入口** @param request* @param zrsc_param_json* @return*/@RequestMapping(value = "routerjson", method = RequestMethod.POST)@ResponseBodypublic 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业务逻辑层

业务逻辑层,简单举例说明,不同业务有所不同。

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)) {//获取省市区街道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;//状态码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,代码举例

@Testvoid 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":"阿胶街东首路北"}

京东开放平台中的传参和签名算法比较有代表性,此博客,只是分享开放平台开放的主要组成部分,供大家学习,后期有时间,我把项目代码整理一下,分享给大家。


http://www.taodudu.cc/news/show-5744702.html

相关文章:

  • 黑苹果N卡的驱动在2022年6月1日后安装失败的解决办法
  • 微信小程序实现星星评分组件(原生)
  • 微信小程序自定义评分小组件
  • 微信小程序评分组件Rate
  • 机器学习之linear_model(普通最小二乘法手写+sklearn实现+评价指标)
  • 小学生是祖国未来的花朵
  • AI小技巧—花朵
  • 使用PyTorch实现对花朵的分类
  • 保护花朵
  • 花朵数算法
  • 微信小程序星星评分组件
  • sklearn 回归 算法 最小二乘法
  • sklearn 使用最小二乘法
  • 花朵数c语言算法,21位花朵数(详解)
  • 架构设计流程
  • 诗人
  • casio计算机按键,卡西欧按键功能
  • 电脑的一些基础按键
  • Ubuntu系统正常连接外接显示器
  • 八大秘诀教你选显示器
  • 为什么表情包越糊就越吸引人
  • 挑战最美博客
  • JavaScript实战篇 -ajax方式实现js打包下载文件
  • 植肤兰护肤化妆品女性身边不可或缺的变美法宝
  • 植肤兰护肤品市场中连锁加盟店无数
  • 为什么现在的女生一定要花那么多钱在护肤品化妆品上面?
  • 全球唯一从种植到生产都天然的护肤品茱莉蔻进军中国电商首选京东
  • 从护肤品到北斗/GPS双模定位模块应该怎么选
  • java护肤品购物系统计算机毕业设计MyBatis+系统+LW文档+源码+调试部署
  • 女人护肤食品

仿京东开放平台框架,开发自己的开放平台(包含需求,服务端代码,SDK代码)...相关推荐

  1. TinkPHP内核仿每推推51领啦试客源码_PC源码+WAP端+APP原生代码_自带5套精美模板

    TinkPHP内核仿每推推51领啦试客源码_PC源码+WAP端+APP原生代码_自带5套精美模板 源码说明:TinkPHP内核上制作而成,是全国领先的免费试用网站!程序全开源无加密!带有wap手机端, ...

  2. 前端开发全家桶:UI组件 开发框架 服务端 辅助工具 应用实例 Demo示例

    element ★11612 - 饿了么出品的Vue2的web UI工具套件 Vux ★7503 - 基于Vue和WeUI的组件库 iview ★5801 - 基于 Vuejs 的开源 UI 组件库 ...

  3. Vue+koa2开发一款全栈小程序(服务端环境搭建和项目初始化)

    1.微信公众平台小程序关联腾讯云 腾讯云的开发环境是给免费的一个后台,但是只能够用于开发,如果用于生产是需要花钱的,我们先用开发环境吧 1.用小程序开发邮箱账号登录微信公众平台 2.[设置]→[开发者 ...

  4. java nio 客户端_Java网络编程:Netty框架学习(二)---Java NIO,实现简单的服务端客户端消息传输...

    概述 上篇中已经讲到Java中的NIO类库,Java中也称New IO,类库的目标就是要让Java支持非阻塞IO,基于这个原因,更多的人喜欢称Java NIO为非阻塞IO(Non-Block IO), ...

  5. android 仿京东地址选择_Android 开发:仿美团地址选择

    最近做了这个功能,分享一下,用的是百度地图api,和美团外卖的地址选择界面差不多,也就是可以搜索或者滑动地图展示地址列表给用户选择,看下效果图先. 文章重点 展示地图并定位到"我" ...

  6. java cxf服务端_webservice概述及cxf在Java开发中应用(二) 简单搭建cxf服务端

    首先我们下载cxf的jar包,我这里下载的是apache-cxf-3.0.4这个版本,目前最新的. Eclipse里面新建一个Java project,在工程中引入需要的jar: 这些包里面包含了je ...

  7. 【开发一个简单的音乐播放器+服务端】【一】

  8. SpringBoot使用cxf框架开发WebServices以及配置安全验证机制

    SpringBoot使用cxf框架开发WebServices以及配置安全验证机制 服务端工程 服务接口的实现 服务接口实现类 服务发布类 启动服务端 客户端工程 生成客户端代码 编写客户端代码 客户端 ...

  9. 钉钉 6.0 开放底层“协同框架” 开发多人实时协作程序像编本地程序一样简单...

    2021 年新年伊始,钉钉在 1 月 14 日发布了最新 6.0 版本,同时宣布战略定位全面升级,钉钉将从过去基于IM的协同办公平台,升级为企业协同办公和应用开发平台. 从产品和市场表现,钉钉已经杀出 ...

  10. 数据自治开放的软件开发和运行环境

    数据自治开放的软件开发和运行环境 吴毅坚1,2, 陈士壮1,2, 葛佳丽1,2, 赵文耘1,2 1. 复旦大学计算机科学技术学院,上海 201203 2. 上海市数据科学重点实验室,上海 201203 ...

最新文章

  1. java 抢单功能设计_java毕业设计_springboot框架的抢单兼职
  2. mysql搭建主主_mysql主主配置
  3. 前端学习(2666):完成vue3.0的todolist编辑
  4. Robotium体验----白盒
  5. echarts Map(地图) 波纹数据点
  6. word2016标题序号变黑色竖线解决方法
  7. 转 为什么数码相机可以拍出彩色照片?
  8. android 软引用intent对象,Android中的软引用(SoftRefrerence)和弱引用(WeakReference)
  9. 【LSR标签平滑理解】
  10. 高等数学(第七版)同济大学 习题12-7 个人解答
  11. 机器学习 - 线性模型
  12. 05_网站日志数据分析
  13. 【SSL】2021-08-19 1045.采药
  14. 2021高考成绩查询省排名,2021年全国高考难度省份排名 高考最难的省份排名公布...
  15. Nginx配置模块详解及多站点共用80端口案例
  16. 大疆文档(9)-Android教程-GEO系统App
  17. 开发新人有必要考虑在工作一年后跳槽
  18. 【论文精读】Superpixel Sampling Networks(SSN)
  19. VPI step by step(1)
  20. 把握两点要素 新闻稿轻松写

热门文章

  1. 附加的文件超过了服务器,将大文件附加到 Outlook 邮件或事件
  2. jquery实现群星闪烁的效果
  3. word tab 支持 word 2010
  4. 【信贷业务】金融信贷存量客户运营管理
  5. python建立简单的数据库_学会最简单的数据库|看完这7招就够了
  6. pubg服务器维护查询,pubg服务器维护中
  7. 苹果7支持快充吗_iPhone12支持防水功能吗 苹果12防水性能怎么样
  8. php获取div高度,JS获取一个未知DIV高度的方法
  9. iphone 软键盘设置参数说明
  10. JAVA中静态方法的调用