golang 实现 ldif 数据转成 json 初探

简介: golang 实现 ldif 数据转成 json 初探

theme: Chinese-red

「这是我参与11月更文挑战的第 8 天,活动详情查看:2021最后一次更文挑战

上一篇我们分享了如何将 ldif 格式的数据,转换成 json 数据的思路并画相应的简图

这一次,我们就来实现一下

实现方式如下:

  • 连接服务器,查询 ldap 服务器上数据结构 ,goalng 如何获取 ldap 服务器的数据? 有说到
  • 遍历每一条 entry
  • 处理每一条 entry 的时候,从右到左获取相应的 rdn(对应的键和值),并给每一个 rdn 创建一个 多叉树的 节点
  • basedn 对应的节点 和 每一个 ou 对应的节点地址,存放到一个 map(key 是 string,value 是节点的地址) 中便于后续遍历处理其他 entry 的时候,直接通过 ou 名字获取对应节点地址即可
  • 对于一个节点下面的用户,直接挂到这个节点上即可

来一起看看数据结构和 main 函数

数据结构为节点的必要信息

// 节点信息
type lNode struct {
  Name     string
  Path     string
  Children []*lNode
  User     []string
}
// 新建一个节点
func NewNode(name, path string) *lNode {
  return &lNode{
    Name:     name,
    Path:     path,
    Children: []*lNode{},
    User:     []string{},
  }
}

main 函数的执行流程具体如下:

  • 连接ldap 服务器并查询对应数据
  • 处理数据并生成一颗树 (默认 dc 为 根节点, / )
  • 将树转成 json 格式,进行打印输出
func main() {
  data := connectLdap(
    "ldap://xxxx",
    "dc=xiaomotong,dc=com",
    "cn=admin,dc=xiaomotong,dc=com",
    "123123",
    "(&(objectClass=*))")
  if len(data) <= 0 {
    fmt.Println("search no data !!")
  }
  mp := make(map[string]*lNode)
  root := NewNode("dc=xiaomotong,dc=com", "/")
  mp["dc=xiaomotong,dc=com"] = root
  // 生成一颗树
  CreateLdapTree(mp, data, "dc=xiaomotong,dc=com")
  b, err := json.Marshal(root)
  if err != nil {
    fmt.Println("json.Marshal error !!!")
    return
  }
  fmt.Println(string(b))
}

从 ldap 服务器上获取数据

我们简单就在 一个 main.go 文件中实现一下,代码结构是这样的

