2017-01-20 4 views
0

私はScalaとSwaggerを使用しています.Jsonの値をループしてチェックするなどの方法を理解する助けが必要です。HTTPから受け取ったJson Stringを解析して値をループする方法

リクエストHTTP GETを後に返されるJSON文字列は次のようになります。

{ 
"count": 3, 
"items": [ 
    { 
    "Id": "fd0a9e5a", 
    "DbName": "Xterior Prod", 
    "Name": "XP" 
    }, 
    { 
    "Id": "4158a1a6", 
    "DbName": "Invidibi Pappear", 
    "Name": "ISP" 
    }, 
    { 
    "Id": "7e0c57046d3f", 
    "DbName": "Multi Match Test", 
    "Name": "MMP" 
    }] 
} 

私のUIは、入力するユーザーIDを可能にします。私がしなければならないことは、APIから返されたJson値をループし、入力されたIDと一致するものを見つけることです。一度私が試合を見つけると、私はデータベースがそれに "テスト"キーワードを持っているかどうかをチェックする必要があります。もしそうなら、私はDbNameと省略名を表示する必要があります。

ここにガイドがいくつか見つかりました(たとえばForeach with JSON Arrays in Play2 and Scala)が、私にとってはうまくいきませんでした。私は私のコードを実行すると、私はこのエラーを取得:ここ

play.api.libs.json.JsResultException: JsResultException(errors:List(((0)/Id,List(ValidationError(List(error.path.missing),WrappedArray()))), ((0)/DbName,List(ValidationError(List(error.path.missing),WrappedArray()))), ((1)/Id,List(ValidationError(List(error.path.missing),WrappedArray()))), ((1)/DbName,List(ValidationError(List(error.path.missing),WrappedArray()))), ((2)/Id,List(ValidationError(List(error.path.missing),WrappedArray()))), ((2)/DbName,List(ValidationError(List(error.path.missing),WrappedArray()))), 

は私のコードです:

case class Environment(Id: String, DbName: String, Name: String) 
contentType = "application/json" 
    //get json from http 

    val httpClient = HttpClients.createDefault() 
    val httpResponse = httpClient.execute(new HttpGet("http://www.customers.com/environments")) 
    val entity = httpResponse.getEntity 

    val content = fromInputStream(httpResponse.getEntity.getContent()).getLines().mkString 

    implicit val envReader = Json.reads[Environment] 
    val envList = (Json.parse(content) \ "items").as[List[Environment]] 
    envList.foreach { env => 
     if (env.Id == EnvId) 
     if (env.DbName.contains("Test")) 
      println(env.DbName + " - " + env.Name) 
      else BadRequest("Not allowed") 
     else 
     BadRequest("ID not found") 
    } 

ENVIDは、ユーザがinputed IDを保持する変数です。誰かがなぜエラーとそれを修正する方法を教えてもらえますか?ありがとう。

注:ここでは、インポートorg.json4s.JsonASTまたはインポートplay.api.libs.json

答えて

0

はすでに答えを得ました。これは私がやった方法です:

case class Environment(Id: String, DbName: String, Name: String) 
class EnvironmentInfo{ 
def CheckProdEnvironment(id: String): Option[String] = { 
    val httpClient = HttpClients.createDefault() 
    val httpResponse = httpClient.execute(new HttpGet("http://example.com")) 
    val content = fromInputStream(httpResponse.getEntity.getContent()).getLines().mkString 

    val envItems = (parse(content) \\ "items").children 
    for (items <- envItems) { 
     val env = items.extract[Environment] 
     if (env.EnvId == Some(id)) { 
     if (equalsIgnoreCase(env.DbName.mkString, "Test")) //do something 
     else //do something 
     } 
    } 
    None 
    } 
} 
0

を使用すると、circeを使用してのアプローチですしてください。 CursorでJSONをナビゲートし、Decoder[A] typeclassを使用してEnvironmentのリストにデコードします。 Either[Failure, A]値で作業することに注意してください。

import io.circe._ 

case class Environment(id: String, dbName: String, name: String) 

implicit val environmentDecoder: Decoder[Environment] = Decoder.instance[Environment] { 
    json => 
    for { 
     id <- json.downField("Id").as[String] 
     dbName <- json.downField("DbName").as[String] 
     name <- json.downField("Name").as[String] 
    } yield { 
     Environment(id, dbName, name) 
    } 
} 

// alternatively: 
// implicit val environmentDecoder: Decoder[Environment] = 
// Decoder.forProduct3[String, String, String, Environment]("Id", "DbName", "Name")(Environment.apply) 


val text = 
    """{ 
    | "count": 3, 
    | "items": [{ 
    | "Id": "fd0a9e5a", 
    | "DbName": "Xterior Prod", 
    | "Name": "XP" 
    | }, { 
    | "Id": "4158a1a6", 
    | "DbName": "Invidibi Pappear", 
    | "Name": "ISP" 
    | }, { 
    | "Id": "7e0c57046d3f", 
    | "DbName": "Multi Match Test", 
    | "Name": "MMP" 
    | }] 
    |} 
    """.stripMargin 

val json = parser.parse(text).fold(_ => ???, json => json) 


val res: Either[DecodingFailure, List[Environment]] = json.hcursor.downField("items").as[List[Environment]] 


println(res) 
// Right(List(Environment(fd0a9e5a,Xterior Prod,XP), Environment(4158a1a6,Invidibi Pappear,ISP), Environment(7e0c57046d3f,Multi Match Test,MMP))) 


// or simply 
// val res2 = parser.parse(text).right 
// .flatMap(_.hcursor.downField("items").as[List[Environment]]) 

また、HTTPリクエストを行うためにhttp4s'http4s-blaze-clienthttp4s-circeを使用することができます。

import org.http4s._ 
import org.http4s.circe._ 
import scalaz.concurrent._ 

val client = org.http4s.client.blaze.defaultClient 

val fetchEnvironments: Task[List[Environment]] = 
    client.fetchAs[Json](Request(Method.GET, Uri.uri("http://example.com"))) 
    .flatMap { json => 
     json.hcursor.downField("items").as[List[Environment]].fold(
     failure => Task.fail(failure), 
     xs => Task.now(xs) 
    ) 
    } 

val xs = fetchEnvironments.unsafePerformSync 
+0

こんにちは、これを実装する方法はjson4sを使っているのですか?これらはすでにjsonが現在のプロジェクトで実装されている方法であり、私はこれらの同じライブラリを一貫性のあるものとして使うことを好むでしょう。 – oneDerer

関連する問題