Object对象转字符串爆内存

当面对大对象转换为JSON字符串时,传统的JSON.toJSONString()可能导致内存溢出。文章提出使用Jackson库的ObjectMapper配合流式处理来避免这个问题。通过创建JsonGenerator,逐步将JSON写入输出流,例如只写入前2000个字符,从而减少内存占用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JSON.toJSONString(jsonResult)

当尝试使用 JSON.toJSONString() 方法将一个较大的对象转换为 JSON 字符串时,可能会导致内存溢出的问题。Handler dispatch failed; nested exception is java.lang.OutOfMemoryError

解决方法:使用流式处理,以及逐步地将 JSON 字符串写入输出流,而不是将整个字符串存储在内存中

ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(jsonResult);

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
JsonGenerator jsonGenerator = objectMapper.getFactory().createGenerator(outputStream);

jsonGenerator.writeRawValue(json.substring(0, Math.min(json.length(), 2000)));
jsonGenerator.flush();

String jsonString = outputStream.toString();

使用 Jackson 库的 ObjectMapper 类将 jsonResult 对象转换为 JSON 字符串。然后,我们创建了一个 ByteArrayOutputStream 输出流和一个 JsonGenerator 对象。

通过使用 JsonGenerator 的 writeRaw() 方法,我们将 JSON 字符串逐步写入输出流,并通过设置长度限制,只写入前 2000 个字符。最后,我们将输出流转换为字符串

### ObjectMapper 使用指南及其常见问题 #### 1. ObjectMapper 的基本功能 `ObjectMapper` 是 Jackson 库中的核心类之一,用于实现 Java 对象与 JSON 字符串之间的相互换。以下是 `ObjectMapper` 的主要功能: - **Java 对象 JSON 字符串** 可以通过 `writeValueAsString()` 方法将 Java 对象序列化为 JSON 字符串[^3]。 ```java ObjectMapper objectMapper = new ObjectMapper(); String jsonString = objectMapper.writeValueAsString(myObject); ``` - **JSON 字符串 Java 对象** 利用 `readValue()` 方法可以从 JSON 字符串反序列化为指定类型的 Java 对象[^1]。 ```java MyObject myObject = objectMapper.readValue(jsonString, MyObject.class); ``` #### 2. 配置选项 `ObjectMapper` 提供了许多配置选项,可以根据需求自定义行为。 - **设置日期格式** 如果需要处理日期时间字段,可以通过 `setDateFormat()` 设置特定的日期格式[^4]。 ```java SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); objectMapper.setDateFormat(sdf); ``` - **忽略未知属性** 当 JSON 数据中存在未映射到 Java 类的字段时,可通过以下方式避免抛出异常[^4]。 ```java objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); ``` - **启用/禁用特性** 支持多种特性的开关操作,例如允许单引号或注释等。 ```java objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); ``` #### 3. 错误处理 在实际开发过程中可能会遇到一些常见的错误场景以及对应的解决方案。 - **NullPointerException** 如果目标对象为空,则会引发 NullPointerException。建议先判断对象是否为 null。 ```java if (myObject != null) { String jsonString = objectMapper.writeValueAsString(myObject); } ``` - **JsonMappingException 和 JsonParseException** 这些异常通常发生在数据不匹配或者格式非法的情况下。推荐捕获并记录这些异常以便调试[^3]。 ```java try { MyObject obj = objectMapper.readValue(jsonData, MyObject.class); } catch (JsonMappingException | JsonParseException e) { log.error("Error parsing JSON", e); } ``` #### 4. 实际案例分析 下面展示了一个综合使用的例子,涵盖了多个方面如日期格式设定、未知属性容忍度调整等。 ```java import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; public class ExampleUsage { public static void main(String[] args) throws Exception { ObjectMapper mapper = new ObjectMapper(); // 设定日期格式 mapper.setDateFormat(new java.text.SimpleDateFormat("dd/MM/yyyy")); // 忽略未知字段 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); String jsonInput = "{ \"date\" : \"01/01/2023\", \"extraField\" : \"ignored\"}"; DataModel model = mapper.readValue(jsonInput, DataModel.class); System.out.println(model.getDate()); } static class DataModel { private java.util.Date date; public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } } } ``` --- ###
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值