当 jackson objectmapper 默认序列化 jsonobject 类型字段时,会将其转为内部状态描述(如 {"empty":false,"maptype":"..."}),而非实际 json 内容;需通过自定义 jsonserializer 将其显式转换为 map 后序列化。
当 jackson objectmapper 默认序列化 jsonobject 类型字段时,会将其转为内部状态描述(如 {"empty":false,"maptype":"..."}),而非实际 json 内容;需通过自定义 jsonserializer 将其显式转换为 map 后序列化。
Jackson 本身并不原生支持 org.json.JSONObject 的语义化序列化——它仅将其视为普通 Java 对象,因此会反射读取其公有字段(如 empty、mapType 等),导致输出不符合预期的 JSON 结构。要获得 {"json":{"key":"value"}} 这样的结果,核心思路是绕过默认反射序列化,主动将 JSONObject 转换为标准 Map
以下是一个完整、可运行的解决方案:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.json.JSONObject;
record Random(String name, JSONObject json) {}
public class SerializerExample {
public static void main(String[] args) throws Exception {
JSONObject json = new JSONObject();
json.put("key", "value");
Random random = new Random("name", json);
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(JSONObject.class, new JSONObjectSerializer());
mapper.registerModule(module);
String result = mapper.writeValueAsString(random);
System.out.println(result); // 输出: {"name":"name","json":{"key":"value"}}
}
public static class JSONObjectSerializer extends JsonSerializer<jsonobject> {
@Override
public void serialize(JSONObject value, JsonGenerator gen, SerializerProvider serializers)
throws java.io.IOException {
if (value == null) {
gen.writeNull();
} else {
gen.writeObject(value.toMap()); // ✅ 关键:委托给 Jackson 序列化 Map
}
}
}
}</jsonobject>
✅ 关键说明:
- JSONObject.toMap() 是 org.json 库提供的标准方法,能递归地将嵌套的 JSONObject/JSONArray 转为 Map/List,完美兼容 Jackson 的泛型序列化能力;
- 使用 JsonSerializer(而非已弃用的 StdSerializer)更符合现代 Jackson 2.12+ 最佳实践;
- gen.writeObject(...) 会自动处理 null、嵌套对象、集合等,无需手动遍历;
⚠️ 注意事项:
- 此方案假设 JSONObject 中只含 JSON 兼容类型(String、Number、Boolean、JSONObject、JSONArray、null),否则 toMap() 可能抛出 JSONException;
- 若项目中大量使用 JSONObject,建议统一替换为 Jackson 的 ObjectNode 或 Map
,从根本上避免序列化适配问题; - 不推荐在 DTO 中混用 org.json.* 和 Jackson 类型——保持 JSON 抽象层一致可显著降低维护成本。
通过注册自定义序列器,你既保留了现有代码结构,又精准控制了序列化行为,实现语义正确、可预测的 JSON 输出。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











