-
2021-11-22 10:10:52
在qq互联上登录创建应用,【有注册开发者身份】QQ互联,然后下载对应的sdk,去下载
之后解压。
创建一个工程【或原有的工程里】,并把open-sdk.jar(压缩包中文件名为:open_sdk_xxxx_lite.jar)文件拷贝到libs(或lib)目录下,如下图所示:
然后配置AndroidManifest;
在应用的AndroidManifest.xml增加配置的<application>节点下增加以下配置(注:不配置将会导致无法调用API);<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <application> <activity android:name="com.tencent.tauth.AuthActivity" android:noHistory="true" android:launchMode="singleTask" > <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="tencent你的AppId" /> 假如你的appid是12345 <data android:scheme="tencent12345 /> </intent-filter> </activity> <activity android:name="com.tencent.connect.common.AssistActivity" android:configChanges="orientation|keyboardHidden" android:screenOrientation="behind" android:theme="@android:style/Theme.Translucent.NoTitleBar" /> <application>
接着初始化SDK
3.5.7版本新增接口提供用户设置是否已授权获取设备信息,在调用互联SDK相关功能接口之前,需要应用在确认用户已授权应用获取设备信息后,调用下面代码通知 SDK:
Tencent.setIsPermissionGranted(true);
如果未调用该接口或传参为false时,调用其它功能接口将直接返回失败。
示例代码
public class OneClickLoginActivity extends AppCompatActivity { private static final String TAG = "OneClickLoginActivity"; private static final String APP_ID = "123456";//你的qq互联上面的appid @BindView(R.id.ll_qq_login) LinearLayout llQqLogin; @BindView(R.id.iv_wb_icon) ImageView ivWbIcon; @BindView(R.id.tv_wb) TextView tvWb; public static Tencent mTencent; //QQ包名 private static final String PACKAGE_QQ = "com.tencent.mobileqq"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_one_click_login); Tencent.setIsPermissionGranted(true); ButterKnife.bind(this); mTencent = Tencent.createInstance(APP_ID, this.getApplicationContext()); } @OnClick({R.id.ll_qq_login}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.ll_qq_login: if (!hasApp(PACKAGE_QQ)) { Toast.makeText(OneClickLoginActivity.this, "未安装QQ应用", Toast.LENGTH_SHORT).show(); return; } loginQQ(); break; } } /** * QQ登录 */ private IUiListener listener; private void getUnionId() { if (mTencent != null && mTencent.isSessionValid()) { IUiListener listener = new IUiListener() { @Override public void onError(UiError e) { Toast.makeText(OneClickLoginActivity.this, "onError", Toast.LENGTH_LONG).show(); } @Override public void onComplete(final Object response) { if (response != null) { JSONObject jsonObject = (JSONObject) response; try { String unionid = jsonObject.getString("unionid"); } catch (Exception e) { Toast.makeText(OneClickLoginActivity.this, "no unionid", Toast.LENGTH_LONG).show(); } } else { Toast.makeText(OneClickLoginActivity.this, "no unionid", Toast.LENGTH_LONG).show(); } } @Override public void onCancel() { Toast.makeText(OneClickLoginActivity.this, "onCancel", Toast.LENGTH_LONG).show(); } @Override public void onWarning(int i) { } }; UnionInfo unionInfo = new UnionInfo(this, mTencent.getQQToken()); unionInfo.getUnionId(listener); } else { Toast.makeText(this, "please login frist!", Toast.LENGTH_LONG).show(); } } private void loginQQ() { listener = new IUiListener() { @Override public void onComplete(Object object) { Log.e(TAG, "登录成功: " + object.toString()); JSONObject jsonObject = (JSONObject) object; try { //得到token、expires、openId等参数 String token = jsonObject.getString(Constants.PARAM_ACCESS_TOKEN); String expires = jsonObject.getString(Constants.PARAM_EXPIRES_IN); String openId = jsonObject.getString(Constants.PARAM_OPEN_ID); mTencent.setAccessToken(token, expires); mTencent.setOpenId(openId); Log.e(TAG, "token: " + token); Log.e(TAG, "expires: " + expires); Log.e(TAG, "openId: " + openId); //获取UnionId getUnionId(); //获取个人信息 getQQInfo(); } catch (Exception e) { } } @Override public void onError(UiError uiError) { //登录失败 Log.e(TAG, "登录失败" + uiError.errorDetail); Log.e(TAG, "登录失败" + uiError.errorMessage); Log.e(TAG, "登录失败" + uiError.errorCode + ""); } @Override public void onCancel() { //登录取消 Log.e(TAG, "登录取消"); } @Override public void onWarning(int i) { } }; //context上下文、第二个参数SCOPO 是一个String类型的字符串,表示一些权限 //应用需要获得权限,由“,”分隔。例如:SCOPE = “get_user_info,add_t”;所有权限用“all” //第三个参数事件监听器 mTencent.login(this, "all", listener); //注销登录 //mTencent.logout(this); } /** * 获取QQ个人信息 */ private void getQQInfo() { //获取基本信息 QQToken qqToken = mTencent.getQQToken(); UserInfo info = new UserInfo(this, qqToken); info.getUserInfo(new IUiListener() { @Override public void onComplete(Object object) { try { Log.e(TAG, "个人信息:" + object.toString()); //头像 String avatar = ((JSONObject) object).getString("figureurl_2"); String nickName = ((JSONObject) object).getString("nickname"); if (!avatar.equals("")) { //需要添加Glide库进行图片展示 Glide.with(OneClickLoginActivity.this).load(avatar).into(ivWbIcon); } tvWb.setText(nickName); } catch (JSONException e) { e.printStackTrace(); } } @Override public void onError(UiError uiError) { } @Override public void onCancel() { } @Override public void onWarning(int i) { } }); } /** * 回调必不可少,官方文档未说明 */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //腾讯QQ回调 Tencent.onActivityResultData(requestCode, resultCode, data, listener); if (requestCode == Constants.REQUEST_API) { if (resultCode == Constants.REQUEST_LOGIN) { Tencent.handleResultData(data, listener); } } } /** * true 安装了相应包名的app */ private boolean hasApp(String packName) { boolean is = false; List<PackageInfo> packages = getPackageManager() .getInstalledPackages(0); for (PackageInfo packageInfo : packages) { // 判断系统/非系统应用 if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) // 非系统应用 { String packageName = packageInfo.packageName; if (packageName.equals(packName)) { is = true; } } else { // 系统应用 } } return is; } }
注。获取unionid在QQ互联上默认是不开启的,需要你自己手动开启,在下面的位置【需要绑定】
更多相关内容 -
爱德华EST3消防主机第三方集成对接方式
2022-03-03 16:08:57读取消防告警信息,做预警监测,智慧消防 -
对接第三方服务,红包购买流程.pdf
2020-05-29 11:27:00可供参考的流程图-对接第三方服务,红包购买流程,在此模版下各位按照自己的情况进行修改,设计出自己或公司所需要的流程图。 -
统一门户单点登录对接第三方跨职能流程图
2020-11-26 13:20:10第三步:认证系统给浏览器发送一个ticket凭证,浏览器将凭证交给第三方系统,第三方系统则拿着浏览器交给他的凭证ticket去认证系统验证凭证ticket是否有效。凭证ticket若是有效,将登录信息保存第三方系统的session... -
DSS-H8900平台第三方对接平台视频流的说明.docx
2020-11-09 12:18:18大华视频处理H.265 等问题。 -
【美团团购】第三方优惠码电子凭证平台对接文档V2版
2022-04-24 10:12:41三方电子凭证平台接入是指第三方按照美团定义的接口规范开发接口,在美团上线产品,美团通过调用第三方接口发放、查询、作废第三方的消费 凭证。 1)文档所涉及接口包括4个: 接口 开发方 调用方 功能 发券通知接口... -
Java调用第三方接口示范的实现
2020-08-25 16:13:35主要介绍了Java调用第三方接口示范的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 -
海康iSC平台测试第三方对接接收事件工具
2020-12-25 09:52:41实时事件对接是通过回调第三方的 http 接口推送事件的,在与第三方对接中 为了方便验证 esc 是否正常回调第三方接口推送事件,我这边开发了一个建议程序,用来监 听一个 http 接口,用来测试事件推送功能。 -
短链接url.cn接口服务端 无需对接第三方
2020-04-21 03:36:33url..cn生成服务端,无需对接第三方接口,打开软件就是接口,可以给别人对接,给别人使用!软件在服务器上运行,打开软件里面设置的端口 -
微信广告任务平台源码运营版 带教程 对接第三方个人免签
2019-07-24 10:03:42带第三方个人免签支付,支持VIP等级充值、在线支付(微信和支付宝)、推广分销、用户提交任务、我的团队等 。适用范围: 最新微信广告任务平台源码运营版|带教程|对接第三方个人免签。运行环境: php+mysql -
和第三方接口对接总结
2018-09-30 16:46:46接口对接分为两种形式: 我方A公司提供接口给B公司,B公司进行一些操作时调用我们的接口进行实现。 例:A开发会员等级同步接口,供B同步会员等级到B系统。B会员等级的变动需要调用A接口主动推送给A(即更新会员卡...接口对接分为两种形式:
- 我方A公司提供接口给B公司,B公司进行一些操作时调用我们的接口进行实现。
例:A开发会员等级同步接口,供B同步会员等级到B系统。B会员等级的变动需要调用A接口主动推送给A(即更新会员卡等级)。
我们首先要做的就是按照对方的要求,在对方调用我们的接口,我方成功处理之后,按照对方所需要的返回数据以及格式反馈给他们信息。
在写本接口中,因为我们会员卡等级的字段是不一样的,所以我们对此主要处理的就是这个事情,1.例如对方传来修改后的卡等级是金卡,因为我们数据库中是分为vipcard和cardgrade两张表的,所以首先我们要去写一个方法,查询cardgrade表中所有的卡等级的id,返回一个list集合,再利用B公司传过来的数据for循环遍历比较,如果相等,则拿到金卡等级在我方A公司的ID,代码如下:
再根据B公司提供的会员卡号在我们查询到该条会员并拿到id;
最后就可以根据拿到跟新后的等级id和该会员的id进行更新了,任务完成!代码如下:
2.B公司开发会员查询接口,A公司调用B公司接口,实时查询会员
调对方接口和对方调我方的接口稍微有些不同,因为中间涉及到安全问题,所以还要满足对方要求我方传入的参数,不然对方不给通过,参数要求如下:
其中AppID,Args,AppSystem是与对方提供给我方特有的,timestamp是当前时间,我们只需获取当前时间按照他的格式生成,这个较简单,稍微复杂点的就是sign的生成了,要做的就是进行加签/验签,按照对方的要求,我们需要将AppId、Timestamp、Token(客户端保存),按照参数名在英文字典中的顺序排序,然后重新拼成一个标准的query string。然后采用sha1或者md5算法对此加密生成sign,代码如下:
参数都好了之后,对方要求以form表单的形式将参数传过去,这又是一个坑,哎。。,网上找了很久,代码如下:
Url是对方给的方法路径,param是放入的5个参数,然后要处理的就是把对方参数对应转成我方的参数形式,采用set/get即可。
供一起刚入坑的参考。
-
新聚合支付第三方第四方支付系统源码
2022-02-23 18:26:18第三方支付第四方支付系统兼容SDK 支持支付宝,微信本地官方接口,本地官员没有上游 可以完成,高成功率的通道;短信接口对接和财富 申请注册的阿里云,阿里的文本界面。 每个站值1.5 W,代码可以稳定运行;系统功能齐全, ... -
第三方数据接口对接.rar
2020-11-08 13:21:58使用C#对接第三方接口 -
基于统一开发者账号的第三方系统对接方法.docx
2022-06-01 17:13:00基于统一开发者账号的第三方系统对接方法.docx基于统一开发者账号的第三方系统对接方法.docx基于统一开发者账号的第三方系统对接方法.docx基于统一开发者账号的第三方系统对接方法.docx基于统一开发者账号的第三方... -
基于统一开发者账号的第三方系统对接方法.pdf
2022-06-01 17:02:34基于统一开发者账号的第三方系统对接方法.pdf基于统一开发者账号的第三方系统对接方法.pdf基于统一开发者账号的第三方系统对接方法.pdf基于统一开发者账号的第三方系统对接方法.pdf基于统一开发者账号的第三方系统... -
今天我们来聊聊,如何做好第三方系统对接
2020-12-18 18:40:43无论你是做面向ToB、ToC还是ToG的业务,开发业务系统,永远也逃脱不了与第三方系统对接的命运,例如:常见的支付宝、微信支付平台对接、短信平台对接,还有单点登录对接,以及与友商的数据接口对接等等,大..
💨 作者:
laker
,因为喜欢LOL滴神faker
,又是NBA湖人队🏀(laker
)粉丝儿(主要是老詹的粉丝儿),本人又姓李,故取笔名:laker
❤️喜欢分享自己工作中遇到的问题和解决方案,以及一些读书笔记和心得分享。
🌰本人创建了微信公众号【Java大厂面试官】,用于和大家交流分享
🏰 个人微信【lakernote】,加作者备注下暗号:cv之道
。
前言
无论你是做面向
ToB
、ToC
还是ToG
的业务,开发业务系统,永远也逃脱不了与第三方系统对接的命运,例如:常见的支付宝、微信支付平台对接、短信平台对接,还有单点登录对接,以及与友商的数据接口对接等等,大到相对成熟的平台对接,小到一个接口的调用,基本上所有的开发都避免不了对接,它已经充斥在我们的日常工作中✒️,如何做好与第三方的对接,降低对接风险,按时保质的完成对接任务,已经成为我们非常头疼的问题了 ⚡⚡⚡。今天我就在这里总结下,个人的经验以及互联网上发表的一些比较好的观点。有用的话,麻烦点个赞 👍 ,转发一波☀️。
首先当我们拿到对接需求的时候,直接
3W
三板斧理论抡起来,来帮助我们梳理一下对接思路。What 是什么
对接的是什么?
- 一定要从宏观到微观的搞清楚我们自己的系统是做什么业务,有哪些数据、哪些字段;需要提供给第三方哪些数据、哪些字段;又需要从第三方获取哪些数据、哪些字段。
这里的宏观和微观指的是宏观的系统物理架构、逻辑架构、部署架构、业务架构,微观的指系统模块、功能点的实现细节、及其涉及的表和其他三方对接历史。
要找到掌握这么多的人,可不是一件容易的事儿,这里能掌握这么多的人,一般都是团队的核心骨干、首席开发工程师❤️
- 同样的也要掌握第三方系统大致业务流程,部署架构等等,知己知彼,百战不殆。
为什么要搞清楚部署架构?在这里我分享下之前的一个真实案例,当场裂开的那种 🐜。
项目对接开始,前期双方都紧锣旗鼓的对接、测试等等,各个环节都很顺利,于是乎在测试环境稳定一周左右后上线。
上线之后的2-3天,突然的某一天,运营人员的一通电话☎️ 打破了祥和的假象!线上出现了很多重复的业务流水号⚠️。
例如:
正常情况数据应该是这样的:
id 流水no 创建时间 10378 QJ00073001 2020-12-18 12:10:11 10379 QJ00073002 2020-12-18 12:10:11 但是现场的情况是:
id 流水no 创建时间 10378 QJ00073001 2020-12-18 12:10:11 10379 QJ00073001 2020-12-18 12:10:11 存在重复的流水号:QJ00073001⚠️,当场我就裂开了,这TM测试环境跑了一周没事儿,正式环境都搞了2-3天了出现问题,趁事态没有扩大,各种排查,
是不是线程安全问题啊?是不是第三方问题啊?这2天动了什么现场环境等等。
很快我们就定位出问题来了,原来是昨天晚上,又对接了一个新的局点导致的,第三方服务部署架构是分级部署的。
我们以为的对接:
实际的对接:
第三方的部署架构是每个局点单独部署一套服务,所以他们那边的流水号都是从1开始的,导致我们直接拿流水号来用的时候裂开了。
处理方式也很简单,流水号加上局点code即可,例如:HW31QJ00073001、HW89QJ00073001
Why 为什么
为什么要对接第三方系统?
比如我们经常对接支付宝、微信平台,你不可能自己开发个支付系统的,再说了支付宝和微信支付的用户也多,方便你我他,可以让我们更专注自己的业务开发。
再比如对接短信平台、快递鸟平台等等。
总结下:基本上都是自己公司想做一件事情,但是自己又没有足够的物力、财力、精力去实现,那么就去找市面上有成熟的解决方案,把专业的活交给专业的人,来以最小化的成本实现我们的需求。
How 怎么做
这里我们再以对接前、对接中、对接后这3个阶段,来分阶段讨论下每个阶段应该怎么做,才能稳步推进我们的对接需求。
对接前
-
明确需求,以及对接的价值(是否真的有必要做及其实现的意义,有可能这一步直接让对接流产✋。。。)
-
搞清楚我们跟第三方的大致交互流程和双方所需数据。(别鸡蛋里面找骨头,他也找不到啊,你要我没有的数据,我可怎么提供)
-
评估大概所需要花费的钱,毕竟跟别人对接,大部分情况下是花钱的。(花的钱太多有可能得不偿失)
-
确定双方相关业务负责人、技术负责人,以及要指定一个总负责任人来推动双方稳步前进(别双方都是放羊模式)
-
制定一个合理的计划,确定联调时间、上线时间、试运行时间(一定要制定合理的计划)
对接中
1. 确定细节
拉上双方业务人员、技术负责人,共同制定接口调用流程,画出接口调用流程图、泳道图、时序图等,毕竟一图胜千言。
这里一定要拉上真正熟悉业务和技术的人去沟通,别找中间人去传话了,也别找不懂的人去,否则在这一步,坑就已经开始挖了。
泳道图示例:
泳道图很清晰的能看到对接双方交互流程,职责划分清晰。
时序图示例:
时序图能清晰看到消息传递的时间顺序。
下面的关键细节我列一下:
关键细节 事项 备注 字段内容 双方确定需要提供什么字段、需要获取哪些字段 接口版本 接口版本规范,url中 /v1/xxx,还是header中 verison=v1,以及协商版本具体规范细节 大量数据 是分页返回,还是以文件的形式,例如csv等 异常处理 定义错误码,以及其对应的相应操作,有什么兜底补偿方案没 调用方式 主动拉取还是被动等待推送 建议双向即可主动式,又可被动式 通信协议 Restful、Webservice、MQ、Websocket等,复杂的对接,是否可以考虑提供sdk 一般建议Restful 报文协议 json、yaml、xml、自定义等 一般建议Json 接口方式 同步接口还是异步接口 接口安全 Oauth2.0 sign token等,注意内外网、以及业务的保密级别 幂等性 确保双方接口是否都是幂等的,防止重复提交 重试机制 一定要确认是否需要接口调用失败后的重试机制,保证数据传输的最终一致性
重试机制包括 实时重试调用:指定次数 + 调用失败持久化,数据库定时任务重试接口文档 要有详尽的说明和丰富的示例代码 联调环境 可以随便折腾的那种 2. 一些建议
-
文档先行,统一规范(双方按照文档来开发,统一规范)
-
需要自己有对接模拟接口,防止三方公司接口迟迟未完成,影响整个项目进度
-
第三方对接模块做成单独的服务最好独立出来,尽最大努力保证服务的高可用、稳定性。(不然你滴电话就要被打爆了☎️)
-
接口升级,尽量做到影响最小,不去修改接口协议,如果必须要动,要做到接口兼容老版本。
-
尽量保证接口的幂等性,因为会有重试机制和补偿方案;
-
接口当中生成requestId,用于日志记录,到返回结果的全流程跟踪,接口接收到的数据,以及解析之后的参数值,都要用日志记录下来,方便查看原因。
-
编码推荐使用注解式声明编程
Feign
举个例子:把第三方对接模块做成单独服务的好处、以及做好对外服务降级操作(业务逻辑降级)。
之前项目中有个需求,需要对接一个厂商的服务,大致流程是调用一个实时接口,输入身份证号,返回这个身份证号关联人的最新的所有的档案信息。
第一阶段
一开始我们是直接把对接代码写到我们业务系统的,这也很正常。
第二阶段
使用一段时间后,公司的另一个团队也需要对接这个厂商,那么现在是否也复制一份儿代码去对接呢?显然我们不会这么去做,第三方接口升级啥的,我们2个团队都要改,耦合性太强了,还有万一后面我们还有其他团队对接呢?不可能都用这种方式。
所以我们的做法是把这个对接模块独立出来,做成一个单独的服务,供所有的团队使用,作为微服务的一部分。
架构如下图:
第三阶段
平稳运行一段时候后,突然的某一天第三方服务厂商服务down掉了,导致我们这边所有相关的业务出现了类似“档案查询接口不可用”的提示。
已经做了断路器、服务通用降级,返回提示信息“档案查询接口不可用”
虽然是第三方的问题,也有提示的降级操作,但是呢,用户体验还是不够友好,于是乎我们开会讨论更完美的方案,我们的需求是返回实时的个人档案信息,
但是如果当第三方服务down了,返回之前查询过的非实时数据,并给个不是最新的提示,也总比提示“档案查询接口不可用”要优雅的多。
于是乎我们会在每个用户查询到档案后,自己本地数据库存一份,当第三方服务不可用的时候去降级到本地数据库查询使用。
架构如下图:
对接后
持续跟踪一段时间系统的使用情况,然后进行总结,看看是否可以把这块对接流程规范化,做标准化接口,将自己的能力或者数据标准化出去,类似于开放平台,让别人按照你的标准来做。(那就乌鸦变凤凰了)
最后我也总结下,之前遇到的风险点:
对接风险
-
对方不配合 (奶茶☕、香烟给安排上,还不行只能让上级去推动了)
-
对接要从源头留痕,防止后面对方扯皮,要留证据。(拿证据说话)
-
对方服务升级,接口变了,未通知升级。(接口版本号制定好,接口做到向下兼容)
-
对方服务不稳定影响自有系统。(服务熔断、降级处理)
-
调用并发频率过高等。(控制频率)
总结与思考
没有最完美的方案,只有尽可能完善的方案,就像系统可用性达不到100%一样,我们做的每一步都要想好失败的场景,以及相应的对应策略,做好降级处理,最终的兜里方案就是人肉补偿了✈️✈️✈️。
QQ群【837324215】
关注我的公众号【Java大厂面试官】,回复:架构、资源等关键词(更多关键词,关注后注意提示信息)获取更多免费资料。公众号也会持续输出高质量文章,和大家共同进步。
-
java对接第三方接口
2019-11-19 10:02:581.准备与第三方接口对接的账号 配置到了Apollo上面 @Value("${taofake.appId}") private String appId; @Value("${taofake.url}") private String url; @Value("${taofake.appSecret}") private String app...1.准备与第三方接口对接的账号
配置到了Apollo上面
@Value("${taofake.appId}") private String appId; @Value("${taofake.url}") private String url; @Value("${taofake.appSecret}") private String appSecret;
2.准备用于接受接口返回结果的实体类
3.准备发HTTP请求的工具类
http工具类
package cn.zhaocha.common.utils; import java.io.IOException; import java.util.Map; import cn.zhaocha.vo.BaseResponseVo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.StringUtils; import lombok.extern.slf4j.Slf4j; import okhttp3.*; @Slf4j public class OKHttpUtil { private static final Logger logger = LoggerFactory.getLogger(OKHttpUtil.class); private static OkHttpClient client = getClient(); public static OkHttpClient getClient() { if (client == null) { client = genericClient();// 创建OkHttpClient对象 } return client; } public static OkHttpClient genericClient() { OkHttpClient httpClient = new OkHttpClient.Builder().addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request().newBuilder() // .addHeader("Content-Type", "text/html; charset=gb2312") // .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8") // .addHeader("Accept-Encoding", "gzip, deflate") // .addHeader("Connection", "keep-alive") // .addHeader("Accept", "*/*") // .addHeader("User-Agent", "Mozilla/5.0 (Linux; Android 9.0.0; MI 6 Build/OPR1.170623.032; wv) AppleWebKit/537.36 (KHTML, like Gecko) // Version/4.0 Chrome/62.0.3202.84 Mobile Safari/537.36/Android/globalscanner/4.00") // .addHeader("Accept-Language", "zh-CN,en-US;q=0.9") .addHeader("ApiVersion", "1.0") // .addHeader("X-Requested-With", "com.globalscanner") .build(); return chain.proceed(request); } }).build(); return httpClient; } public static String postAsync(String urlStr, Map<String, String> paramMap, Callback callback) { return postAsync(urlStr, paramMap, callback, null); } public static String postAsync(String urlStr, Map<String, String> paramMap, Callback callback, Map<String, String> header) { Request.Builder oneBuilder = getOneBuilder(urlStr, paramMap, header); Request request = oneBuilder.build(); getClient().newCall(request).enqueue(callback); return null; } private static Request.Builder getOneBuilder(String urlStr, Map<String, String> paramMap, Map<String, String> header) { // 创建表单请求体 FormBody.Builder formBody = new FormBody.Builder(); for (String key : paramMap.keySet()) { formBody.add(key, paramMap.get(key)); } // 创建Request 对象。//传递请求体 Request.Builder postBuild = new Request.Builder().url(urlStr).post(formBody.build()); if (header != null && header.size() > 0) { for (String key : header.keySet()) { postBuild.addHeader(key, header.get(key)); } } return postBuild; } private static Request.Builder getGetBuilder(String urlStr, Map<String, String> paramMap, Map<String, String> header) { HttpUrl.Builder urlBuilder = HttpUrl.parse(urlStr).newBuilder(); if (paramMap != null) { for (String key : paramMap.keySet()) { urlBuilder.setQueryParameter(key, paramMap.get(key)); } } Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build()) .headers(header == null ? new Headers.Builder().build() : Headers.of(header)).get(); return requestBuilder; } /** * 同步请求 */ public static <T> BaseResponseVo<T> post(String urlStr, Map<String, String> paramMap, Class clazz) { return post(urlStr, paramMap, null, clazz); } public static <T> BaseResponseVo<T> post(String urlStr, Map<String, String> paramMap, Map<String, String> header, Class clazz) { Request.Builder oneBuilder = getOneBuilder(urlStr, paramMap, header); Request request = oneBuilder.build(); try { log.info("请求:OKHttpUtil-post-日志信息请求参数:" + urlStr + " " + paramMap.toString()); Response response = client.newCall(request).execute(); if (response != null && response.isSuccessful()) { if (response.body() == null) { log.info("响应:OKHttpUtil-post-日志信息响应结果未空:"); return BaseResponseVo.err("1", "response.body内容为空", null); } String content = response.body().string(); log.info("响应:OKHttpUtil-post-日志信息响应结果:" + content); // String content ="{error_msg: \"成功\",error_code: 0}"; // String content = "{error_msg: \"失败\",error_code: 1}"; if (!StringUtils.isEmpty(content)) { T obj = (T) FastJsonUtil.jsonToBean(content, clazz); return BaseResponseVo.succ("0", "获取成功", obj); } } } catch (IOException e) { e.printStackTrace(); return BaseResponseVo.err(e.toString()); } return BaseResponseVo.err("1", "获取失败", null); } public static <T> BaseResponseVo<T> get(String urlStr, Map<String, String> paramMap, Map<String, String> header, Class clazz) { Request.Builder oneBuilder = getGetBuilder(urlStr, paramMap, header); Request request = oneBuilder.build(); try { log.info("请求:OKHttpUtil-post-日志信息请求参数:" + urlStr + " " + paramMap.toString()); Response response = client.newCall(request).execute(); if (response != null && response.isSuccessful()) { if (response.body() == null) { log.info("响应:OKHttpUtil-get-日志信息响应结果未空:"); return BaseResponseVo.err("1", "response.body内容为空", null); } String content = response.body().string(); log.info("响应:OKHttpUtil-get-日志信息响应结果:" + content); if (!StringUtils.isEmpty(content)) { T obj = (T) FastJsonUtil.jsonToBean(content, clazz); return BaseResponseVo.succ("0", "获取成功", obj); } } } catch (IOException e) { e.printStackTrace(); return BaseResponseVo.err(e.toString()); } return BaseResponseVo.err("1", "获取失败", null); } }
4.调用第三方接口
黄色线表示访问第三方接口
现在我们可以来测试一下了
与第三方接口对接就完成了
-
微信公众号对接第三方平台(全网发布 java)源码 含 jar
2018-03-22 17:47:52微信公众号对接第三方平台(全网发布 java)源码+jar 里面有完成全网发布的源码直接tomcat部署运行和所需的jar 具体对接流程,关注我们的博客 http://blog.csdn.net/qq_34919987 (可能没这么快更新) -
第三方支付平台如何对接?
2022-02-18 19:31:37支付宝原生通道可以在支付宝上提交资料申请,审批后就...扫码聚合支付是未来的主流,而第三方支付平台是第三方支付的基础,是一个具有在线支付、电子支付等功能的平台。一般第三方支付平台可以分为两类:一类是银联等金 -
OneNET与第三方平台对接(最简单方式)
2017-08-25 15:37:43这个微信对接类似,比微信还简单一点,如果你对接过微信,相信这个很简单。 采用本地映射外部链接方式(ngrok工具) 1、第一步写客户端代码 采用SpringMVC+Spring框架 @Controller public class OneNoteController {... -
第三方接口对接规范
2020-11-13 17:21:19如果项目是属于那种集成项目,那么对接各种第三方平台在所难免。根据亲身经历,暂定如下对接规范。 1 自定义异常 针对第三方的异常,大致可以分为第三方内部异常、第三方传入参数异常、自身调用异常、登录异常。 第... -
第三方接口对接之鉴权
2019-04-24 15:06:47记录一次和第三方接口对接的过程。 对接要求 对方的接口做了加密验证,需要将参数进行加密生成一个Signature签名。然后对方也会根据参数做一样的步骤来比对签名是否相等来判断参数是否被篡改或者判断身份是否一致。 ... -
对接qq第三方登陆
2015-05-12 08:51:50对接qq第三方登陆,对于初学者挺有用的,分享一下 -
客服系统第三方对接
2020-07-15 18:12:08我这里建议大家在时间紧的情况下,采用第三方的客服系统进行对接就可以了。现在的客服系统只需要一个链接展示到前端,用户点击就可以进行对话聊天,支持文字、图片、语音等,具体根据业务需求而定! ... -
聚合小说漫画动漫听书分销系统源码+代理系统+第三方支付+对接微信公众号+安装教程.zip
2019-05-11 13:56:48聚合小说漫画动漫听书分销系统源码+代理系统+第三方支付+对接微信公众号+安装教程 一.环境要求:操作系统/win或linux、PHP/5.4x、mysql/5.5x、Apache/2.4.x、开启openssl扩展。 二.修改数据库配置文件,路经如下\... -
JAVA web框架开发通过第三方支付公司与银行对接
2013-05-22 23:09:02通过第三方支付公司与银行对接: 这种方式接方式的优缺点: 优点:系统只需要与第三方支付公司打交道,第三方支付公司根据用户选择的支付银行,并根据支付银行的接入规范,引导用户与银行对接,从而实现支付。此种... -
使用SpringBoot RestTemplate实现第三方接口对接
2019-10-27 16:52:15实现对接第三方接口,可以使用HttpClient(年岁较久),也可以使用SpringBoot RestTemplate(新生代)。可根据个人喜好选择适当的方式进行对接,个人推荐使用SpringBoot RestTemplate。 具体使用如下: 自定义配置类: ... -
如何高效对接第三方支付
2020-05-24 17:41:24目前我们已经服务30个国家和地区,不同国家往往需要对接不同的第三方支付公司,所以最近两年,研发组对接了大量的第三方支付公司,积累了一定的经验。 本文主要分享如何对接第三方支付,以及在生产上实际遇到的一些... -
uni-app 对接第三方h5
2020-07-23 15:17:281.uni-app中对接第三方为了防止跳出app使用了webview <template> <view> <web-view :src="url" @message="message"></web-view> </view> </template> <script> ... -
对接第三方接口--使用post请求发送json数据
2021-03-15 00:46:01对接第三方接口–使用post请求发送json数据实习4个多月,终于转正!终于可以安心好好上班,好好学习!第一篇播客记录下工作中的中的小知识点。本文记录的内容如下:1.使用HttpClient相关类,包括PostMethod,Request...