2

スプレー ルーティングを使用して、クエリ文字列パラメーターを JSON エンティティとマージする単一のディレクティブが必要です。どちらもオプションです。マーシャリングが発生する前にこれを発生させたいと思います。

このようなもの:

val myRoute = mergedParametersAndEntity(as[DomainSpecificClass]) { myobj =>
  // ... code code code ...
  complete(OK, myobj.someMethod)
}

基本的に私が望んでいたのは、次の動作でした。

誰かが次のようなリクエストをしたとき:

POST /v1/resource?a=helloQS&b=helloQS
Content-Type: application/json

{"a":"helloFromJson","c":"helloFromJson"}

次に、上記のオブジェクト ( myobj) にキーを含めることができます。

a -> helloFromJson
b -> helloQS
c -> helloFromJson

つまり、リクエスト本文で指定されたアイテムは、クエリ文字列内のものをオーバーライドします。私はこれが何とか可能でなければならないことを知っていますが、それを行う方法がわかりません。誰でも助けることができますか?

ありがとうございました!

4

2 に答える 2

2

私の提案:このアプローチをとらないでください。汚い感じです。可能であれば、製図板に戻ります。

そのことを念頭に置いて、Spray の既存の JSON マーシャリング サポートでは、必要なようにマージを挿入することはできません。自分で縫い合わせる必要があります。このようなものは、少なくとも正しい方向を示しているはずです (それがあなたが行かなければならない方向である場合):

import org.json4s.JsonAST._
import org.json4s.JsonDSL._
def mergedParametersAndEntity[T](implicit m:Manifest[T]): Directive1[T] = {
  entity(as[JObject]).flatMap { jObject =>
    parameterMap flatMap { params =>
      val left = JObject(params.mapValues { v => JString(v) }.toSeq : _*)
      provide(left.merge(jObject).extract[T])
    }
  }
}
于 2014-02-17T10:22:14.620 に答える
0

これを行う方法をまだ疑問に思っている人がいる場合は、JSON をアンマーシャリングする前に param 値をコピーできる小さな Spray ディレクティブを次に示します。JSON レンズ ( https://github.com/jrudolph/json-lenses ) を使用して、アンマーシャリングの前にリクエスト本文を変更します。

def updateJson(update: Update): Directive0 = {
  mapRequest((request: HttpRequest) => {
    request.entity match {
      case Empty => request
      case NonEmpty(contentType, data) =>
        try {
          request.copy(entity = HttpEntity(`application/json`, JsonParser(data.asString).update(update).toString))
        }
        catch {
          case e: ParsingException => request
        }
    }
  })
}

で、使い方はこんな感じ。PUT リクエストでリソースを更新し、URL からアンマーシャラーに ID を渡したいとします (非常に一般的なシナリオです)。

// Model
case class Thing(id: Long, title: String, description: String, createdAt: DateTime)

// Actor message for the update operation
case class UpdateThing(id: Long, title: String)

// Spray routing
def thingsRoute = 
  path("things" / Segment) { id =>
    put {
      updateJson(field("id") ! set[Long](id)) {
        entity(as[UpdateThing]) { updateThing =>
          complete {
            // updateThing now has the ID set
            (someActor ? updateThing).mapTo[Thing]
          }
        }
      }
    }
  }

ディレクティブと組み合わせて、parameters任意の GET パラメータを設定することもできます。

于 2015-12-06T05:57:59.433 に答える