func connectLdap(addr, baseDB, username, passwd, filter string) []*ldap.Entry { 函数的具体实现,在文章 goalng 如何获取 ldap 服务器的数据? 有体现,我们这一次只是将参数调整了一下

处理 ldap 响应的数据

ldap 返回的数据是以 ldif 格式返回的,会返回0条到多条 entry,我们需要逐个的来解析每一个 entry 里面的数据

一个 entry 就是一个 DN ,一个 DN 里面有多个 RDN,一个 RDN 就是一个键值对

  • 创建根节点,信息是 BASEDN :dc=xiaomotong,dc=com , 并将信息放到 map 中

  • 开始解析数据每一条 dn,dn 中的 每一个 rdn 创建对应的节点,并通过dn 从右到左的顺序,将 rdn 连接起来
  • 一个组里面有子组,就放在 node 的 Children 里面, 一个组里面的 用户就放在 User里面,当前节点的名字 放在 name中,当前节点的绝对路径就放在 path 中

来看看 func CreateLdapTree(mp map[string]*lNode, Entries []*ldap.Entry, BASEDN string) { 函数

// 创建一棵树
func CreateLdapTree(mp map[string]*lNode, Entries []*ldap.Entry, BASEDN string) {
  // 遍历 Entries
  for _, Entry := range Entries {
    if BASEDN == Entry.DN {
      continue
    }
    ProcessDN(Entry.DN, mp, BASEDN)
  }
}

CreateLdapTree 里面具体的实现是遍历 ldap 的所有 entry,并调用 ProcessDN 函数来解析 dn 数据,且根据 dn 来生成对应的多叉树片段

具体处理 DN 数据

func ProcessDN(DN string, mp map[string]*lNode, BASEDN string) { 是具体处理 DN 数据的主要函数

  • 主要做的是解析一条 DN 数据,并生成一个多叉树的片段
  • ou 的节点地址会相应放到 map 中进行记录,便于后续使用

处理的逻辑,会去判断 rdn 的 key 是 dc,cn,ou,来做相应的处理,如果是 ou 就创建节点,并将节点的地址记录在 map 中

json 序列化

最后将数据结构序列化成 json,并以字符串的方式打印出来

上述代码逻辑也比较简单,就是将 ldif 转成树而已,代码流程是

整个 main.go 文件,执行之后,结果如下,成功将 ldif 转成多叉树,且已 json 的方式展现出来

{
    "Name": "dc=xiaomotong,dc=com",
    "Path": "/",
    "Children": [
        {
            "Name": "People",
            "Path": "/People/",
            "Children": [],
            "User": [
                "xiaozhupeiqi"
            ]
        },
        {
            "Name": "dev",
            "Path": "/dev/",
            "Children": [
                {
                    "Name": "golang",
                    "Path": "/dev/golang/",
                    "Children": [],
                    "User": [
                        "xiaoppp"
                    ]
                },
                {
                    "Name": "clang",
                    "Path": "/dev/clang/",
                    "Children": [
                        {
                            "Name": "woshixiaozhu",
                            "Path": "/dev/clang/woshixiaozhu/",
                            "Children": [],
                            "User": [
                                "xiaopang2"
                            ]
                        }
                    ],
                    "User": []
                },
                {
                    "Name": "java",
                    "Path": "/dev/java/",
                    "Children": [],
                    "User": []
                }
            ],
            "User": []
        }
    ],
    "User": [
        "admin",
        "zhangsan",
        "xiaopang",
        "xiaopang2"
    ]
}

学习所得,如有偏差,还请不吝赐教,细心的朋友会发现上述逻辑有坑,下次见

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是小魔童哪吒,欢迎点赞关注收藏,下次见~

相关文章
|
1天前
|
XML JSON API
转Android上基于JSON的数据交互应用
转Android上基于JSON的数据交互应用
|
9天前
|
JSON JavaScript Java
从前端Vue到后端Spring Boot:接收JSON数据的正确姿势
从前端Vue到后端Spring Boot:接收JSON数据的正确姿势
21 0
|
11天前
|
JSON 数据格式 Python
Python标准库中包含了json模块,可以帮助你轻松处理JSON数据
【4月更文挑战第30天】Python的json模块简化了JSON数据与Python对象之间的转换。使用`json.dumps()`可将字典转为JSON字符串,如`{&quot;name&quot;: &quot;John&quot;, &quot;age&quot;: 30, &quot;city&quot;: &quot;New York&quot;}`,而`json.loads()`则能将JSON字符串转回字典。通过`json.load()`从文件读取JSON数据,`json.dump()`则用于将数据写入文件。
16 1
|
11天前
|
JSON 数据格式 Python
Python处理JSON数据
【4月更文挑战第30天】该内容介绍了Python处理JSON数据的三个方法:1)使用`json.loads()`尝试解析字符串以验证其是否为有效JSON,通过捕获`JSONDecodeError`异常判断有效性;2)通过`json.dumps()`的`indent`参数格式化输出JSON数据,使其更易读;3)处理JSON中的日期,利用`dateutil`库将日期转换为字符串进行序列化和反序列化。
22 4
|
11天前
|
JSON JavaScript 前端开发
Golang深入浅出之-Go语言JSON处理:编码与解码实战
【4月更文挑战第26天】本文探讨了Go语言中处理JSON的常见问题及解决策略。通过`json.Marshal`和`json.Unmarshal`进行编码和解码,同时指出结构体标签、时间处理、omitempty使用及数组/切片区别等易错点。建议正确使用结构体标签,自定义处理`time.Time`,明智选择omitempty,并理解数组与切片差异。文中提供基础示例及时间类型处理的实战代码,帮助读者掌握JSON操作。
22 1
Golang深入浅出之-Go语言JSON处理:编码与解码实战
|
14天前
|
存储 JSON 数据处理
|
15天前
|
监控 安全 Go
Golang深入浅出之-Channels基础:创建、发送与接收数据
【4月更文挑战第22天】Go语言的Channels是并发通信的核心,用于Goroutines间安全高效的数据交换。本文介绍了Channels的基础知识,包括创建(无缓冲和缓冲通道)、发送与接收数据,以及如何避免常见问题。创建通道使用`make(chan T)`,发送数据用`ch &lt;- value`,接收数据则相反。无缓冲通道需匹配的发送和接收操作,否则会阻塞。缓冲通道能暂存数据,但需注意缓冲区大小以防止死锁。关闭通道后不能发送,但能接收剩余数据,多值接收可检测通道状态。掌握这些概念和技巧,能提升Go语言并发编程的效率和稳定性。
19 1
|
15天前
|
JSON 编译器 Go
Golang深入浅出之-结构体标签(Tags):JSON序列化与反射应用
【4月更文挑战第22天】Go语言结构体标签用于添加元信息,常用于JSON序列化和ORM框架。本文聚焦JSON序列化和反射应用,讨论了如何使用`json`标签处理敏感字段、实现`omitempty`、自定义字段名和嵌套结构体。同时,通过反射访问标签信息,但应注意反射可能带来的性能问题。正确使用结构体标签能提升代码质量和安全性。
15 0
|
6天前
|
监控 算法 Go
Golang深入浅出之-Go语言中的服务熔断、降级与限流策略
【5月更文挑战第4天】本文探讨了分布式系统中保障稳定性的重要策略:服务熔断、降级和限流。服务熔断通过快速失败和暂停故障服务调用来保护系统;服务降级在压力大时提供有限功能以保持整体可用性;限流控制访问频率,防止过载。文中列举了常见问题、解决方案,并提供了Go语言实现示例。合理应用这些策略能增强系统韧性和可用性。
30 0
|
4天前
|
分布式计算 Java Go
Golang深入浅出之-Go语言中的分布式计算框架Apache Beam
【5月更文挑战第6天】Apache Beam是一个统一的编程模型,适用于批处理和流处理,主要支持Java和Python,但也提供实验性的Go SDK。Go SDK的基本概念包括`PTransform`、`PCollection`和`Pipeline`。在使用中,需注意类型转换、窗口和触发器配置、资源管理和错误处理。尽管Go SDK文档有限,生态系统尚不成熟,且性能可能不高,但它仍为分布式计算提供了可移植的解决方案。通过理解和掌握Beam模型,开发者能编写高效的数据处理程序。
133 1