Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Scala中使用JSON.parseFull时报告解析错误_Json_Scala - Fatal编程技术网

如何在Scala中使用JSON.parseFull时报告解析错误

如何在Scala中使用JSON.parseFull时报告解析错误,json,scala,Json,Scala,当我的应用程序接收到语法不正确的JSON时,我希望能够向用户报告错误,并提供一些有用的细节,以便找到问题区域 因此,在本例中,j将是None,因为“File1”后面有一个逗号。是否有方法获取上次分析错误的详细信息 val badSyntax = """ { "menu1": { "id": "file1", "value": "File1", }, "menu2": { "id": "file2", "value": "File2", }

当我的应用程序接收到语法不正确的JSON时,我希望能够向用户报告错误,并提供一些有用的细节,以便找到问题区域

因此,在本例中,j将是None,因为“File1”后面有一个逗号。是否有方法获取上次分析错误的详细信息

    val badSyntax = """
{
  "menu1": {
    "id": "file1",
    "value": "File1",
  },
  "menu2": {
    "id": "file2",
    "value": "File2",
  }
}"""

    val j = JSON.parseFull(badSyntax)

当出现解析错误时,使用
JSON.lastnosucces
获取最后一个错误。它属于
JSON.NoSuccess
类型,其中有两个子类,
JSON.Error
JSON.Failure
,都包含详细说明错误的
msg:String
成员。 请注意,
JSON.lastNoSuccess
不是线程安全的(它只是一个全局变量),现在已被弃用(必然会在scala 2.11中消失)

更新:显然,我错误地认为它不是线程安全的:在scala 2.10之前它确实不是线程安全的,但是现在
lastNoSuccess
由线程局部变量支持(因此在多线程上下文中使用是安全的)。 在完成此任务后,您可以认为,只要您在解析失败后立即阅读与用于解析的线程相同的线程(您称之为
parseFull
)中的,那么一切都将按预期工作。不幸的是,在此重构过程中,他们还改变了
lastNoSuccess
Parsers.phrase
内部使用
JSON.parseFull
的方式。 看见 由于此重构,
lastnosucces
Parsers.phrase
的末尾被重置为
None
。这在解析器中通常没有问题,因为
lastNoSuccess
被用作作为
解析器的结果返回的临时值。
这里的问题是,我们不调用
Parsers.phrase
,而是调用
JSON.parseFull
,这会删除任何错误信息(请参见
case None=>None
方法内的
JSON.parseRaw
at)。 在scala 2.10之前,
JSON.parseFull
删除任何错误信息的事实可以通过直接读取
JSON.lastNoSuccess
轻松避免,正如我之前所建议的,但是现在在
Parsers.phrase
的末尾重置了该值,因此您无法从
JSON
中获取错误信息

有解决方案吗?有。您可以创建自己的
JSON
版本,该版本不会删除错误信息:

import util.parsing.json._

object MyJSON extends Parser {
  def parseRaw(input : String) : Either[NoSuccess, JSONType] = {
    phrase(root)(new lexical.Scanner(input)) match {
      case Success(result, _) => Right(result)
      case ns: NoSuccess => Left(ns)
    }
  }

  def parseFull(input: String): Either[NoSuccess, Any] = {
    parseRaw(input).right.map(resolveType)
  }

  def resolveType(input: Any): Any = input match {
    case JSONObject(data) => data.transform {
      case (k,v) => resolveType(v)
    }
    case JSONArray(data) => data.map(resolveType)
    case x => x
  }
}
我刚刚将
选项
更改为
作为结果类型,这样我就可以将解析错误作为
返回

scala> MyJSON.parseFull("[1,2,3]")
res11: Either[MyJSON.NoSuccess,Any] = Right(List(1.0, 2.0, 3.0))

scala> MyJSON.parseFull("[1,2,3")
res12: Either[MyJSON.NoSuccess,Any] =
Left([1.7] failure: end of input

[1,2,3
      ^)

感谢您的回答,但它不适用于我的2.10.0版本。
JSON。lastNoSuccess
在解析错误数据后为
null
。事实上,我现在可以确认这一点。我进行了(长时间)更新,请查看。