精华内容
下载资源
问答
  • 网站api接口对接教程
    千次阅读
    2021-06-03 10:56:40

    编写总结不易 点赞关注收藏三连一波 哈哈哈
    使用axios请求库前提
    封装 axios 工具,编辑 src/api/index.js 文件
    首先,我们要使用 axios 工具,就必须先安装 axios 工具。执行下面的命令进行安装

    npm install axios -D

    由于宿舍翻墙条件不好,这里使用 cnpm 替代

    这样,我们就安装好了 axios 工具了。

    一 ,
    新建了一个 src/api/index.js
    配置封装axios请求

    // 配置API接口地址
    var root = 'https://cnodejs.org/api/v1'  //写死的地址
    var root = '/apis';   //动态切换  配合配置文件   正常是config文件
    // 引用axios
    var axios = require('axios')
    // 自定义判断元素类型JS
    function toType (obj) {
      return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
    }
    // 参数过滤函数
    function filterNull (o) {
      for (var key in o) {
        if (o[key] === null) {
          delete o[key]
        }
        if (toType(o[key]) === 'string') {
          o[key] = o[key].trim()
        } else if (toType(o[key]) === 'object') {
          o[key] = filterNull(o[key])
        } else if (toType(o[key]) === 'array') {
          o[key] = filterNull(o[key])
        }
      }
      return o
    }
    

    /*
    接口处理函数
    这个函数每个项目都是不一样的,我现在调整的是适用于
    https://cnodejs.org/api/v1 的接口,如果是其他接口
    需要根据接口的参数进行调整。参考说明文档地址:
    https://cnodejs.org/topic/5378720ed6e2d16149fa16bd
    主要是,不同的接口的成功标识和失败提示是不一致的。
    另外,不同的项目的处理方法也是不一致的,这里出错就是简单的alert
    */

    function apiAxios (method, url, params, success, failure) {
      if (params) {
        params = filterNull(params)
      }
      axios({
        method: method,
        url: url,
        data: method === 'POST' || method === 'PUT' ? params : null,
        params: method === 'GET' || method === 'DELETE' ? params : null,
        baseURL: root,
        withCredentials: false
      })
      .then(function (res) {
        if (res.data.success === true) {
          if (success) {
            success(res.data)
          }
        } else {
          if (failure) {
            failure(res.data)
          } else {
            window.alert('error: ' + JSON.stringify(res.data))
          }
        }
      })
      .catch(function (err) {
        let res = err.response
        if (err) {
          window.alert('api error, HTTP CODE: ' + res.status)
        }
      })
    }
    
    
    // 返回在vue模板中的调用接口
    export default {
      get: function (url, params, success, failure) {
        return apiAxios('GET', url, params, success, failure)
      },
      post: function (url, params, success, failure) {
        return apiAxios('POST', url, params, success, failure)
      },
      put: function (url, params, success, failure) {
        return apiAxios('PUT', url, params, success, failure)
      },
      delete: function (url, params, success, failure) {
        return apiAxios('DELETE', url, params, success, failure)
      }
    }
    

    调整 main.js 绑定 api/index.js 文件
    因为原始文件就配置得比较好,就是加上两行定义
    原始是

    import Vue from 'vue'
    import App from './App'
    import router from './router'
    
    
    Vue.config.productionTip = false
    
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      template: '<App/>',
      components: { App }
    })
    修改添加后
    
    
    import Vue from 'vue'
    import App from './App'
    import router from './router'
    
    
    // 引用API文件
    import api from './api/index.js'
    // 将API方法绑定到全局
    Vue.prototype.$api = api
    
    
    Vue.config.productionTip = false
    
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      template: '<App/>',
      components: { App }
    })
    

    修改一下 src/page/index.vue 文件,将代码调整为以下代码:

    <template>
      <div>index page</div>
    </template>
    <script>
    export default {
      created () {
        this.$api.get('topics', null, r => {
          console.log(r)
        })
      }
    }
    </script>
    

    这里是调用 cnodejs.org 的 topics 列表接口,并且将结果打印出来。
    https://img-blog.csdn.net/20170826143745291?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRnVuZ0xlbw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
    以上是所有人可以调试的接口 以及写死的接口
    以下是个人动态的接口以及代理配置 因为是开发环境需要
    至于为什么会需要代理 是因为跨域问题 具体各位百度 个人知识浅薄 可能讲的不好
    配置文件 vue.config.js
    位置在项目根目录下(因为好多博客并不说明文件位置 像我一样小白会当初傻逼)

    const vueConfig = {
      devServer: {
        // development server port 8000
        port: 8085,
        // If you want to turn on the proxy, please remove the mockjs /src/main.jsL11
        proxy: {
          '/apis': {
    //  /apis对接匹配你接口文件的之后动态的路径
            target: 'http://116.199.15.19:8070/apis',
            // target: 'http://192.168.3.105:8001',
            ws: false,
            changeOrigin: true,
            pathRewrite: {
              '^/apis': '/',
            },
          },
          '/files': {
            target: 'http://116.199.15.19:8070/files',
            ws: false,
            changeOrigin: true,
            pathRewrite: {
              '^/files': '/',
            },
          },
        },
      },
    };
    module.exports = vueConfig;
    

    到此你接口配置好了 接下来就是对于接口url接上具体的文件名称之类,以及对于验证参数的传参之类的 以下是我的登录验证 src/view/login.vue
    handlevalue()方法就是对接口进行补充传参验证做路由跳转

    <template>
      <div id="components-layout-demo-basic">
        <a-layout class="layout-login">
          <a-layout-header>
            <div>
              <div>
                <img src="@/assets/logo-header.svg" alt="" style="height: 44px; margin-right: 16px; border-style: none" />
                <span class="header-title">Ant Design</span>
              </div>
    
    
              <div class="desc">Ant Design 是西湖区最具影响力的 Web 设计规范</div>
            </div>
          </a-layout-header>
          <a-layout-content class="content-body">
            <div class="content-header">
              <a-tabs default-active-key="1" @change="callback">
                <a-tab-pane key="1" tab="账户密码登录">
                  <a-form id="components-form-demo-normal-login" :form="form" class="login-form" @submit="handleSubmit">
                    <a-form-item style="text-align: left">
                      <a-input
                        v-decorator="['userName', { rules: [{ required: true, message: '请输入帐户名或邮箱地址' }] }]"
                        class="input-header"
                        placeholder="账户: admin"
                        size="large"
                      >
                        <a-icon slot="prefix" type="user" style="color: rgba(0, 0, 0, 0.25)" />
                      </a-input>
                    </a-form-item>
                    <a-form-item style="text-align: left">
                      <a-input-password
                        v-decorator="['password', { rules: [{ required: true, message: '请输入密码!' }] }]"
                        type="password"
                        placeholder="密码: admin or ant.design"
                        size="large"
                        userName
                      >
                        <a-icon slot="prefix" type="lock" style="color: rgba(0, 0, 0, 0.25)" />
                      </a-input-password>
                    </a-form-item>
                    <!-- <a-form-item>
                      <a-checkbox
                        v-decorator="[
                          'remember',
                          {
                            valuePropName: 'checked',
                            initialValue: true,
                          },
                        ]"
                        class="checkbox-left"
                      >
                        记住密码
                      </a-checkbox>
                      <a class="login-form-forgot" href=""> 自动登录 </a>
                      <a-button type="primary" html-type="submit" class="login-form-button"> 登录 </a-button>
                      Or
                      <a href=""> register now! </a>
                    </a-form-item> -->
                  </a-form>
                </a-tab-pane>
                <a-tab-pane key="2" tab="手机号登录" force-render style="text-align: left">
                  <a-form id="components-form-demo-normal-login" :form="form" class="login-form" @submit="handleSubmit">
                    <a-form-item>
                      <a-input
                        v-decorator="['phone', { rules: [{ required: true, message: '请输入手机号' }] }]"
                        class="input-header"
                        placeholder="手机号"
                        size="large"
                      >
                        <a-icon slot="prefix" type="mobile" style="color: rgba(0, 0, 0, 0.25)" />
                      </a-input>
                    </a-form-item>
                    <a-form-item @submit="handleSubmit">
                      <span>
                        <a-input
                          v-decorator="['verificationCode', { rules: [{ required: true, message: '请输入验证码!' }] }]"
                          type="password"
                          placeholder="验证码"
                          size="large"
                          style="float: left; width: 65%"
                        >
                          <a-icon slot="prefix" type="mail" style="color: rgba(0, 0, 0, 0.25)" />
                        </a-input>
                        <a-button size="large" style="float: right; font-size: 14px; width: 30%" html-type="submit"> 获取验证码 </a-button></span
                      >
                    </a-form-item>
                  </a-form>
                </a-tab-pane>
              </a-tabs>
            </div>
            <div class="content-header">
              <a-form id="components-form-demo-normal-login" class="login-form" @submit="handleSubmit">
                <a-form-item>
                  <a-checkbox
                    v-decorator="[
                      'remember',
                      {
                        valuePropName: 'checked',
                        initialValue: true,
                      },
                    ]"
                    class="checkbox-left"
                    >自动登录
                  </a-checkbox>
                  <a class="login-form-forgot" href=""> 忘记密码 </a>
    
    
                  <a-button size="large" type="primary" class="login-form-button" html-type="submit" @click="handlevalue()">登录</a-button>
                  <!-- <router-link :to="{ path: this.routervalue }">登录</router-link> -->
                </a-form-item>
                <div style="text-align: left">
                  <span style="float: left">其他登录方式</span><a-icon class="icon-all" type="alipay" /><a-icon class="icon-all" type="taobao" /><a-icon
                    class="icon-all"
                    type="weibo"
                  />
                  <a style="float: right" href=""> 注册账户 </a>
                </div>
              </a-form>
            </div>
          </a-layout-content>
          <a-layout-footer class="footer">
            <div style="padding-left: 40px; margin-bottom: 8px">
              <span style="padding-right: 40px">帮助</span><span style="padding-right: 40px">隐私</span><span style="padding-right: 40px">条款</span>
            </div>
            <div>Copyright © 2018 vueComponent</div>
          </a-layout-footer>
        </a-layout>
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          routervalue: '',
          name: '',
          password: '',
          // status: '',
          // name: this.form.getFieldValue('userName'),
          // form: [
          //   {
          //     password: '',
          //     userName: '123',
          //     phone: '',
          //     verificationCode: '',
          //   },
          // ],
        };
      },
      beforeCreate() {
        this.form = this.$form.createForm(this, { name: 'normal_login' });
      },
    
    
      mounted() {},
      methods: {
        callback(key) {
          // console.log(key);
        },
        handlevalue() {
          this.name = this.form.getFieldValue('userName');
          this.password = this.form.getFieldValue('password');
          this.$api.post('/auth/login', { userName: this.name, password: this.password }, (r) => {
            const status = '';
            this.status = r.success;
            // console.log(this.status);
            // console.log(this.name);
            // console.log(this.password);
            if ((this.status = true)) {
              this.routervalue = '/home';
    
    
              console.log(this.status);
              console.log(this.form.getFieldValue('password'));
              console.log(this.name);
              this.$router.push(this.routervalue);
            }
          });
        },
    
    
        handleSubmit(e) {
          e.preventDefault();
          this.form.validateFields((err, values) => {
            if (!err) {
              console.log('Received values of form: ', values);
            }
          });
        },
      },
    };
    </script>
    <style>
    #components-layout-demo-basic {
      text-align: center;
    }
    #components-layout-demo-basic .ant-layout-header,
    #components-layout-demo-basic .ant-layout-footer {
      background: transparent;
      /* color: red; */
    }
    #components-layout-demo-basic .ant-layout-footer {
      line-height: 1.5;
    }
    
    
    #components-layout-demo-basic .ant-layout-content {
      background: transparent;
      /* color: red; */
      /* min-height: 120px; */
      line-height: 120px;
    }
    #components-layout-demo-basic > .ant-layout {
      margin-bottom: 48px;
    }
    #components-layout-demo-basic > .ant-layout:last-child {
      margin: 0;
    }
    .layout-login {
      width: 100%;
      min-height: 540px;
      background: #f0f2f5 url(../assets/bg-login.svg) no-repeat 50%;
      background-size: 100%;
      position: relative;
      padding: 54px 0 74px;
    }
    .header-title {
      font-size: 33px;
      color: rgba(0, 0, 0, 0.85);
      font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
      font-weight: 600;
      position: relative;
      top: 10px;
    }
    .desc {
      font-size: 14px;
      color: rgba(0, 0, 0, 0.45);
      line-height: 0px;
      margin-top: 15px;
      margin-bottom: 40px;
    }
    .content-header {
      margin-top: 200px;
      width: 368px;
      /* height: 350px; */
      overflow: auto;
      margin: auto;
      /* position: absolute;
      top: 250px;
      left: 0;
      right: 0; */
    }
    .content-body {
      margin-top: 70px;
    }
    .checkbox-left {
      float: left;
    }
    .input-header {
      height: 40px;
    }
    .icon-all {
      /* color: rgba(0, 0, 0, 0.2); */
      color: #f0f2f5;
      font-size: 18px;
      background-color: rgb(192, 194, 196);
      border-radius: 20px;
      margin-left: 16px;
      padding: 3px;
    }
    .footer {
      width: 100%;
      bottom: 0;
      padding: 0 16px;
      margin: 48px 0 24px;
      text-align: center;
    
    
      color: rgba(0, 0, 0, 0.45);
    }
    /* 表单 */
    #components-form-demo-normal-login .login-form {
      max-width: 300px;
    }
    #components-form-demo-normal-login .login-form-forgot {
      float: right;
    }
    #components-form-demo-normal-login .login-form-button {
      width: 100%;
      margin-top: 24px;
    }
    </style>
    

    参考https://blog.csdn.net/fungleo/article/details/77601761
    编写总结不易 点赞关注收藏三连一波 哈哈哈

    更多相关内容
  • API对接实战

    千次阅读 多人点赞 2020-09-26 21:23:00
    在平时工作中,经常会遇到的一种场景是:A公司要对接B公司的API方法,这时,A公司就要阅读B公司的接口文档,从接口文档中找到自己需要对接API,并根据接口文档的要求,完成编码工作,最终完成对接工作。...

    目录

    一 背景

    二 了解B公司接口的基础约定

    三 基础域名

    四 请求及相应格式说明

    五 确定要对接哪些API

    六 根据API文档,编写一些基础工具类。

    七 根据API文档,编写必要的DTO

    八 针对每个API方法,进行对接

    九 对接代码结构

    十 一些对接技巧


    一 背景

    在平时工作中,经常会遇到的一种场景是:A公司要对接B公司的API方法,这时,A公司就要阅读B公司的接口文档,从接口文档中找到自己需要对接的API,并根据接口文档的要求,完成编码工作,最终完成对接工作。

    本篇是站在A公司的角度,去对接B公司API接口的实战。

    二 了解B公司接口的基础约定

    一般情况下,B公司都会给出以下类似约定来满足基础对接,并且会提供测试环境和正式环境的两套信息。

    appkey:A公司商户平台 id

    appsecret:A公司商户平台 secret

    三 基础域名

    一般情况下,B公司会提供测试环境和生产环境两个基础域名。

    例如

    测试环境 : https://api-b-dev.com.cn

    生产环境 : https://api-b-prod.com.cn

    四 请求及相应格式说明

    一般情况下,B公司会提供请求及相应的基础格式说明。

    例如:

    1 请求方式

    post

    2 请求消息格式

    application/json

    3 响应消息格式

    application/json

    4 请求公共参数

    例如,B公司有以下要求

    所有接口均需要以 Http Header 方式传递以下参数;

    参数名

    描述

    必填

    appkey

    商户平台 id

    request_id

    请求标识 ,每次请求唯一

    sign_type

    签名方法,固定为 sha256

    signature

    签名,算法为 HMACSHA256(appkey+timestamp+appsecret,appsecret)

    version

    版本, 固定为 2.0

    callback_url

    回调地址, 以 https://或者 http://开头并进行 base64 编码

    是(同步响应的接口可不必填写)

    timestamp

    时间戳(秒), 30 分钟过期

    当然,不同的公司提供的参数各不相同,因公司而异。

    5 响应/回调参数说明

    例如:B公司所有API都有响应,并且有的API还有回调响应,不论是响应还是回调响应,它们的参数格式都一样。

    参数

    类型

    描述

    code

    int

    状态码

    msg

    String

    消息

    request_id

    String

    请求时的 request_id

    data

    Object

    数据

    appkey

    String

    商户平台id

    6 针对异步回调的说明

    例如:B公司对异步回调说明如下:

    异步回调:

    某些特定的接口需要异步返回结果,因此需商户A提供一个回调地址,将其进行base64 编码后,配置在 Http 请求 Header 中的 callback_url 里。

    应答机制:

    应答机制是指当商户A收到B公司数据通知时,必须回写 success 字符串,不区分大小写,B公司收到该“ success”,便认为商户A已收到通知; 否则会继续重复请求回调接口 3 次, 时间间隔为 1s, 5s, 30s。如果 4 次都访问不通,则会间隔 3h 继续轮询回调。

    回调解密:

    回调使用 aes 加密,需解密后使用。为避免由于网络波动造成回调失败,长时间未收到回调,请主动查询。

    7 请求体加密说明及示例

    数据采用AES加密,加密后作为data的值。

    示例:

    加密前:

    {"settlement_code":["JS19BUB14F5D8D4C"],"random_code":["19BUB14F5D8D4C","19BUAD0E89D780"]}

    加密后:

    {"data":"236agZcupcSsMZghtlmzhb7lEWzGZc3FO5GWQyrSB5kP/y1ESvd+CuBgQiWU/fwAICY/s0mideku/rXSKEb8In41F4SkUVLyLzYoYGed4QTjsqohTM0T6wmbkOiT1TH3"}

    对 {"settlement_code":["JS19BUB14F5D8D4C"],"random_code":["19BUB14F5D8D4C","19BUAD0E89D780"]} 进行AES加密,结果为:

    236agZcupcSsMZghtlmzhb7lEWzGZc3FO5GWQyrSB5kP/y1ESvd+CuBgQiWU/fwAICY/s0mideku/rXSKEb8In41F4SkUVLyLzYoYGed4QTjsqohTM0T6wmbkOiT1TH3

    8 回调解密说明以及示例

    数据采用AES解密,解密data值部分,解密后是json字符串

    解密前:

    {
        "code":0,"
        "msg":"处理成功",
        "request_id":"47fbb4ce-ae8e-4276-9d4a-4d279c9dfa78",
        "data":"TI6H4Zx7YeWM0dSiial6L+nCvrEv8Oqk1ZFhWXqYZcRzzZyy/xECQW0nf
                DszpNDmRMlSmsWkBJMmu4a/PmBivUBoNJwFBzAnOfn8gtYKdxDU16lDFwN5d/I
                W1UJijJ2lU5YkDs/rMTyRN1NTR+0vJ1So0lmeZQiGQWEwE5t4wZykSC3cMQZyvJ95
                2J7KU6aBXv1ZUGncZbWHQQaLw4UxFaBWIO8bVlkBIAqzolswI4dhtqBzFwmdEx+7
                hzHSeidOVbIja5adgKMAjvIUTdtUEb/cO0ipO6QbK8wglk6dQ8+7rFTchBYIoaaqM9Sf
                hcdvAYuSGk6yHIyN4GEtLBA5Zw==",
        "appkey":"47fbb4ce-ae8e-4276-9d4a-4d279c9dfa78"
    }

    解密后:

    {
        "code":0,"
        "msg":"处理成功",
        "request_id":"47fbb4ce-ae8e-4276-9d4a-4d279c9dfa78",
        "data":
        {
            "settlement_code":"JS19BR19A690E9F9",
            "order_random_code":"09708757-7ea1-4fda",
            "refund_merchant_amount":54736.84,
            "refund_service_amount":263.16,
            "change_code":"FW19BRAA9A200255",
            "change_merchant_amount":4263.16,
            "change_service_amount":236.84
        },
        "appkey":"47fbb4ce-ae8e-4276-9d4a-4d279c9dfa78"
    }

    9 一般公司B还会对code值进行说明。

    五 确定要对接哪些API

    一般情况下,公司B会针对某个项目提供必要的API,我们往往只需要对接少部分API接口,因此,首先确认要对接哪些API方法。我们只需要按照API的要求进行对接即可。

    六 根据API文档,编写一些基础工具类。

    工具类分两类。一类工具类,公司B会提供DEMO,我们拿来用即可。另外一类就需要自己根据API要求自己编写了。

    1 公司B提供的基础工具类

    例如,公司B提供了AES加解密以及签名的工具类

    import org.apache.commons.codec.binary.Base64;
    
    import javax.crypto.Cipher;
    import javax.crypto.Mac;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    import java.security.Security;
    
    /**
    * AES加解密工具
    */
    public class EncryptUtil {
        private static final String CipherMode="AES/CBC/PKCS7Padding";
    
        private static final String EncryptAlg ="AES";
    
        private static final String Encode="UTF-8";
    
        private static final String APPSECRET = "7da8046aa2da46bfb08429058e910081";
    
        private static final String AESIV = "ff465fdecc764337";
        /**
         * 加密:有向量16位,结果转base64
         * @param context
         * @return
         */
        public static String encrypt(String context) {
            try { //下面这行在进行PKCS7Padding加密时必须加上,否则报错
                Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
                byte[] content=context.getBytes(Encode);
                Cipher cipher = Cipher.getInstance(CipherMode);
                cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(APPSECRET.getBytes(Encode), EncryptAlg), new IvParameterSpec(AESIV.getBytes(Encode)));
                byte[] data = cipher.doFinal(content);
                String result= Base64.encodeBase64String(data);
                return result;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 解密
         * @param context
         * @return
         */
        public static String decrypt(String context) {
            try {
                byte[] data=Base64.decodeBase64(context);
                Cipher cipher = Cipher.getInstance(CipherMode);
                cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(APPSECRET.getBytes(Encode), EncryptAlg), new IvParameterSpec(AESIV.getBytes(Encode)));
                byte[] content = cipher.doFinal(data);
                String result=new String(content,Encode);
                return result;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 生成 HMACSHA256
         * @param data 待处理数据
         * @param key 密钥
         * @return 加密结果
         * @throws Exception
         */
        public static String HMACSHA256(String data, String key) throws Exception {
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
            sha256_HMAC.init(secret_key);
            byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
            StringBuilder sb = new StringBuilder();
            for (byte item : array) {
                sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
            }
            return sb.toString();
        }
    
        public static void main(String[] args) {
            //test256();
            testEncrypt();
            //testdecrypt();
        }
    
        private static void testdecrypt() {
            String s1 = "TI6H4Zx7YeWM0dSiial6L+nCvrEv8Oqk1ZFhWXqYZcRzzZyy/xECQW0nf" +
                    "DszpNDmRMlSmsWkBJMmu4a/PmBivUBoNJwFBzAnOfn8gtYKdxDU16lDFwN5d/I" +
                    "W1UJijJ2lU5YkDs/rMTyRN1NTR+0vJ1So0lmeZQiGQWEwE5t4wZykSC3cMQZyvJ95" +
                    "2J7KU6aBXv1ZUGncZbWHQQaLw4UxFaBWIO8bVlkBIAqzolswI4dhtqBzFwmdEx+7hzHSeid" +
                    "OVbIja5adgKMAjvIUTdtUEb/cO0ipO6QbK8wglk6dQ8+7rFTchBYIoaaqM9Sf" +
                    "hcdvAYuSGk6yHIyN4GEtLBA5Zw==";
            System.out.println(decrypt(s1));
        }
    
        private static void testEncrypt() {
            String s = "{\"name\":\"小明\",\"certificate_num\":\"451121196209260032\",\"certificate_type\":1,\"phone_num\":\"1388888888\",\"merchant_id\":\"c7c114d5da444df2b5d47a66c9c11111\"}";
            String afterEncrypt  = encrypt(s);
            System.out.println(afterEncrypt);
        }
    
        private static void test256() {
            // 签名算法
            String s2 = "c7c114d5da444df2b5d47a66c9cbd3fc16010271967da8046aa2da46bfb08429058e910081";
            String key = "7da8046aa2da46bfb08429058e911111";
            try {
                String s1 = HMACSHA256(s2,key);
                System.out.println(s1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    2 根据API要求自己编写的工具类

    例如:根据公司B的要求,编写特定的post方法

    // 满足公司B的post方法
    public static String sendPostByJsonWithHeader(String url, String body, Map<String, String> headers) throws Exception {
        CloseableHttpClient httpclient = HttpClients.custom().build();
        HttpPost post = null;
        String resData = null;
        CloseableHttpResponse result = null;
        try {
            // 封装 url,并且是 post 请求。
            post = new HttpPost(url);
            HttpEntity entity = new StringEntity(body, Consts.UTF_8);
            // 基本配置
            post.setConfig(RequestConfig.custom().setConnectTimeout(30000).setSocketTimeout(30000).build());
            // 封装消息头
            if (null != headers && !headers.isEmpty()) {
                for (Entry<String, String> entry : headers.entrySet()) {
                    post.setHeader(entry.getKey(), entry.getValue());
                }
            }
            // 消息头支持 json
            post.setHeader("Content-Type", "application/json");
            // 封装数据
            post.setEntity(entity);
            // 发送请求
            result = httpclient.execute(post);
            if (HttpStatus.SC_OK == result.getStatusLine().getStatusCode()) {
                // 返回结果
                resData = EntityUtils.toString(result.getEntity());
            }
        } finally {
            if (result != null) {
                result.close();
            }
            if (post != null) {
                post.releaseConnection();
            }
            httpclient.close();
        }
        return resData;
    }
    
    // 生成header的方法
    private static Map<String, String> generateHeader(String callbackUrlParam) {
        Map<String, String> headers = new HashMap<>();
        // 商户结算平台 id,固定
        headers.put("appkey", Constant.appkey);
        // 请求标识 ,每次请求唯一,动态数据
        String requestID = UUID.randomUUID().toString();
        headers.put("request_id", requestID);
        // 时间戳(秒),30 分钟过期,动态数据
        Date date = new Date();
        String timestamp = String.valueOf(date.getTime() / 1000);
        headers.put("timestamp", timestamp);
        // 签名方法 ,暂支持 sha256
        headers.put("sign_type", "sha256");
        // 签名,算法为 HMACSHA256(appkey+timestamp+appsecret),动态生成
        String signatureStr = Constant.appkey + timestamp + Constant.appsecret;
        String signature = null;
        try {
            signature = EncryptUtil.HMACSHA256(signatureStr, Constant.appsecret);
        } catch (Exception e) {
            e.printStackTrace();
        }
        headers.put("signature", signature);
        // 版本, 本文档为 2.0
        headers.put("version", "2.0");
        // 回调地址, 以 https://或者 http://开头并进行 base64 编码
        String callbackUrl = callbackUrlParam;
        if (callbackUrl != null) {
            // 需要对callbackUrlParam进行base64 编码,然后赋值给 callbackUrl
            Base64.Encoder encoder = Base64.getEncoder();
            byte[] textByte;
            try {
                textByte = callbackUrlParam.getBytes("UTF-8");
                callbackUrl = encoder.encodeToString(textByte);
                headers.put("callback_url", callbackUrl);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
    
    
        // 项目编号,暂不支持
        headers.put("project_code", null);
        return headers;
    }

    七 根据API文档,编写必要的DTO

    针对每个API,主要包含请求DTO,响应DTO,回调响应DTO,这个就要跟踪API要求,编写满足要求的DTO。

    当然有些DTO是可以抽象成一个类,例如一般响应DTO和回调响应DTO都是一样的,这个时候就可以抽象为一个DTO了。

    例如:

    package GDDto;
    
    /**
    * @className: GDCommonRes
    * @description: 共同响应结果
    * @date: 2020/9/24
    * @author: cakin
    */
    public class GDCommonRes {
        /**
         * 状态码
         */
        private int code;
        /**
         * 消息
         */
        private String msg;
        /**
         * 请求时的 request_id
         */
        private String request_id;
        /**
         * 数据
         */
        private String data;
        /**
         * appkey
         */
        private String appkey;
    
        public int getCode() {
            return code;
        }
    
        public void setCode(int code) {
            this.code = code;
        }
    
        public String getMsg() {
            return msg;
        }
    
        public void setMsg(String msg) {
            this.msg = msg;
        }
    
        public String getRequest_id() {
            return request_id;
        }
    
        public void setRequest_id(String request_id) {
            this.request_id = request_id;
        }
    
        public String getData() {
            return data;
        }
    
        public void setData(String data) {
            this.data = data;
        }
    
        public String getAppkey() {
            return appkey;
        }
    
        public void setAppkey(String appkey) {
            this.appkey = appkey;
        }
    }

    八 针对每个API方法,进行对接

    做好以上准备工作,就可以一个个接口进行对接了。可采用下面方式一个一个接口进行对接。

    public static void main(String[] args) {
        // 1. 批量创建结算单    回调接口。
        // batchSettlement();
        // 2. 查询结算单       非回调接口。
        //querySettlement();
        // 3. 结算单退款       回调接口。
        refundSettlement();
        // 4. 授权签约      非回调接口。
        // authorizSigned();
        // 5. 获取签约结果     非回调接口。
        // querySigned();
    }

    九 对接代码结构

    十 一些对接技巧

    1 遇到问题,如果需要公司B的帮助,需要主动和公司B的对接人员交流,尽快找到问题所在。

    2 有些基础代码,如果公司B能提供,主动要一下,如果确实因为信息安全问题,公司B不方面提供,那就得自己写了,写完后,如果不确定代码是否符合B的要求,可以发给公司B的对接人员看看,以确定代码的正确性。

    3 学习公司B的接口文档中好的地方,应用到自己的工作中。

    4 委婉指出接口文档中的错误和不足,帮助公司B文档质量改进,这样在对接时,公司B的对接人员也会更热心的帮助你。

    5 公司A的对接代码,放到正式代码的test目录中,一来可以方便调用正式代码中的工具类,二来方便将对接代码移植到正式代码中。

    展开全文
  • 官方提供的PHP对接海康威视综合安防平台接口开发类文件,可直接使用
  • 百度实时推送api接口应用示例,api示例网站质量不错的网站可以在百度站长平台/数据提交/sitemap栏目下看到实时推送的功能, 目前这个工具是邀请开放, 百度的实时推送的api接口可以实时推送我们新发布的文章, 保证百度...

    百度实时推送api接口应用示例,api示例

    网站质量不错的网站可以在百度站长平台/数据提交/sitemap栏目下看到实时推送的功能, 目前这个工具是邀请开放, 百度的实时推送的api接口可以实时推送我们新发布的文章, 保证百度在第一时间收录.

    百度站长平台 http://zhanzhang.baidu.com/

    01040CJ9-0.jpg

    打开百度站长平台, 点开实时推送的添加新数据接口获得带token的api推送地址:

    http://ping.baidu.com/sitemap?site=www.yourdomain.com&resource_name=sitemap&access_token=xxxxxxx

    分享一段网友写的php实时推送代码:

    php 实时推送新发布的文章

    socketopen方式推送sitemap

    复制代码 代码如下:

    function sitemap_ping_baidu($urls){

    $baidu_ping_url = 'ping.baidu.com';

    $get = '/sitemap?site=www.yourdomain.com&resource_name=sitemap&access_token=xxxxxxx';

    $port=80;

    if ( ( $io = fsockopen( $baidu_ping_url, $port, $errno, $errstr, 50 ) ) !== false ) {

    $send = "POST $get HTTP/1.1"."rn";

    $send .= 'Accept: */*'."rn";

    $send .= 'Cache-Control: no-cache'."rn";

    $send .= 'Host: '.$baidu_ping_url."rn";

    $send .= 'Pragma: no-cache'."rn";

    //$send .= "Referer: http://".$url.$get."rn";

    //$send .= 'User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)'."rn";

    $xml = '';

    foreach($urls as $url){

    $xml .= '';

    $xml .= '';

    $xml .= ''.date('Y-m-d').'';

    $xml .= 'monthly';

    $xml .= '0.8';

    $xml .= '';

    }

    $xml .= '';

    $send .= 'Content-Length:'.strlen($xml)."rn";

    $send .= "Connection: Closernrn";

    $send .= $xml."rn";

    fputs ( $io, $send );

    $return = '';

    while ( ! feof ( $io ) )

    {

    $return .= fread ( $io, 4096 );

    }

    return $return;

    }else{

    return false;

    }

    }

    $return = sitemap_ping_baidu(array('http://www.yourdomain.com/a.php?id=1'));

    推送后百度会返回的xml文档

    复制代码 代码如下:

    200

    状态码含义如下

    200

    无使用方式错误,需要进一步观察返回的内容是否正确

    400

    必选参数未提供

    405

    不支持的请求方式,我们只支持POST方式提交数据

    411

    HTTP头中缺少Content-Length字段

    413

    推送的数据过大,超过了10MB的限制

    422

    HTTP头中Content-Length声明的长度和实际发送的数据长度不一致

    500

    站长平台服务器内部错误

    API接口怎使用?

    您这个问题太粗狂了,不同的API接口,提供的调用与使用的方式会不一样。一般的情况下,提供API者会提供对应的说明和示例。

    百度sitemapPost推送示例怎使用

    具备了开发者账号后就进入百度开放云平台,下面的这个网址是开发指南:developer.baidu.com/...qq.c2c。原则上说是可以根据这个指南就可以成功运行百度提供的示例程序,但是个人感觉说得不够详细,我就自己的经历写下如下步骤。

    当进入如上的网站后,点击右上角的登录,成功后就后在右上角显示管理控制台。点击管理控制台进入轻应用管理,再点击如图的箭头就可以显示如图1.1 移动应用管理分类,点击移动应用管理进入应用管理。

    点击进入如下界面,填写应用名称,例如推送测试2,点击保存。

    点击管理控制台进入轻应用管理,再点击如图的箭头就可以显示如图1.1 移动应用管理分类,点击开发者服务管理进入图1.4,其中的推送测试2就是刚才新建的。

    图1.4 开发者服务管理

    点击推送测试2进入图1.5中记录红圈ID,后面会写入到程序中。

    图1.5基本信息

    package="com.baidu.push.example"

    图1.6 推送设置

    在这里第一次使用的时候可能不知道应用包名是什么,那就先来介绍百度云推送的SDK。从该网址下载android版本的客户端SDK包及应用Demo:developer.baidu.com/...entsdk 。 下面并解压包目录如下\Baidu-Push-SDK-Android-L2-3.2.0\Demo,将Demo导入到eclipse中。如果出现编

    译报就将编码改成UTF-8的,一般就不会报错了。这样把示例程序运行到手机中,会发现程序接收不到百度云在推送。是因为还要修改mainfest.xml中在api_key的值就是刚才推送测试2中基本信息API key见图1.5中的红圈。我的修改如下:

    再次运行就可以接收百度云推送的消息了。下一节介绍详细测试过程。

    手机上运行pushdemo软件,进入百度云开发者服务管理,在工程名称中选择刚才的推送测试2。点击左边的云推送如图1.7;

    点击通知,进入如下图1.8,在标题和消息内容中填写相关内容,最后也是最关键的时候到了,最好将pushdemo运行到后台或者说退出,这样你才能更加形象的感受到推送功能,好了点击图中的发送,大概1秒的时间,你就会听到声音,说明你收到了推送,如图1.9测试结果,这个消息和图1.8中的内容不对应,因为结果是我第二天。关于消息和媒体的测试我这就不说了,我测试过要可以的。

    http://www.bkjia.com/PHPjc/897688.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/897688.htmlTechArticle百度实时推送api接口应用示例,api示例 网站质量不错的网站可以在百度站长平台/数据提交/sitemap栏目下看到实时推送的功能, 目前这个工具...

    展开全文
  • PAYPAL --集成API接口教程网站专业版收款---------------PayPal网站专业版收款(快速支付)可以让您的客户更快捷、更安全地完成付款。客户可以选择存放在PayPal账户中的配送地址等信息返回给您的网站,这样...

    PAYPAL --集成API接口教程

    网站专业版收款

    ---------------

    PayPal网站专业版收款(快速支付)可以让您的客户更快捷、更安全地完成付款。客户可以选择存放在PayPal账户中的配送地址等信息返回给您的网站,这样他们就不需要在您的网站上重复录入,大大节省购物时间;同时,该解决方案是基于API的,每次API调用都需要进行身份认证,所以更加安全。

    

    在整个支付流程中,共需调用三个API接口,流程示意图如下:

    

    

    

    实现Express Checkout 共分四步:

    ◆ 创建带有Express Checkout按钮的购物车页面

    当您的客户挑选好商品并被引导到购物车页面时,您即可将Express Checkout按钮添加到购物车页面,如下图红框所示,您也可以将PayPal作为一个支付可选项与其他支付方式并排:

    

    

    关于PayPal图标位置编排的说明请参考这里。

    

    

    

    

    ◆ 引导客户登录到PayPal授权付款

    客户点击购物车页面上的Express Checkout按钮后,你必须调用第一个API函数:SetExpressCheckout。调用该函数时可以设置很多参数,但是以下三个参数是必须的:

    -- OrderTotal:订单总价,此价格可以是一个订单的估计值;

    -- ReturnURL:客户确认相关信息后返回到您网站继续完成付款动作的网址;

    -- CancelURL:客户由于不能通过PayPal付款或者取消PayPal付款而返回到您网站的网址,建议设置为带有PayPal Express Checkout按钮的购物车页面或支付页面;该函数将返回一个参数token。此token用于跟踪整个付款过程,在此后两个API函数调用中都必须带上此token。获取token后,重定向客户的网页到PayPal网站,以便客户进行登录并选择付款方式和配送信息;

    -- 重定向客户到:https://www.paypal.com/cgi-bin/w ... checkout&token= mytoken

    -- 用您从PayPal中获取的token替换上面的mytoken ;

    

    你的客户登录PayPal并选择一个配送地址及付款方式,如下图所示:

    

    

    

    

    注:所有参数可以参考文档

    

    参数参考文挡

    

    

    ◆获取**并确认订单

    

    客户确认配送地址等信息以后,PayPal将引导他们回到您的网站,该返回的地址由函数SetExpressCheckout中所带的参数ReturnURL决定。此时,您即可以通过调用第二个API函数GetExpressCheckoutDetails获取客户的相关信息,并将其显示在订单确认页面上,如下图所示:

    

    

    

    

    当PayPal将您的客户重定向回由ReturnURL指定的网址后,PayPal将在ReturnURL后面附加两个变量:token及PayerID(客户PayPal账户加密后的HASH码)。

    

    • 若ReturnURL没有带参数,如: https://www.myshop.com/checkout

    则返回的URL为:

    https://www.myshop.com/checkout ?token= EC-0W8920957N684880R&PayerID=TEJ9UFMQHWZRF

    

    • 若ReturnURL已经带有参数,如:https://www.myshop.com/checkout?cart_id=1234

    则返回的URL为:

    https://www.myshop.com/checkout?cart_id=1234 &token=EC-0W8920957N684880R

    &PayerID=TEJ9UFMQHWZRF

    

    当您接收到从PayPal到ReturnURL的POS后,提取出token的值,并将其作为第二个API函数GetExpressCheckoutDetails的参数,该函数的目的就是为了从PayPal处获取客户的相关信息,如配送信息等。该函数返回的内容主要包括:

    • PayerID:加密后的客户的PayPal账号,这个值在调用第三个API函数DoExpressCheckoutPayment是必须的;

    • Payer:客户的email地址;

    • FirstName:客户的名;

    • LastName:客户的姓;

    • Address:客户的配送地址,该地址是在PayPal中选择或者新增的;

    • AddressStatus:客户配送地址的标志。如果该值为Confirmed,则表明该配送地址是经过PayPal认证过的;

    

    将您从PayPal处接收到的客户的姓名及配送信息显示给客户看,以便客户进行确认,在这里你也可以让用户选择配送方式或做一些相应的广告。

    

    

    

    ◆ 完成付款

    客户对订单确认后,即可点击最后付款按钮完成付款动作。这个付款按钮实际上就是通过调用最后一个API函数DoExpressCheckoutPayment完成付款动作。在调用该函数后,PayPal将立即返回一个付款状态,您可以将付款细节及付款状态显示给客户看,如下图所示:

    

    

    

    如果付款不成功,您也应该显示类似信息。

    

    

    

    ▲▲▲相关文档及开发包下载地址:▲▲▲

    • Express Checkout Integration Guide(PDF ,HTML)

    • Name-Value Pair API Developer Guide and Reference(PDF ,HTML)

    • Sandbox User Guide (PDF ,HTML)

    a193f2a69803769aa2b6d0e68c4d4c11.gif

    [本帖最后由 fancuihui 于 2009-3-13 12:25 编辑]

    展开全文
  • api接口怎么使用

    2022-07-06 09:13:43
    API,官方定义为应用程序编程接口。就是把是一些预先定义的接口,用来提供应用程序与开发人员基于某软件或硬件得以访问的一组例程,而又无需访问源码,或理解内部工作机制的细节。
  • 现在做不管是做短视频还是网站,防红都是至关重要的一步,源码已经整理修复完毕,自带八条接口,可任意使用。 功能好用,搭建简单,支付对接了派特第三方个人免签,对接自带API文档提供下载。非常好用的东西,不拿...
  • 在做一些游戏开发的时候,经常要用到一些彩票开奖的数据做为开奖结果,自己到网上去抓,经常没多久对方网站...接口返回各种格式有json,xml ,下面我给大家演示用双色球案例演示一下对接教程 { // title:'双色球',
  • 介绍: 使用阿里巴巴全球速卖通接口,稳定高效不易和谐上传就可以直接使用了无需配置 网盘下载地址: https://zijiewangpan.com/4L47liaKGGu 图片:
  • 前言 1、以前的流程是用户添加第三方应用,然后...企微服务商后台管理操作教程 1、用户在企微应用市场搜索服务商开发的第3方应用,假如应用名字【天气助手】。然后点击安装。 2、这时候服务商的后台服务会收到腾讯服
  • 那么请往下看,首先苹果cms的采集接口api是这种样子的:{这是图片}{图片结束}一般都是对接别人的api接口,因为前两天遇到一个网站的api,观察了几天,都还没关闭,请看图;于是我就采集了一波,完成后打开看了...
  • 如何使用API_api接口有什么优点
  • 电商平台及ISV商家对物流api接口的需求有很多,今天我们主要分享的就是快递鸟快递单号查询接口的对接指南,快递单号查询接口对接的应用场景有很多,很多场景会遇到,最主要的就是电商网站用户打开“我的订单”时调用...
  • 易语言如何调用API函数?你代码方法错了,如果传出参数为文本或字节集必须先“申请内存缓冲”,如图1源码中有两种方法,建议你采用“长整数”的那个,比较方便~!易语言dll怎么注入别的程序并运行?每个可执行程序...
  • 1、网站用户后台的订单页面,用户打开页面时先调用快递接口查询这个用户的订单的快递,然后将结果显示在页面中; 2、内部快速搜索,用户打电话过来只要问对方的名字,然后直接搜到这个用户的订单的快递状况,主要是...
  • 免费实用API接口

    千次阅读 2020-05-27 15:53:40
    抖音短视频无水印解析:http://api.63code.com/douyin 2、皮皮虾视频无水印解析:http://api.63code.com/pipixia 3、b站视频解析:http://api.63code.com/bili 4、必应每日壁纸:http://api.63code.com/bing 5、...
  • 最近做了个小项目,主要是来备份自己在抖音里面发的一些作品到自己的电脑本地。因为这两年陆陆续续在抖音和tiktok里面已经发了不少作品了。...正好在网上找到一个这种无水印解析视频的接口。这篇文章主要是
  • PhalApi开源接口框架 读音:派框架,官网:https://www.phalapi.net/ PhalApi是一个PHP轻量级开源接口框架,致力于快速开发接口服务。支持HTTP/SOAP/RPC等协议,可用于搭建接口/微服务/RESTful接口/Web Services。...
  • 3、通用彩票信息API接口,免费好用

    千次阅读 2022-01-26 10:10:19
    RollToolsApi通用系列接口包含多很多免费通用的API接口,利用这些接口可以帮你实现去开发出很多功能丰富,服务稳定的小程序,APP或者网页,无论是练手还是实战都是不错的选择。所有接口的列表可以在此查看 ...
  • 2012年3月22日,发了一条关于Excel通过API接口批量获取天气记录的微博,现在博客上做个总结,并对此文件的实现方法做个简要教程供大家学习参考。微博内容如下:利用Excel快速批量获取并保存城市天气记录,如果不选择...
  • 应用列表2、在基础信息中勾选上需要的功能3、生成RSA2密钥进入开放平台文档中心,搜索:生成RSA下载生成工具打开工具,生成密钥查看生成的公钥私钥4、上传应用公钥查看自己对应的应用接口加签方式-设置应用公钥把上...
  • python 获取api接口

    千次阅读 2020-12-20 10:58:03
    Python获取IP地址对应的地理位置信息... 文章 阿里云实时计算Flink 2019-09-09 2988浏览量 Python快递鸟API接口对接(即时查询|物流跟踪|电子面单|单号识别) 快递鸟 kdniao python sdk, with tornado async & asyncio ...
  • 微信小程序:调用API接口

    千次阅读 2021-09-11 10:03:00
    首先去果创云之类的API调用的网站找到你想调用的API 以大学查询接口为例 复制API接口,然后要现在第一个?前面加上appkey,然后name可以换成变量,最后的10是显示的条数,也可以改。 最后效果是可以查询...
  • 网站接入微信支付收款的接口配置教程 微信支付设置 1,微信支付 APPID,APPSECRET 获取方式 进入为微信公众号后台,点击左侧的开发-->基本配置在基本配置处即可看到AppId和AppSecret 注意:AppSecret 在...
  • 这段时间学习了一下简单搭建一个api接口后端服务,现在记录一下。 本文主要内容 下载tp6 打开错误调试 隐藏入口文件 解决跨域问题-(使用全局中间件处理) 路由解决api版本控制 jwt token验证-(使用路由中间件验证...
  • 学习完本课程可以继续学习“Web前端开发仿美团/饿了吗移动App之高德地图接口对接案例”, 主要内容: 路线的查询接口 周边搜索接口 学习针对高德地图接口对接的实际应用    访问地址:...
  • 给大家带来搭建网课搜题公众号教程,下面看搭建好的成品图 下面带大家搭建搜题公众号 首先我们需要的材料: 1.有自己的微信公众号(已经注册好的,直接登录自己公众号即可) 注册公众号教程: 点我进入注册公众号...
  • • 独立的api接口调用,让接入更高效,更新方便,并且配备开发接口文档。 搭建需要工具:服务器linux系统,备案域名,环境配置:Apache + PHP5.6以上 + MySQL5.5以上(推荐使用宝塔面板一键安装) 1.首先源码传到服务器根...
  • 对接支付宝支付接口,官方文档已经写的很清楚了,但是也有很多像我一样的小白,第一次对接支付宝支付接口,会有些迷茫,所以我在此写下这篇文章,给我和我一样的同学,一点思路吧。需要思路的可以私聊我两大支付平台...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,800
精华内容 720
关键字:

网站api接口对接教程

友情链接: 8.zip