【问题标题】:Scala Json Lift - MappingException error for one recordScala Json Lift - 一条记录的 MappingException 错误
【发布时间】:2018-08-26 00:40:06
【问题描述】:

我在解析 json 时遇到问题。仅当有一组记录是否所有列都具有值或一个或多个列为空值时才会出现此问题。其他情况下它工作正常。

我的输入案例类如下:

    case class Source(AccountNo: String, Name: String)
    case class HitsIndex(_index: String, _type: String, _id: String, _score: Double, _source: Source)
    case class HitsCount(total: Int, max_score: Double, hits: List[HitsIndex])
    case class Shards(total: Int, successful: Int, failed: Int, hits: HitsCount)
    case class ParseJson(took: Int, timed_out: Boolean, _shards: Shards)

导入语句:

import scala.collection.mutable._
import net.liftweb.json._
import net.liftweb.json.DefaultFormats
import net.liftweb.json.Serialization.write

下面是我测试的代码:

 case class Uiresult(AccountNo: String, Name: String)

    val json = parse(jsonString)
    val elements = (json \\ "_source").children
    for (acct <- elements) {
      val m = acct.extract[Source]
      val res = write(Uiresult(m.accountNo,  (m.firstName.toString() + m.lastName.toString()))
      println(res)
    }

一条记录的期望输出:

注意:姓氏为空

[
{"AccountNo":"1234","Name":"Augustin "}
]

注意:所有列都有值

[
{"AccountNo":"1234","Name":"Augustin Wagstuff "}
]

但收到如下错误消息:

 > Exception in thread "main" net.liftweb.json.MappingException: No usable value for AccountNo
    Did not find value which can be converted into java.lang.String
        at net.liftweb.json.Meta$.fail(Meta.scala:191)
        at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:357)
        at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:317)
        at net.liftweb.json.Extraction$$anonfun$14.apply(Extraction.scala:253)
        at net.liftweb.json.Extraction$$anonfun$14.apply(Extraction.scala:253)
        at scala.collection.immutable.List.map(List.scala:273)
        at net.liftweb.json.Extraction$.instantiate$1(Extraction.scala:253)
        at net.liftweb.json.Extraction$.newInstance$1(Extraction.scala:286)
        at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:315)
        at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$extract0(Extraction.scala:366)
        at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$extract0(Extraction.scala:199)
        at net.liftweb.json.Extraction$.extract(Extraction.scala:43)
        at net.liftweb.json.JsonAST$JValue.extract(JsonAST.scala:312)
        at com.aexp.prospect.atul.sample_01.JsonRead$$anonfun$1.apply(JsonRead.scala:115)
        at com.aexp.prospect.atul.sample_01.JsonRead$$anonfun$1.apply(JsonRead.scala:114)
        at scala.collection.immutable.List.map(List.scala:273)
        at com.aexp.prospect.atul.sample_01.JsonRead$.main(JsonRead.scala:114)
        at com.aexp.prospect.atul.sample_01.JsonRead.main(JsonRead.scala)
    Caused by: net.liftweb.json.MappingException: Did not find value which can be converted into java.lang.String
        at net.liftweb.json.Meta$.fail(Meta.scala:191)
        at net.liftweb.json.Extraction$.convert(Extraction.scala:403)
        at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:314)
        at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:351)
        ... 16 more

我的输入 Json:(姓氏为空)

注意:所有列都有值

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 3,
    "successful": 3,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 2.2488084,
    "hits": [
      {
        "_index": "test_02",
        "_type": "test_type",
        "_id": "123456",
        "_score": 2.2488084,
        "_source": {
          "AccountNo": "06009625297",
          "firstName": "Augustin",
          "lastName": "Wagstuff "
        }
      }
    ]
  }
}   

注意:姓氏为空

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 3,
    "successful": 3,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 2.2488084,
    "hits": [
      {
        "_index": "test_02",
        "_type": "test_type",
        "_id": "123456",
        "_score": 2.2488084,
        "_source": {
          "AccountNo": "06009625297",
          "firstName": "Augustin",
          "lastName": ""
        }
      }
    ]
  }
}   

Json 对象打印:

示例 1:
在这里,我注意到所有列都有价值。我只选择了一组记录,这是一个问题。

json JObject(List(JField(took,JInt(1)),JField(timed_out,JBool(false)),JField(_shards,JObject(List(JField(total,JInt(3)),JField(成功, JInt(3)), JField(失败,JInt(0))))), JField(命中,JObject(List(JField(total,JInt(1))), JField(max_score,JDouble(2.2488084)), JField(命中,JArray(List(JObject(List(JField(_index,JString(test_02))), JField(_type,JString(test_type)), JField(_id,JString(123456)), JField(_score,JDouble(2.2488084)), JField (_source,JObject(List(JField(AccountNo,JString(06009625297)), JField(firstName,JString(Augustin)), JField(lastName,JString()))))))))))))))

示例:2 在这里,我注意到这里的 lastName 是空的。我只选择了一组记录,这是一个问题。有人可以帮助我如何处理这种情况。

