如何使用带有连字符的 camelizeKeys

How to use camelizeKeys with hyphens

我正在解析来自 Web 服务的 json 响应,其中一些字段使用连字符定义。我想在我的 scala 案例 class 中将这些名称转换为混合案例名称。我想使用 camelizeKeys 规定,但它似乎不起作用。例如,假设我有一个 json 响应,例如:

{"offset":0,"total":359,"per-page":20}

转换为:

case class Response(offset: Int, total: Int, perPage: Int)

我也是:

parse(str).camelizeKeys.extract[Response]

我收到错误:

Ex: org.json4s.package$MappingException: No usable value for perPage Did not find value which can be converted into int

解决方法是在解析文本之前用下划线替换所有出现的连字符。因此可以执行以下操作:

parse(str.replaceAll("([a-z])-([a-z])", "_")).camelizeKeys.extract[Response] 

但是这个解决方案有局限性,因为它可能无法处理复杂的数据结构;如果任何字段值包含此类模式,您最终可能会破坏返回的数据。所以一个更完整的解决方案是编写我自己的 replaceAll 函数:

def replaceAll(str: String, regex: String)(f: String => String) = {
    val pattern = regex.r
    val (s, i) = (("", 0) /: pattern.findAllMatchIn(str)) { case ((s, i), m) =>
        (s + str.substring(i, m.start) + f(m.toString), m.end)
    }
    s + str.substring(i)
}

并将其应用于我的 json 字符串:

replaceAll(str, "\"[0-9a-z\-]*\":")(_.replace('-', '_'))

您可以用下划线替换连字符,如下所示。

def replaceHyphens(value: JValue): JValue = {
    value.transformField {
        case JField(name, x) => JField(name.replaceAll("-", "_"), x)
    }
}

该功能参考json4s中的rewriteJsonAST实现

replaceHyphens(parse(str)).camelizeKeys.extract[Response]