【问题标题】:Spray test case doesn't property unmarshal UTF-8 encoded json using HTTPEntity喷雾测试用例不使用 HTTPEntity 解组 UTF-8 编码的 json
【发布时间】:2016-07-27 04:34:27
【问题描述】:

我有一个使用 Spray 框架编写的 API 的 Scalatest,如下所示:

"correctly deserializes multi-lang title metadata" in {
  implicit def json4sFormats: org.json4s.Formats = ModelJsonHelper.jsonFormats

  val v2MultiLangTitle = getStringFromResource("/json_samples/cmp.asset.v2.AssetWriteMultiMetadata.json")

  //Deserialize
  val v2AssetEither = HttpEntity(`application/cmp.ela.assetWrite.v2+json`, v2MultiLangTitle).as[Asset]
  v2AssetEither.isRight shouldEqual true
  v2AssetEither.right.map(asset => {
    asset.assetMetadata.getOrElse(List()).size shouldEqual(3)
    asset.assetMetadata.getOrElse(List())(1).language shouldEqual("es")
    asset.assetMetadata.getOrElse(List())(1).data.title shouldEqual(Some("Encabezado prueba de AFP"))
    asset.assetMetadata.getOrElse(List())(2).language shouldEqual("tlh")
    asset.assetMetadata.getOrElse(List())(2).data.title shouldEqual(Some("Daj jaw AFP"))
    asset.assetMetadata.getOrElse(List())(0).language shouldEqual("de")
    asset.assetMetadata.getOrElse(List())(0).data.title shouldEqual(Some("Test AFP Überschrift"))
  })
}

def getStringFromResource(input: String): String = {
  Source.fromInputStream(this.getClass.getResourceAsStream(input))(Codec.UTF8).getLines.mkString("")
}

正在处理的json如下

{
  "assetMetadata" : [
    {
      "title": "Test AFP Überschrift",
      "language": "de"
    },
    {
      "title": "Encabezado prueba de AFP",
      "language": "es"
    },
    {
      "title": "Daj jaw AFP",
      "language": "tlh"
    }
  ]
}

并且失败发生在德语变音符号上:

[info] - correctly deserializes multi-lang title metadata *** FAILED ***
[info]   Some("Test AFP �berschrift") did not equal "Test AFP Überschrift" (V2AssetWriteMarshallerSpec.scala:367)

在表面之下,有一些用于解包过程的json4s。但是,如果我直接使用 json4s 解析器,则可以正确处理德语字符:

import scala.io.Source
import java.io.FileInputStream
val v = Source.fromInputStream(new FileInputStream("/path/to/project/src/test/resources/json_samples/cmp.asset.v2.AssetWriteMultiMetadata.json")).getLines.mkString("")
import org.json4s._
import org.json4s.native.JsonMethods._

val obj = parse(v)
(obj \ "assetMetadata")

给我结果:

res0: org.json4s.JValue = JArray(List(JObject(List((title,JString(Test AFP Überschrift)), ....

我正在使用 Spray 1.3.3 和 json4s 3.2.10。 HttpEntity 中的那个类型是自定义类型,我尝试将 ( "charset" -> "UTF-8" ) 添加为参数,如下所示:

val `application/cmp.ela.assetWrite.v2+json` = register(
    MediaType.custom(
      mainType = "application",
      subType = "cmp.ela.assetWrite.v2+json",
      compressible = true,
      binary = false,
      parameters = Map[String,String]( "charset" -> "UTF-8" )
    )
  )

..但测试仍然因无效字符而失败。如何让 Spray 正确解组包含国际字符的字符串?

【问题讨论】:

    标签: json scala utf-8 spray scalatest


    【解决方案1】:

    我帮助您在 Scala IRC 频道中找到了解决方案。我找到了这个链接,剩下的交给你了!

    https://github.com/spray/spray/blob/master/spray-http/src/main/scala/spray/http/MediaType.scala#L168

    固定测试:

      //Deserialize
      val v2AssetEither = HttpEntity(`application/vnd.dsa.assetWrite.v2+json` withCharset(HttpCharsets.`UTF-8`), v2MultiLangTitle).as[Asset]
      v2AssetEither.isRight shouldEqual true
    

    正在添加的关键

    withCharset(HttpCharsets.`UTF-8`)
    

    【讨论】:

      猜你喜欢
      • 2015-03-03
      • 1970-01-01
      • 1970-01-01
      • 2013-10-24
      • 1970-01-01
      • 2021-03-22
      • 2013-02-15
      • 1970-01-01
      • 2014-01-24
      相关资源
      最近更新 更多