如何使用带连字符的camelizeKeys

时间:2015-09-23 23:54:49

标签: json scala json4s

我正在解析来自Web服务的json响应,该服务包含使用连字符定义的一些字段。我想在scala案例类中将这些名称转换为混合大小写的名称。我想使用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:perPage没有可用的值   没找到可以转换成int的值

2 个答案:

答案 0 :(得分:0)

解决方法是在解析文本之前用下划线替换所有出现的连字符。所以可以做以下事情:

parse(str.replaceAll("([a-z])-([a-z])", "$1_$2")).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('-', '_'))

答案 1 :(得分:0)

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

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

这个函数是参考json4s中的rewriteJsonAST实现的

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