解析HTTP响应中的复杂JSON数据
来源:stackoverflow
时间:2024-03-26 18:57:35 354浏览 收藏
本文介绍了如何解析包含复杂 JSON 数据的 HTTP 响应。该 JSON 数据具有多层嵌套结构,包括列表和映射。为了从该 JSON 数据中提取特定信息,可以使用自定义函数 `findNested` 来递归地遍历映射并查找指定的键。`findNested` 函数会返回一个布尔值,指示该键是否找到,以及找到的值。利用此函数,可以轻松地提取所需字段,例如每个站点的 site_id、ip 和域名。
我正在针对 api 执行 http.postform,结果是 json。 json结构是这样的:
{
"sites": [
{
"site_id": 456,
"status": "pending-dns-changes",
"domain": "blabla",
"account_id": 123,
"acceleration_level": "advanced",
"site_creation_date": 1515455285000,
"ips": [
"1.2.3.4"
],
"dns": [
{
"dns_record_name": "something.bla.com",
"set_type_to": "cname",
"set_data_to": [
"something.x.incapdns.net"
]
}
],
"original_dns": [
{
"dns_record_name": "blabla2.com",
"set_type_to": "a",
"set_data_to": [
""
]
},
{
"dns_record_name": "blabla3.something.com",
"set_type_to": "a",
"set_data_to": [
"1.2.4.5"
]
},
],
"warnings": [],
"active": "bypass",
"support_all_tls_versions": false,
"use_wildcard_san_instead_of_full_domain_san": true,
"add_naked_domain_san": true,
"additionalerrors": [],
"display_name": "something.blablabla2.com",
"security": {
"waf": {
"rules": [
{
"action": "api.threats.action.alert",
"action_text": "alert only",
"id": "api.threats.sql_injection",
"name": "sql injection"
},
{
"action": "api.threats.action.alert",
"action_text": "alert only",
"id": "api.threats.cross_site_scripting",
"name": "cross site scripting"
},
{
"action": "api.threats.action.alert",
"action_text": "alert only",
"id": "api.threats.illegal_resource_access",
"name": "illegal resource access"
},
{
"block_bad_bots": true,
"challenge_suspected_bots": false,
"id": "api.threats.bot_access_control",
"name": "bot access control"
},
{
"activation_mode": "api.threats.ddos.activation_mode.auto",
"activation_mode_text": "auto",
"ddos_traffic_threshold": 1000,
"id": "api.threats.ddos",
"name": "ddos"
},
{
"action": "api.threats.action.quarantine_url",
"action_text": "auto-quarantine",
"exceptions": [
{
"values": [
{
"urls": [
{
"value": "/neverbogus.pvr",
"pattern": "equals"
}
],
"id": "api.rule_exception_type.url",
"name": "url"
}
],
"id": 1618746719
},
{
"values": [
{
"urls": [
{
"value": "/doubleneverbogus.pvr",
"pattern": "equals"
},
{
"value": "/ddoubleneverbogus.pvr",
"pattern": "equals"
}
],
"id": "api.rule_exception_type.url",
"name": "url"
}
],
"id": 856301271
},
{
"values": [
{
"client_apps": [
"537"
],
"id": "api.rule_exception_type.client_app_id",
"name": "client app id"
}
],
"id": 58318563
},
{
"values": [
{
"ips": [
"192.168.66.66"
],
"id": "api.rule_exception_type.client_ip",
"name": "ip"
}
],
"id": 707083378
},
{
"values": [
{
"geo": {
"countries": [
"bf"
]
},
"id": "api.rule_exception_type.country",
"name": "country"
}
],
"id": 1432086237
},
{
"values": [
{
"user_agents": [
"gasdfafafdfasdfadsfadsffads"
],
"id": "api.rule_exception_type.user_agent",
"name": "user agent"
}
],
"id": 1876871261
},
{
"values": [
{
"parameters": [
"bogusparamnamehere234"
],
"id": "api.rule_exception_type.http_parameter",
"name": "http parameter"
}
],
"id": 1338747790
}
],
"id": "api.threats.backdoor",
"name": "backdoor protect"
},
{
"action": "api.threats.action.alert",
"action_text": "alert only",
"id": "api.threats.remote_file_inclusion",
"name": "remote file inclusion"
},
{
"action": "api.threats.action.disabled",
"action_text": "ignore",
"id": "api.threats.customrule",
"name": "incaprules"
}
]
}
},
"seallocation": {
"id": "api.seal_location.none",
"name": "no seal "
},
"ssl": {
"origin_server": {
"detected": true,
"detectionstatus": "ok"
},
"custom_certificate": {
"active": false
},
"generated_certificate": {
"ca": "gs",
"validation_method": "dns",
"validation_data": [
{
"dns_record_name": "blablablasomething2",
"set_type_to": "txt",
"set_data_to": [
"somethingtexty"
]
}
],
"san": [
"*.blabla2.com"
],
"validation_status": "done"
}
},
"sitedualfactorsettings": {
"enabled": false,
"customareas": [],
"customareasexceptions": [],
"allowallusers": true,
"shouldsuggestapplicatons": true,
"allowedmedia": [
"ga",
"sms"
],
"shouldsendloginnotifications": true,
"version": 0
},
"login_protect": {
"enabled": false,
"specific_users_list": [],
"send_lp_notifications": true,
"allow_all_users": true,
"authentication_methods": [
"ga",
"sms"
],
"urls": [],
"url_patterns": []
},
"performance_configuration": {
"advanced_caching_rules": {
"never_cache_resources": [],
"always_cache_resources": []
},
"acceleration_level": "advanced",
"async_validation": true,
"minify_javascript": true,
"minify_css": true,
"minify_static_html": true,
"compress_jpeg": true,
"compress_jepg": true,
"progressive_image_rendering": false,
"aggressive_compression": false,
"compress_png": true,
"on_the_fly_compression": true,
"tcp_pre_pooling": true,
"comply_no_cache": false,
"comply_vary": false,
"use_shortest_caching": false,
"perfer_last_modified": false,
"prefer_last_modified": false,
"disable_client_side_caching": false,
"cache300x": false,
"cache_headers": []
},
"extended_ddos": 1000000,
"log_level": "security",
"incap_rules": [
{
"id": 51589,
"name": "wordpress",
"action": "api.rule_action_type.rule_action_alert",
"rule": "(url contains \"/xmlrpc.php$\" | url contains \"/wp-login.php$\") & (user-agent == \"mozilla/5.0 (windows nt 10.0; wow64) applewebkit/537.36 (khtml, like gecko) chrome/51.0.2704.103 safari/537.36\" | user-agent == \"mozilla/5.0 (windows nt 6.1; wow64; rv:40.0) gecko/20100101 firefox/40.1\")",
"creation_date": 1518810206000
},
{
"id": 52179,
"name": "no browser",
"action": "api.rule_action_type.rule_action_alert",
"rule": "(clienttype != browser & clienttype != spambot & clienttype != ddosbot & clienttype != sitehelper) & (user-agent != \"mozilla/5.0 (windows nt 6.1; wow64) applewebkit/534+ (khtml, like gecko) bingpreview/1.0b\" & user-agent != \"pingdom.com_bot_version_1.4_(http://www.pingdom.com/)\")",
"creation_date": 1519432068000
}
],
"res": 0,
"res_message": "ok",
"debug_info": {
"id-info": "13019"
}
},
api 文档:https://docs.imperva.com/bundle/cloud-application-security/page/api/sites-api.htm#list
对于我来说,理解 go 似乎非常痛苦,因为我才刚刚开始。 从我读到的内容来看,我应该用我期望的格式定义一个 struct 类型的对象。 有什么办法可以让我更轻松地解决这个问题吗?我有兴趣为每个单独的站点提取一些项目,例如 site_id / ips / 域。
不确定我应该如何解决这个问题。我一直在尝试了解 https://github.com/buger/jsonparser 但我无法真正理解如何使用它。
到目前为止我一直在做的是:
func main() {
fmt.Println("Starting this..")
formData := url.Values{
"api_id": {keyid},
"api_key": {apikey},
"page_size": {"100"},
"page_num": {"0"},
}
response, err := http.PostForm("https://my.imperva.com/api/prov/v1/sites/list", formData)
if nil != err {
fmt.Println("Ooops..", err)
}
log.Println(response.Status)
bodyBytes, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
var results map[string]interface{}
fmt.Println(string(bodyBytes))
json.Unmarshal([]byte(bodyBytes), &results)
defer response.Body.Close()
}解决方案
如果您只需要提取几个字段,则实际上不需要定义复杂的 struct 类型来描述整个结构。您可以使用 stdlib 将 json 解组到 map[string]interface{},然后使用类似此函数的功能来查找有趣的键:
// findNested looks for a key named s in map m. If values in m map to other
// maps, findNested looks into them recursively. Returns true if found, and
// the value found.
func findNested(m map[string]interface{}, s string) (bool, interface{}) {
// Try to find key s at this level
for k, v := range m {
if k == s {
return true, v
}
}
// Not found on this level, so try to find it nested
for _, v := range m {
nm, ok := v.(map[string]interface{})
if ok {
found, val := findNested(nm, s)
if found {
return found, val
}
}
}
// Not found recursively
return false, nil
}
此代码仅处理嵌套映射。您可以稍微调整它以透视切片等。
今天关于《解析HTTP响应中的复杂JSON数据》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!
-
502 收藏
-
502 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
139 收藏
-
204 收藏
-
325 收藏
-
478 收藏
-
486 收藏
-
439 收藏
-
357 收藏
-
352 收藏
-
101 收藏
-
440 收藏
-
212 收藏
-
143 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习