4

私はこの関数の実装をplays jsonライブラリの使用から変更しようとしています

def apply[T](action: => ApiResponse[T])(implicit tjs: Writes[T], ec: ExecutionContext): Future[Result] = {
    action.fold(
      err =>
        Status(err.statusCode) {
          JsObject(Seq(
            "status" -> JsString("error"),
            "statusCode" -> JsNumber(err.statusCode),
            "errors" -> Json.toJson(err.errors)
          ))
        },
      t =>
        Ok {
          JsObject(Seq(
            "status" -> JsString("ok"),
            "response" -> Json.toJson(t)
          ))
        }
    )
  }

そのようにアルゴノートを使用するには

def apply[T](action: => ApiResponse[T])(implicit encodeJson: EncodeJson[T], ec: ExecutionContext): Future[Result] = {
    action.fold(
      err =>
        Status(err.statusCode) {
          Json(
          "status" -> jString("error"),
          "statusCode" -> jNumber(err.statusCode),
          "errors" -> err.errors.asJson
          )
        },
      t =>
        Ok {
          Json(
          "status" -> jString("ok"),
          "response" -> t.asJson
          )
        }
    )
  }

しかし、私は得る

Argonaut.Json のインスタンスを HTTP 応答に書き込めません。Writeable[argonaut.Json] を定義してみてください

Status{} ブロックと Ok{} ブロックの両方について、この問題に対する有益な回答がhttps://groups.google.com/forum/#!topic/play-framework/vBMf72a10Zcにありました。

だから私はそのように暗黙的な変換を作成しようとしました

implicit def writeableOfArgonautJson(implicit codec: Codec): Writeable[Json] = {
      Writeable(jsval => codec.encode(jsval.toString))
    }

これはjsonオブジェクトを文字列に変換し、それをcodec.encodeに提供してArray [Bytes]に変換すると思いますが、

アルゴナウト.Json に使用するコンテンツ タイプを推測できません。ContentTypeOf[argonaut.Json] を定義してみてください

jsval.nospaces.getBytes も Array[Bytes] を返すため、それがまったく役立つかどうかはわかりません

したがって、最後のエラー メッセージは、コンテンツ タイプ application.json を使用する必要があることをプレイに伝える必要があることを意味していると思いますが、これは不必要なウサギの穴である可能性があり、これを行うためのより簡単な方法があるはずです。

編集: contentType を定義することで、少なくともコンパイルが行われるようなうさぎの穴ではありませんでしたが、これが正しいかどうかはまだ知りたいです

4

1 に答える 1

3

あなたは自分の質問に答えたようですが、確認するために、次のWritable[A]とおりです。

  1. A型をArray[Bytes]およびに変換する方法
  2. 応答で使用するコンテンツ タイプ。これも必要です。
  3. 現在の文字エンコーディング

文字エンコーディングは暗黙的なインスタンスによって処理されるため、暗黙的なwhere is がCodec必要になります。ContentTypeOf[A]Aargonaunt.Json

implicit def contentTypeOf_ArgonautJson(implicit codec: Codec): ContentTypeOf[argonaut.Json] = {
  ContentTypeOf[argonaut.Json](Some(ContentTypes.JSON))
}

そして、スコープ内(定義したばかり)Writable[A]があるという型の制約があります。AContentTypeOf[A]

implicit def writeableOf_ArgonautJson(implicit codec: Codec): Writeable[argonaut.Json] = {
  Writeable(jsval => codec.encode(jsval.toString))
}

そして、あなたが指摘するように、うさぎの穴は終わりです。確かに、これはちょっとした気晴らしのように思えますが、Ok(myArgonautObject)追加の変換やヘッダー設定のボイラープレートを使用せずに、必要な数のアクションを実行できるようになったことを考えると、追加のコードはそれほど多くありません。

おそらくExtraJsonHelpers、定型文をさらに削減するために、これらの暗黙をトレイトに入れてコントローラーに混ぜることができます。

于 2015-02-01T16:05:12.133 に答える