You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elixir中如何解析mandrill_events并将JSON数组字符串转为Map?

解决Mandrill Events解析失败及JSON数组转Map的问题

我来帮你搞定这两个问题——Mandrill Events解析失败的排查修复,以及JSON对象数组转Map的实现:

一、修复Mandrill Events解析失败的问题

Mandrill发送的mandrill_events参数本质是JSON数组的URL编码字符串,你遇到的解析失败大概率是URL解码不彻底、JSON格式转义异常,或者误把数组当成单个对象解析导致的。按下面的步骤排查修复:

1. 先做URL解码

这是最容易忽略的第一步!Mandrill会对事件数组做URL编码,直接解析编码后的字符串肯定会失败。举两个常见语言的解码示例:

  • Java:
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

// 从请求中获取原始的mandrill_events参数
String encodedEvents = request.getParameter("mandrill_events");
// 解码还原成原始JSON字符串
String decodedEvents = URLDecoder.decode(encodedEvents, StandardCharsets.UTF_8);
  • Python:
import urllib.parse

# 从表单或请求参数中获取值
encoded_events = request.form.get("mandrill_events")
# URL解码
decoded_events = urllib.parse.unquote(encoded_events)

2. 校验JSON格式合法性

解码后,把字符串复制到本地的JSON校验工具(比如JSONlint桌面版)里检查,看是否存在语法错误:

  • 有没有多余的尾逗号
  • 引号是否配对(比如单引号混双引号)
  • 数组括号[]是否闭合

3. 处理双重转义问题

有时候请求中的JSON会被双重转义(比如\"变成\\\"),这时候需要先还原转义字符:

  • Java可以用org.apache.commons.text.StringEscapeUtils.unescapeJava(decodedEvents)处理
  • Python可以用ast.literal_eval(decoded_events)先做转义还原,再用json.loads()解析

4. 正确解析为数组

Mandrill的事件是数组格式,别尝试解析成单个对象!最终解析示例:

  • Java(用Jackson):
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.type.TypeReference;
import java.util.List;
import java.util.Map;

ObjectMapper objectMapper = new ObjectMapper();
// 解析为Map组成的List
List<Map<String, Object>> eventsList = objectMapper.readValue(decodedEvents, new TypeReference<List<Map<String, Object>>>() {});
// 访问指定值,比如获取第一个事件的类型
String firstEventType = (String) eventsList.get(0).get("event");
  • Python:
import json

events_list = json.loads(decoded_events)
# 遍历事件并访问值
for event in events_list:
    print(f"事件类型:{event.get('event')}")

二、实现JSON对象数组转Map的功能

JSON数组转Map需要先确定Map的key规则,常用两种方案:

方案1:用数组索引作为Map的key

适合不需要业务唯一标识的场景:

  • Java:
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.core.type.TypeReference;

public Map<Integer, Map<String, Object>> arrayToMapByIndex(String jsonArrayStr) throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    List<Map<String, Object>> jsonList = mapper.readValue(jsonArrayStr, new TypeReference<List<Map<String, Object>>>() {});
    Map<Integer, Map<String, Object>> resultMap = new HashMap<>();
    for (int i = 0; i < jsonList.size(); i++) {
        resultMap.put(i, jsonList.get(i));
    }
    return resultMap;
}
  • Python:
import json

def array_to_map_by_index(json_array_str):
    json_list = json.loads(json_array_str)
    return {idx: item for idx, item in enumerate(json_list)}

方案2:用对象中的唯一字段作为Map的key

如果数组里的每个对象都有唯一标识(比如id字段),可以用它作为key:

  • Java:
public Map<String, Map<String, Object>> arrayToMapByUniqueKey(String jsonArrayStr) throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    List<Map<String, Object>> jsonList = mapper.readValue(jsonArrayStr, new TypeReference<List<Map<String, Object>>>() {});
    Map<String, Map<String, Object>> resultMap = new HashMap<>();
    for (Map<String, Object> item : jsonList) {
        String uniqueId = (String) item.get("id");
        if (uniqueId != null) {
            resultMap.put(uniqueId, item);
        }
    }
    return resultMap;
}
  • Python:
def array_to_map_by_unique_key(json_array_str):
    json_list = json.loads(json_array_str)
    result_map = {}
    for item in json_list:
        item_id = item.get("id")
        if item_id is not None:
            result_map[item_id] = item
    return result_map

排查小贴士

如果还是解析失败,把解码后的完整字符串打印出来,肉眼检查是否有明显的格式问题——比如有时候网关或代理会额外添加字符,破坏JSON结构。

内容的提问来源于stack exchange,提问作者Cyzanfar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:19:40