스칼라 / 리프트로 JSON 스트링을 구성하고 구문 분석하려면 어떻게해야합니까?
문제
JSON을 사용하여 브라우저와 앱간에 데이터를 보내려고합니다.
JSON 현을 생성하고 구문 분석하기 위해 리프트 1.0을 사용하려고하지만 어떤 이유로 든 방금 구성한 JSON을 구문 분석 할 수 없습니다.
scala>import scala.util.parsing.json.JSON._
import scala.util.parsing.json.JSON._
scala> import net.liftweb.http.js._
import net.liftweb.http.js._
scala> import net.liftweb.http.js.JE._
import net.liftweb.http.js.JE._
scala> val json = JsObj(("foo", 4), ("bar", "baz")).toJsCmd
json: String = {'foo': 4, 'bar': 'baz'}
scala> parseFull(json)
res3: Option[Any] = None
다시 구문 분석 할 수있는 Scala/Lift에서 유효한 JSON 메시지를 프로그래밍 방식으로 구성합니까?
해결책
리프트 1.0을 사용하고 있습니다 JsCmd
, 단일 크기의 줄로 JSON을 생성하고 Scala의 구문 분석기로 구문 분석하려고 시도합니다.
JSON에 대한 여러 정의가 있다는 것을 인식하는 것이 중요합니다.
JSON에서 단일 크기의 문자열이 유효합니까?
- 그들은 다음과 같습니다 ECMAScript 5th ed
- 그들은 Crockford의 원본에 따른 것이 아닙니다 RFC 4627
리프트와 스칼라는 JSON을 구문 분석하는 여러 가지 방법을 제공하며, 때로는 버전 간의 동작이 다릅니다.
이 파서에 의해 받아 들여지는 줄은 동등하지 않습니다.
다음은 제품 및 Parse JSON 스트링에 대한 다양한 방법에 대한 몇 가지 의견과 예입니다.
The와 함께 JSON을 생산합니다 리프트 -JSON 도서관 DSL
- 추천
- 그 이름에도 불구하고 이것은 나머지 리프트에 의존성이없는 별도의 프로젝트입니다.
예시:
scala> import net.liftweb.json.JsonAST
import net.liftweb.json.JsonAST
scala> import net.liftweb.json.JsonDSL._
import net.liftweb.json.JsonDSL._
scala> import net.liftweb.json.Printer._
import net.liftweb.json.Printer._
scala> val json1 = ("foo" -> 4) ~ ("bar" -> "baz")
json1: net.liftweb.json.JsonAST.JObject = JObject(List(JField(foo,JInt(4)), JField(bar,JString(baz))))
scala> compact(JsonAST.render(json1))
res0: String = {"foo":4,"bar":"baz"}
scala> val json2 = List(1,2,3)
json2: List[Int] = List(1, 2, 3)
scala> compact(JsonAST.render(json2))
res1: String = [1,2,3]
scala> val json3 = ("foo", 4) ~ ("bar", List(1,2,3))
json3: net.liftweb.json.JsonAST.JObject = JObject(List(JField(foo,JInt(4)), JField(bar,JArray(List(JInt(1), JInt(2), JInt(3))))))
scala> compact(JsonAST.render(json3))
res2: String = {"foo":4,"bar":[1,2,3]}
JSON을 구문 분석합니다 리프트 -JSON 도서관
- 추천
- Scala Case-Classes에 대한 암시 적 매핑을 제공합니다
- 콘솔에 정의 된 사례 클래스는 현재 지원되지 않습니다 (
com.thoughtworks.paranamer.ParameterNamesNotFoundException: Unable to get class bytes
) - 아래의 예는 사용합니다
Publicid
, 스칼라 콘솔에서 작동하도록 기존 스칼라 케이스 클래스.
예시:
scala> import scala.xml.dtd.PublicID
import scala.xml.dtd.PublicID
scala> import net.liftweb.json._
import net.liftweb.json._
scala> import net.liftweb.json.JsonAST._
import net.liftweb.json.JsonAST._
scala> import net.liftweb.json.JsonDSL._
import net.liftweb.json.JsonDSL._
scala> implicit val formats = DefaultFormats
formats: net.liftweb.json.DefaultFormats.type = net.liftweb.json.DefaultFormats$@7fa27edd
scala> val jsonAst = ("publicId1" -> "idString") ~ ("systemId" -> "systemIdStr")
jsonAst: net.liftweb.json.JsonAST.JObject = JObject(List(JField(publicId,JString(idString)), JField(systemId,JString(systemIdStr))))
scala> jsonAst.extract[PublicID]
res0: scala.xml.dtd.PublicID = PUBLIC "idString" "systemIdStr"
Scala 2.7.7 및 2.8.1의 JSON을 구문 분석합니다
- 권장되지 않음 - "더 이상 실제로 지원되지 않습니다"
- Scala 2.7.7의 파서는 단일 크기의 JSON을 구문 분석하지 않습니다
- 이 질문에 사용 된이 구문 분석 방법
예시:
scala>import scala.util.parsing.json.JSON._
import scala.util.parsing.json.JSON._
scala> parseFull("{\"foo\" : 4 }")
res1: Option[Any] = Some(Map(foo -> 4.0))
scala> parseFull("[ 1,2,3 ]")
res2: Option[Any] = Some(List(1.0, 2.0, 3.0))
scala> parseFull("{'foo' : 4 }")
res3: Option[Any] = None
리프트 2.0 및 2.2에서 JSON을 구문 분석합니다 util.jsonparser
- 중립 추천
- Lift 's util.jsonparser는 단일 또는 이중 인용 JSON 문자열을 구문 분석합니다.
예시:
scala> import net.liftweb.util.JSONParser._
import net.liftweb.util.JSONParser._
scala> parse("{\"foo\" : 4 }")
res1: net.liftweb.common.Box[Any] = Full(Map(foo -> 4.0))
scala> parse("[ 1,2,3 ]")
res2: net.liftweb.common.Box[Any] = Full(List(1.0, 2.0, 3.0))
scala> parse("{'foo' : 4}")
res3: net.liftweb.common.Box[Any] = Full(Map(foo -> 4.0))
리프트 2.0 및 2.2에서 JSON을 구문 분석합니다 json.jsonparser
- 중립 추천
- LIFT의 JSON.JSONPARSER는 단일 크기의 JSON 문자열을 구문 분석하지 않습니다.
예시:
scala> import net.liftweb.json._
import net.liftweb.json._
scala> import net.liftweb.json.JsonParser._
import net.liftweb.json.JsonParser._
scala> parse("{\"foo\" : 4 }")
res1: net.liftweb.json.JsonAST.JValue = JObject(List(JField(foo,JInt(4))))
scala> parse("[ 1,2,3 ]")
res2: net.liftweb.json.JsonAST.JValue = JArray(List(JInt(1), JInt(2), JInt(3)))
scala> parse("{'foo' : 4}")
net.liftweb.json.JsonParser$ParseException: unknown token '
Near: {'foo' : 4}
at net.liftweb.json.JsonParser$Parser.fail(JsonParser.scala:216)
at net.liftweb.json.JsonParser$Parser.nextToken(JsonParser.scala:308)
at net.liftweb.json.JsonParser$$anonfun$1.apply(JsonParser.scala:172)
at net.liftweb.json.JsonParser$$anonfun$1.apply(JsonParser.scala:129)
at net.liftweb.json.JsonParse...
리프트 1.0 JSCMD로 JSON 생산
- 권장되지 않음 - 모든 JSON 파서에 유효하지 않은 출력
- 문자열 주변의 단일 인용문에 유의하십시오.
예시:
scala> import net.liftweb.http.js._
import net.liftweb.http.js._
scala> import net.liftweb.http.js.JE._
import net.liftweb.http.js.JE._
scala> JsObj(("foo", 4), ("bar", "baz")).toJsCmd
res0: String = {'foo': 4, 'bar': 'baz'}
scala> JsArray(1,2,3).toJsCmd
res1: String =
[1, 2, 3]
scala> JsObj(("foo", 4), ("bar", JsArray(1,2,3))).toJsCmd
res2: String =
{'foo': 4, 'bar': [1, 2, 3]
}
리프트 2.0 JSCMD로 JSON 생산
- 중립 추천
- 문자열 주변의 이중 인용문에 주목하십시오.
예시:
scala> import net.liftweb.http.js._
import net.liftweb.http.js._
scala> import net.liftweb.http.js.JE._
import net.liftweb.http.js.JE._
scala> JsObj(("foo", 4), ("bar", "baz")).toJsCmd
res0: String = {"foo": 4, "bar": "baz"}
scala> JsArray(1,2,3).toJsCmd
res1: String =
[1, 2, 3]
scala> JsObj(("foo", 4), ("bar", JsArray(1,2,3))).toJsCmd
res3: String =
{"foo": 4, "bar": [1, 2, 3]
}
스칼라에서 JSON 생산 (2.10으로 테스트)
- "더 이상 실제로 지원되지 않습니다"하지만 효과가 있고 거기에 있습니다.
예시:
scala> import scala.util.parsing.json._
import scala.util.parsing.json._
scala> JSONObject (Map ("foo" -> 4, "bar" -> JSONArray (1 :: 2 :: 3 :: Nil))) .toString()
res0: String = {"foo" : 4, "bar" : [1, 2, 3]}
다른 팁
보세요 요부. 사용하는 것이 정말 좋으며 새로운 도구를 활용합니다. 엉성한 그리고 고양이. 또한, 당신은 그것을 사용할 수 있습니다 Scala는 JavaScript로 컴파일되었습니다.
에서 가져 왔습니다 Circe Readme:
Scala> import io.circe., io.circe.generic.auto., io.circe.parser., io.circe.syntax. 가져 오기 io.circe._ 가져 오기 io.circe.generic.auto._ import io.circe.parser._ 가져 오기 io.circe.syntax._
Scala> 봉인 된 특성 foo 정의 된 특성 foo
Scala> Case Class Bar (XS : List [String]) 확장 FOO 정의 클래스 표시 줄
scala> case class qux (i : int, d : 옵션 [double]) 확장 foo 정의 클래스 qux.
scala> val foo : foo = qux (13, 일부 (14.0)) foo : foo = qux (13, 일부 (14.0))
scala> foo.asjson.nospaces res0 : String = { "qux": { "d": 14.0, "i": 13}}
scala> decodefoo res1 : cats.data.xor [io.circe.error, foo] = right (qux (13, 일부 (14.0)))