json JObject(List(JField(took,JInt(1)),JField(timed_out,JBool(false)),JField(_shards,JObject(List(JField(total,JInt(3)),JField(成功, JInt(3)), JField(失败,JInt(0))))), JField(命中,JObject(List(JField(total,JInt(1))), JField(max_score,JDouble(2.2488084)), JField(命中,JArray(List(JObject(List(JField(_index,JString(test_02))), JField(_type,JString(test_type)), JField(_id,JString(123456)), JField(_score,JDouble(2.2488084)), JField (_source,JObject(List(JField(AccountNo,JString(06009625297)), JField(firstName,JString(Augustin)), JField(lastName,JString()))))))))))))))

输入中有 2 组或更多记录集的示例:

输入有 2 组记录(仅提取 2 条而不是 1 条):这不会产生任何问题并产生所需的输出。如果您注意到第一个记录与之前的示例相同:2 输入,但这里它不会产生任何错误。

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 3,
    "successful": 3,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 2.2488084,
    "hits": [
      {
        "_index": "test_02",
        "_type": "test_type",
        "_id": "123456",
        "_score": 2.2488084,
        "_source": {
          "AccountNo": "06009625297",
          "firstName": "Augustin",
          "lastName": "Wagstuff"
        },
               "hits": [
      {
        "_index": "test_02",
        "_type": "test_type",
        "_id": "789078",
        "_score": 2.2188084,
        "_source": {
          "AccountNo": "06009625297",
          "firstName": "Augustin",
          "lastName": "Jhonson"
        }
      }
    ]
  }
}

输出:正如预期的那样。

[
    {"AccountNo":"06009625297","Name":"Augustin Wagstuff "},
    {"AccountNo":"06009625297","Name":"Augustin Jhonson"},

    ]

代码中的acct值:

当我在输出中有一组记录时尝试在账户中显示竞争(引用代码中的变量)时,我只看到第一列,即使输入中的所有其他列都有效价值观。

acct JField(AccountNo,JString(1234))

当输出中有两组记录时,当我尝试在账户中显示竞争(引用代码中的变量)时,我只看到第一列,即使所有列都具有有效值。

acct JField(_source,JObject(List(JField(AccountNo,JString(06009625297)), JField(firstName,JString(Augustin)), JField(lastName,JString(Wagstuff)))))

acct JField(_source,JObject(List(JField(AccountNo,JString(06009625297)), JField(firstName,JString(Augustin)), JField(lastName,JString(Jhonson)))))

我在迭代列表时怀疑这个问题。请有人帮我解决。

【问题讨论】:

  • 我把其他问题的信息移到了这里。检查一下,我得到了所有相关数据,希望你能解决它
  • 谢谢谢多。我看到了,详细信息可在链接中找到。戴夫惠特克---->用户:829752。你们中的一个人可以帮助我或联系他解决这个问题吗? stackoverflow.com/questions/25299474/…。另请参阅另一个答案但无法获得解决方案:stackoverflow.com/questions/34170046/…
  • 我更新了有关我的问题的更多详细信息。尤其是我遇到此问题并在失败前捕获数据的情况。希望这将有助于提供解决方案。如果您需要更多详细信息,请告诉我。
  • 谁能帮我解决这个问题。

标签: json scala lift-json


【解决方案1】:

我创建了一个代码来处理输入记录为 1 或零时。 2 条或更多条记录正在运行(感谢 Shaido)。下面是代码,有人可以建议,是否可以以更好的方式构造此代码。

case class Source(AccountNo: fnameString, : String, lname: String)
case class HitsIndex(_index: String, _type: String, _id: String, _score: Double, _source: Source)
case class HitsCount(total: Int, max_score: Double, hits: List[HitsIndex])
case class Shards(total: Int, successful: Int, failed: Int)
case class ParseJson(took: Int, timed_out: Boolean, _shards: Shards, hits: HitsCount)

case class Uiresult(masterid: String, value: String)
case class ErrorMsg(searchType: String, error_message: String)

def formatResult(jsonString: String, searchType: String): String = {
  implicit val formats = DefaultFormats
  val json = JsonParser.parse(jsonString)

  val elements = (json \\ "_source").children
  if (elements.isEmpty == true) {
    implicit val formats = DefaultFormats
    return (List(write(ErrorMsg(searchType, "No Matching Record Found"))).mkString("[\n", ",\n", "\n]"))
  }
  if (json.extract[ParseJson].hits.total == 1) {
    val m = (json \\ "_source").extract[Source]
    val list = List(write(Uiresult(m.AccountNo.toString(), (m.fname.toString() + m.lname.toString() ))))
    return (list.mkString("[\n", ",\n", "\n]"))

  } else {
    val elements = (json \\ "_source").children
    val list = for (source <- elements) yield {
      println(" source " + source)
      val m = source.extract[Source]
      val list = List(write(Uiresult(m.AccountNo.toString(), (m.fname.toString() + m.lname.toString() ))))
    }
    return (list.mkString("[\n", ",\n", "\n]"))
  }
}

【讨论】:

    【解决方案2】:

    Parse json using liftweb in scala with no usable value也有类似的讨论

    我在使用lift-json_2.11版本为3.2.0时也遇到了这个问题,经过多次尝试,我终于用2.6.3版本解决了这个问题

    <dependency>
        <groupId>net.liftweb</groupId>
        <artifactId>lift-json_2.11</artifactId>
        <version>2.6.3</version>
    </dependency>
    

    【讨论】:

    • 您能否添加一个代码示例,该依赖项允许您使用?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-07
    • 1970-01-01
    • 2020-05-27
    • 1970-01-01
    相关资源
    最近更新 更多