2015-08-24 25 views
12

ben çalışıyorum Akka-http ve umarım birisi şu sorulara ışık tutabilir: birinciyi kabul dayalı farklı yolları oluşturmak nasıldırAkka-http: Kabul ve İçerik tipi işleme

  1. : istekte başlık? Örneğin, "json" işlemek ve "xml" isteklerini işlemek için bir kod yolu istiyorum (başlık eksikse varsayılan olarak "json" için)

  2. ContentType'ın istemesini istemediğim durumlarda ertelenir, nasıl belirleyebilirim? Örneğin, aşağıdaki kodda json'u compactPrint() ile çalıştırmaya çalışıyorum ancak bu onu bir dizgeye, dolayısıyla "text/plain" olarak değiştirir. Bunu geçersiz kılmak ve müşteriye hala json olduğunu söylemek istiyorum.

Benim kodum böyle bir şeydir;

... 
path("api") { 
      get { 
       complete { 
       getStuff.map[ToResponseMarshallable] { 
        case Right(r) if r.isEmpty => List[String]().toJson.compactPrint 
        case Right(r) => r.toJson.compactPrint 
        case Left(e) => BadRequest -> e 
       } 
       } 
      } 
     } 
... 

Bu durumda yanıt text/plain, çünkü compactPrint bir dize oluşturur. eleştiri çok hoş geldiniz. ;)

aşağıdaki gibi içerik türü tanımlayabilirsiniz
+1

Akka-http'un otomatik içerikli müzakere özelliğini kullanmak için, kaynak türünüz için birkaç içerik türüne göre marş kalacağınız bir kunduracı sağlamanız gerekir. Marshaller.oneOf'unu kullanarak, her bir mareşalin yalnızca bir içerik türüne nasıl karar verileceğini bildikleri farklı mareşallar oluşturmak için kullanabilirsiniz. Marshaller hakkındaki belgeleri http://doc.akka.io/docs/akka-stream-and-http-experimental/1.0/scala/http/common/marshalling.html#Custom_Marshallers adresinde gördünüz mü? – jrudolph

+0

Teşekkürler. Bu rotayı bitirdim. –

cevap

8

,

Sen olarak özel yönergesini oluşturabilir
complete { 
      HttpResponse(entity = HttpEntity(ContentType(MediaTypes.`application/json`), """{"id":"1"}""")) 
     } 

,

def handleReq(json: String) = { 
    (get & extract(_.request.acceptedMediaRanges)) { 
     r => 
     val encoding: MediaRange = 
      r.intersect(myEncodings).headOption 
      .getOrElse(MediaTypes.`application/json`) 
     complete { 
      // check conditions here 
     // HttpResponse(entity = HttpEntity(encoding.specimen, json)) // 
     } 
    } 
    } 

gibi rotada yönergesini kullanmak

val route = path("api"){ handleReq(json) } 
+0

Teşekkürler. Sadece, gerçek işlemeyi kapsamamak için, üstbilgiye dayalı bir reddetme yapmak için bir direktif umuyordum. Ama yine de, XML veya JSON'a serileştirme işlemini otomatik olarak yapan mareşalleri hayata geçirdim, bu yüzden artık bu yaklaşıma ihtiyacım yok. Ama yardımın için teşekkür ederim, hayal kırıklığımı geçmeme yardımcı oldu ve bir şeyleri gerçekleştirmenin bir yolu. Bu yüzden cevabı kabul edeceğim. –

+0

Burada daha iyi kullanım ContentTypes.'uygulama/json' yerine ContentType (MediaTypes.'application/json') – RomKazanova

1

1. soru için olası bir cevap bu gibi görünüyor, ancak özel bir direktifle veya daha zarif bir şeyle yapmak istiyorum. Ne yazık ki, Akka-Http özel direktifleri için dokümantasyon eksik görünüyor.

// the encodings I want, in the order of preference 
val myEncodings = Seq(MediaRange(`application/xml`),MediaRange(`application/json`)) 

    ... 
    path("api") { 
       (get & extract(_.request.acceptedMediaRanges)){ 
        r => 
        val encoding = 
         r.intersect(myEncodings).headOption 
         .getOrElse(MediaRange(`application/json`)) 
        complete { 
         // check "encoding" here and make decision. 
        } 
       } 
      } 
    ... 

umuduyla birisi bir şey temizleyici sağlayabilir.

+0

Cevabını güncelledim, kontrol edebilirsin, istediğin buydu. –

0

Kabul edilen cevap akka-http v10.0.3 ile artık çalışmıyor gibi görünüyor.

Bu olsa çalışır: Ayrıca bu yardımcı olur

val myEncodings = Seq(MediaRange(`application/xml`),MediaRange(`application/json`)) 

path("api") { 
     (get & extract(_.request.headers)){ requestHeaders => 
     complete { 
      val mediaTypeNegotiator = new MediaTypeNegotiator(requestHeaders) 
      if(mediaTypeNegotiator.accept(MediaTypes.`application/xml`)) { 
      // respond with xml 
      } else if(mediaTypeNegotiator.accept(MediaTypes.`application/json`)) { 
      // respond with json 
      } else { 
      // respond with json by default or reject properly : 
      reject(UnsupportedRequestContentTypeRejection(Set(MediaTypes.`application/xml`, MediaTypes.`application/json`))) 
      } 
     } 
    } 
} 

Umutlar yapabileceği

// the encodings I want, in the order of preference 
val myEncodings = Seq(MediaRange(`application/xml`),MediaRange(`application/json`)) 

... 
path("api") { 
      (get & extract(_.request.headers)){ requestHeaders => 
       val mediaTypeNegotiator = new MediaTypeNegotiator(requestHeaders) 
       val encoding = mediaTypeNegotiator 
        .acceptedMediaRanges 
        .intersect(myEncodings) 
        .headOption 
        .getOrElse(MediaRange(`application/json`)) 
       complete { 
        // check "encoding" here and make decision. 
       } 
      } 
     } 
... 

.

İlgili konular