整体流程
创建套件 - 配置协议 - 上架协议 - 创建第三方系统适配器 - 创建第三方系统参数要求 - 适配协议 - 编写脚本 - 上架适配器
业务集成 - 上架应用 - 安装应用 - 配置协议及适配器 - 使用
适配厂商信息
- 请求地址:https://ip.taobao.com/outGetIpInfo
- 请求参数:ip=183.45.175.222
定义阶段
创建API套件
套件名称:IP地址查询
套件简介:提供快速精准的IP地址查询能力
添加状态码
我的套件 > 查看协议 > 状态码
代码 | 描述 |
---|---|
200 | 查询成功 |
1001 | 无效的IP |
添加API协议
我的套件 > 查看协议 > 创建API协议
基本信息:
协议名称:IP地址查询
请求类型:POST
接口类型:同步
协议URL:/ip/query
协议说明:通过IP地址查询返回具体的地理位置信息
请求头:
名称 | 必填 | 类型 | 默认值 | 备注 |
---|---|---|---|---|
- | - | - | - | - |
请求参数:
名称 | 必填 | 类型 | 默认值 | 备注 |
---|---|---|---|---|
ip | 是 | string | - | 目标IP地址 |
返回参数:
名称 | 必填 | 类型 | 默认值 | 备注 |
---|---|---|---|---|
code | 否 | number | 状态码 | |
msg | 否 | string | 信息描述 | |
sucess | 否 | string | 成功标识(true 成功 false 失败) | |
data | 否 | object | 数据 | |
data -> ip | 否 | string | 目标IP地址 | |
data -> address | 否 | string | 物理位置 |
- API套件上架
适配阶段
API模型适配
- 创建适配器
我的套件 > 查看适配器 > 创建适配器
基本信息
适配器名称: 淘宝IP查询
适配器说明:由淘宝提供的的IP查询服务
适配器参数
注意:这里的参数只是为了演示用,真实不应该是这两个参数
参数名称 | 参数标识 | 说明 |
---|---|---|
服务器地址 | server | 在线工具服务器地址(如:https://ip.taobao.com/ ) |
查询路由 | router | 在线工具ip查询路由(如:outGetIpInfo) |
适配代码
import cn.hutool.http.HttpRequest
import cn.hutool.json.JSONObject
import cn.hutool.json.JSONUtil
import cn.hutool.log.StaticLog
import cn.flyrise.pai.apistore.util.GroovyScriptUtil
String main(){
// 淘宝:https://ip.taobao.com/outGetIpInfo
// 太平洋电脑网:http://whois.pconline.com.cn/ipJson.jsp
server = param.getStr("server");
result = HttpRequest.get(server + param.getStr("router"))
.header("Referer", param.getStr("server"))
.timeout(3000)
.form("ip", data.getStr("ip"))
.form("json", "true") //兼容太平洋电脑网
.execute().body()
if (JSONUtil.isJson(result)) {
JSONObject json = JSONUtil.parse(result);
StaticLog.error("在线调试信息: {} ", JSONUtil.toJsonPrettyStr(json))
// 淘宝
if (server.contains("taobao") && json.getInt("code") == 0 ) {
json = json.getObj("data")
return JSONUtil.createObj().set("ip", data.getStr("ip"))
.set("address", json.getStr("country") + " " + json.getStr("region") + " " + json.getStr("city") + " " + json.getStr("isp"))
.set("common-login", GroovyScriptUtil.invokeMethod("login"))
}
// 太平洋电脑网
else if ( server.contains("pconline") && json.getStr("err") == "" ) {
return JSONUtil.createObj().set("ip", data.getStr("ip"))
.set("address", json.getStr("addr"))
.set("common-login", GroovyScriptUtil.invokeMethod("login"))
}
// 错误
else {
return JSONUtil.createObj().set("ip", data.getStr("ip")).set("address","查询失败").set("result", json)
.set("common-login", GroovyScriptUtil.invokeMethod("login"))
}
}
return JSONUtil.createObj().set("ip", data.getStr("ip")).set("address","解析失败").set("result", result)
}
main()
在线调试
淘宝(有QPS限制)
适配器参数:
server: https://ip.taobao.com
router: /outGetIpInfo请求参数:
ip => 219.131.197.178
太平洋电脑网
适配器参数:
server: http://whois.pconline.com.cn
router: /ipJson.jsp请求参数:
ip => 219.131.197.178
集成阶段
API模型集成
- 申请授权并添加API套件
我的套件 > API权限 > 申请开通 > 添加API套件 > IP地址查询
业务集成
后端接口
配置参数:
bootstrap-dev.yml
pai:
apistore:
config:
api-server: http://pai.flyrise.cn/apistore-api
ip-router: /open/v1/1/ip/query
client-id: kysK******K4zqdf
secret-key: 3ylsWI******daWTOSNj
ApiProperties.java
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties("pai.apistore.config")
public class ApiProperties {
/**
* APIStore 服务地址
*/
private String apiServer;
/**
* APIStore 接入ID
*/
private String clientId;
/**
* APIStore 接入Key
*/
private String secretKey;
/**
* IP查询路由地址
*/
private String ipRouter;
public String getApiServer() {
return apiServer;
}
public void setApiServer(String apiServer) {
this.apiServer = apiServer;
}
public String getIpRouter() {
return ipRouter;
}
public void setIpRouter(String ipRouter) {
this.ipRouter = ipRouter;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
}
IpAddressVO.java
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel("IP地址信息")
public class IpAddressVO {
@ApiModelProperty("目标IP地址")
String ip;
@ApiModelProperty("物理地址")
String address;
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
IIpAddressService.java
import cn.flyrise.pai.attendancestd.model.vo.IpAddressVO;
/**
* IP查询服务
*/
public interface IIpAddressService {
/**
* 根据IP查询出实际的物理地址
*
* @param ip 目标IP地址
* @return 物理地址
*/
IpAddressVO query(String ip);
}
IpAddressServiceImpl.java
签名方式为:md5(body + configId + timestamp + secureKey)
import cn.flyrise.common.core.exception.CommonException;
import cn.flyrise.pai.attendancestd.config.ApiProperties;
import cn.flyrise.pai.attendancestd.model.vo.IpAddressVO;
import cn.flyrise.pai.attendancestd.service.IIpAddressService;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
@Service
public class IpAddressServiceImpl implements IIpAddressService {
@Autowired
ApiProperties apiProperties;
@Override
public IpAddressVO query(String ip) {
final String jsonBody = JSONUtil.createObj().set("ip", ip).toString();
final String timestamp = String.valueOf(System.currentTimeMillis());
final String configId = getConfigId();
final String sign = SecureUtil.md5(jsonBody + configId + timestamp + apiProperties.getSecretKey());
final String result = HttpRequest.post(apiProperties.getApiServer().concat(apiProperties.getIpRouter()))
.header("X-Client-Id", apiProperties.getClientId())
.header("X-Timestamp", timestamp)
.header("X-Config-Id", configId)
.header("X-Sign", sign)
.body(jsonBody)
.timeout(3000).execute().body();
if (JSONUtil.isJson(result)) {
JSONObject json = JSONUtil.parseObj(result);
if (json.getBool("success")) {
return JSONUtil.toBean(json.getJSONObject("data"), IpAddressVO.class);
}
}
throw new CommonException("1001", "无效的IP");
}
private String getConfigId() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = servletRequestAttributes.getRequest();
String result = HttpRequest.get(apiProperties.getApiServer().concat("/adapter/param/config/list"))
.header("Authorization", request.getHeader("Authorization"))
.form("appCode", "cn.flyrise.attendance.std")
.timeout(3000).execute().body();
if (JSONUtil.isJson(result)) {
JSONObject json = JSONUtil.parseObj(result);
if (json.getBool("success") && json.getJSONArray("data").size() > 0) {
return json.getJSONArray("data").getJSONObject(0).getStr("id");
}
}
return null;
}
}
IpAddressController.java
import cn.flyrise.common.core.domain.Reply;
import cn.flyrise.pai.attendancestd.model.vo.IpAddressVO;
import cn.flyrise.pai.attendancestd.service.IIpAddressService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/ip")
@Api(tags = "IP地址接口")
public class IpAddressController {
@Autowired
IIpAddressService service;
@GetMapping("query")
@ApiOperation("查询IP物理地址")
@ApiImplicitParam(name = "ip", value = "目标IP地址", required = true, example = "xxx.xxx.xxx.xxx")
public Reply<IpAddressVO> query(String ip) {
return Reply.success(service.query(ip));
}
}
前端页面
nuxt.config.js
const LOCAL_PROXY_OPTIONS = {
enable: true, // 是否启用
target: 'http://127.0.0.1:8080',
proxies: [
{
path: 'attendance-std-api', // 替换成业务后端api
},
]
}
pages/ip.vue
<template>
<el-form ref="form" label-width="80px" style="margin:100px auto;width: 300px">
<el-form-item label="IP地址">
<el-input v-model="ip"></el-input>
</el-form-item>
<el-form-item label="物理地址">
<div v-text="address"></div>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
</el-form>
</template>
<script>
import request from "~/plugins/request";
export default {
data() {
return {
ip: "",
address: "",
};
},
methods: {
onSubmit() {
request({
url: "/attendance-std-api/ip/query",
method: "GET",
params: { ip: this.ip },
}).then((res) => {
this.address = res.data.address
});
},
},
};
</script>
安装阶段
业务上架安装
开发者后台 > 应用中心 > 飞智云考勤(标准版)> 添加版本 > 配置 微应用(IP地址查询 /pages/ip)
开发者后台 > 我的套件 > 飞智云考勤(标准版)> 沙箱 > 一键更新
配置适配器及参数
控制台 > 应用 > 飞智云考勤(标准版) > 协议配置 > 添加适配器
server: https://ip.taobao.com/
router: outGetIpInfo
使用阶段
业务使用演示
工作台 > 应用 > 飞智云考勤(标准版) > IP地址查询
183.45.175.222
219.131.197.178