如何使用json4s解析无分隔符的流式JSON对象?
处理json4s解析多无分隔符JSON对象的方案
这个场景太常见了!我之前做流式数据处理时也踩过同样的坑——json4s的parse方法确实只会解析第一个JSON对象就停住,但其实不用自己手动拼数组或者拆分字符串,我们可以借助它底层依赖的Jackson流式解析能力来完美解决。
核心思路
json4s默认使用Jackson作为JSON解析引擎,而Jackson本身就支持流式逐个解析JSON对象,我们可以直接利用这一点,让json4s配合Jackson的JsonParser来遍历所有的JSON对象,而不是只解析第一个。
具体实现代码
先导入需要的依赖包:
import org.json4s._ import org.json4s.jackson.JsonMethods._ import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.databind.ObjectMapper
然后写一个通用的解析方法,不管是字符串形式的流式数据,还是真正的输入流都能用:
def parseMultiJson(input: String): List[JValue] = { // 初始化Jackson的解析器 val mapper = new ObjectMapper() val parser: JsonParser = mapper.getFactory.createParser(input) // 先跳过开头的空白字符,定位到第一个JSON对象的起始位置 parser.nextToken() val result = collection.mutable.ListBuffer[JValue]() // 循环解析每个JSON对象 while (parser.hasCurrentToken) { // 用json4s的parse方法从当前解析器位置读取一个完整的JSON对象 val singleJson = parse(parser) result += singleJson // 移动到下一个token,自动跳过对象之间的空白字符 parser.nextToken() } result.toList }
如果是处理真正的流式数据源(比如InputStream),只需要把方法参数换成InputStream即可:
def parseMultiJsonStream(input: java.io.InputStream): List[JValue] = { val mapper = new ObjectMapper() val parser: JsonParser = mapper.getFactory.createParser(input) parser.nextToken() val result = collection.mutable.ListBuffer[JValue]() while (parser.hasCurrentToken) { val singleJson = parse(parser) result += singleJson parser.nextToken() } result.toList }
为什么比手动方案可靠?
你提到的手动加括号转数组或者拆分字符串的方式,在遇到JSON字段内部包含空白字符(比如字符串值里的空格、换行)时很容易出错,而用Jackson的流式解析会严格按照JSON语法来识别每个对象的边界,完全不会出现误拆分的问题。
测试示例
假设你的流式数据是这样的:
{"name":"Alice","age":30} {"name":"Bob","age":25} {"name":"Charlie","age":35}
调用parseMultiJson方法后,会返回包含三个JObject的列表,每个对应一个用户对象,完美解决你的问题。
内容的提问来源于stack exchange,提问作者otus
相关产品推荐
相关产品推荐

