如何使用Groovy将URL编码字符串转换为指定JSON结构?
Groovy实现URL编码嵌套键值对转指定结构JSON
核心思路
先对URL编码字符串解码,再解析带方括号的嵌套键路径,将键值对映射为包含account对象、leads数组的嵌套Groovy集合,最后转换为JSON格式。
完整实现代码
import java.net.URLDecoder import groovy.json.JsonBuilder // 示例URL编码字符串 def urlEncodedStr = "account%5Bname%5D=Acme+Corp&account%5Bphone%5D=1234567890&leads%5B0%5D%5Bemail%5D=lead1%40example.com&leads%5B0%5D%5Bname%5D=John+Doe&leads%5B1%5D%5Bemail%5D=lead2%40example.com&leads%5B1%5D%5Bname%5D=Jane+Smith" // 1. URL解码 def decodedStr = URLDecoder.decode(urlEncodedStr, "UTF-8") // 2. 拆分键值对为Map def keyValuePairs = decodedStr.split('&').collectEntries { entry -> def parts = entry.split('=', 2) [parts[0], parts[1]] } // 3. 构建嵌套结构的工具方法 def buildNestedStructure(Map<String, String> keyValuePairs) { def result = [:] keyValuePairs.each { key, value -> // 拆分键路径:将leads[0][email]拆分为['leads', '[0]', 'email'] def pathParts = key.split(/(?=\[)|\]/).findAll { it.trim() } def current = result pathParts.eachWithIndex { part, index -> if (part.startsWith('[')) { // 处理数组索引,转换为整数 def idx = part.substring(1) as Integer // 初始化数组(如果当前层级不是List) if (!(current instanceof List)) { def parentKey = pathParts[index - 1] current = [] result[parentKey] = current } // 确保数组长度足够,不足则补空Map while (current.size() <= idx) { current.add([:]) } current = current[idx] } else { // 处理普通键 if (index == pathParts.size() - 1) { current[part] = value } else { // 初始化下一级Map(如果不存在) current[part] = current.getOrDefault(part, [:]) current = current[part] } } } } return result } // 4. 构建嵌套结构并转为JSON def nestedStructure = buildNestedStructure(keyValuePairs) def jsonOutput = new JsonBuilder(nestedStructure).toPrettyString() println(jsonOutput)
代码说明
- URL解码:使用
URLDecoder.decode将编码后的字符串转为可读的键值对串,指定UTF-8编码避免乱码。 - 键路径解析:通过正则拆分带方括号的键,将
leads[0][email]这类路径拆分为层级节点,区分普通键和数组索引。 - 嵌套结构构建:遍历键路径,动态初始化Map(对应对象)和List(对应数组),确保数组索引不会越界。
- JSON转换:利用Groovy内置的
JsonBuilder将嵌套集合转为格式化的JSON字符串。
输出结果
{ "account": { "name": "Acme Corp", "phone": "1234567890" }, "leads": [ { "email": "lead1@example.com", "name": "John Doe" }, { "email": "lead2@example.com", "name": "Jane Smith" } ] }
内容的提问来源于stack exchange,提问作者Valentin Borisenko
相关产品推荐
相关产品推荐

