Поскольку документация не готов, я спрошу здесь у сопровождающих akka.
Почему akka-http Unmarshaler
возвращает Future[T]
вместо T
? Вот моя цель. Я хочу разобрать класс из XML-ответа http так же, как это делается для json. Например, я хотел бы написать
Unmarshal(HttpResponse.entity).to[Person]
где класс case и его unmarshaller выглядят так
case class Person(name: String, age: Int)
implicit val personUnmarshaller = Unmarshaller[NodeSeq, Person] { _ => xml =>
Future(Person((xml \\ "name").text, (xml \\ "age").text.toInt))
}
Он не будет компилироваться с ScalaXmlSupport
, поставляемым с 1.0-RC4, потому что Unmarshaller[ResponseEntity,Person]
недоступен в области видимости. Поэтому, чтобы обмануть его, я написал два неявных преобразования
implicit def xmlUnmarshallerConverter[T](marsh: Unmarshaller[NodeSeq, T])(implicit mat: Materializer): FromEntityUnmarshaller[T] =
xmlUnmarshaller(marsh, mat)
implicit def xmlUnmarshaller[T](implicit marsh: Unmarshaller[NodeSeq, T], mat: Materializer): FromEntityUnmarshaller[T] =
defaultNodeSeqUnmarshaller.map(Unmarshal(_).to[T].value.get.get)
Это работает, но мне не нравятся уродливые .value.get.get
. Есть ли более элегантный способ реализовать это?
Future
, потому чтоHttpEntity
может быть нестрогим, и поэтому тело может быть неполным из-за типа получения ответа. То есть, если вы разбили ответы на фрагменты, вы не можете выполнить демаршалирование до тех пор, пока ответ не будет завершен. - person ale64bit   schedule 04.07.2015Future
. Насколько я помню,HttpEntity
по умолчанию имеет известную длину, но по-прежнему предоставляет содержимое черезSource[ByteString]
, и поэтому вы получаетеFuture
, я думаю. Тем не менее, я согласен с вами, что не очень приятно, когда вы хотите, чтобы все было просто. - person ale64bit   schedule 04.07.2015Unmarshaller[NodeSeq, Person]
в первую очередь? В противном случае вы могли бы напрямую определитьFromEntityUnmarshaller[Person]
с помощьюdefaultNodeSeqUnmarshaller.map(xml => /* the code from your personUnmarshaller*/)
. - person jrudolph   schedule 04.07.2015NodeSeq
unmarshaler, который вы, ребята, предоставили, который используется на основеContent-Type
. Думаю, я мог бы создать свой собственный трейт вместо использованияUnmarshaller[NodeSeq, T]
, но я предпочитаю использовать как можно больше стандартных компонентов.. - person expert   schedule 04.07.2015xmlUnmarshaller
, чтобы избежатьvalue.get.get
? Я получаю исключение, потому что вызываетсяNone,get
. По-видимому, unmarshaller пытается получить значение до того, как оно будет рассчитано. - person expert   schedule 05.07.2015Unmarshaller[NodeSeq, Person]
для использования стандартногоNodeSeq
unmashaller. Вот почему я бы предложил попробоватьimplicit val personUnmarshaller: FromEntityUnmarshaller[Person] = defaultNodeSeqUnmarshaller.map(xml => /* the code from your personUnmarshaller*/)
- person jrudolph   schedule 05.07.2015