Спрей не будет преобразовывать класс моего случая в json и ожидать спрей.httpx.marshalling.ToResponseMarshallable

Я пытаюсь воспроизвести это или это, но я продолжаю получать сообщение об ошибке, которое не могу исправить...

Прежде всего, вот мои зависимости:

compile 'io.spray:spray-can_2.11:1.3.1'
compile 'io.spray:spray-routing_2.11:1.3.1',
compile 'io.spray:spray-json_2.11:1.2.6'

Теперь я пытаюсь сделать следующее:

class WHttpService extends Actor with HttpService with ActorLogging {

  implicit def actorRefFactory = context

  def receive = runRoute(route)

  lazy val route = logRequest(showReq _) {
    // Way too much imports but I tried all I could find
    import spray.json._
    import DefaultJsonProtocol._
    import MasterJsonProtocol._
    import spray.httpx.SprayJsonSupport._
    path("server" / Segment / DoubleNumber / DoubleNumber) { (login, first, second) =>
      get {
          complete {
            Answer(1, "test")
          }
      }
    }
  }

  private def showReq(req : HttpRequest) = LogEntry(req.uri, InfoLevel)
}

С участием:

case object MasterJsonProtocol extends DefaultJsonProtocol with SprayJsonSupport {
  import spray.json._

  case class Answer(code: Int, content: String)
  implicit val anwserFormat: JsonFormat[Answer] = jsonFormat2(Answer)
}

Теперь я получаю эту ошибку:

Error:(42, 19) type mismatch;
 found   : MasterJsonProtocol.Answer
 required: spray.httpx.marshalling.ToResponseMarshallable
            Answer(1, "test")
                  ^

Я пробовал много вещей, но не могу заставить это работать. я пробовал с

Answer(1, "test").toJson
Answer(1, "test").toJson.asJsObject

Наконец то, что я сделал, было

complete {
    Answer(1, "test").toJson.compactPrint
}

Это работает, но отправляется клиенту как Content-Type: text/plain, когда мне нужно application/json.

Кто-нибудь видит, в чем здесь проблема?

Изменить: я добавил пример проекта на github https://github.com/ydemartino/spray-test


person ydemartino    schedule 11.07.2014    source источник
comment
+1. Это потрясающий первый пост, добро пожаловать на SO: D   -  person JoeBilly    schedule 11.07.2014
comment
Я должен был спросить об этом в комментарии высшего уровня. Какую версию Scala вы используете? Похоже, у Spray еще нет релиза для 2.11 github.com/spray/spray/issues /790   -  person Gangstead    schedule 12.07.2014
comment
Я видел эту проблему, но согласно официальной документации: spray.io/project-info/current -versions spray 1.3.1 создан для Scala 2.10.3 и Akka 2.3.0, а также Scala 2.11.1 и Akka 2.3.2. Поскольку я мог получить файлы, используя «io.spray:spray-can_2.11:1.3.1», я думал, что они тем временем исправили это. Я попробую со scala 2.10, чтобы увидеть, скомпилируется ли мой код.   -  person ydemartino    schedule 12.07.2014
comment
Я добавил образец проекта на github, который позволяет воспроизвести проблему. В этом проекте используется scala 2.10: github.com/ydemartino/spray-test   -  person ydemartino    schedule 12.07.2014


Ответы (3)


Я создал запрос на вытягивание, чтобы решить вашу проблему: https://github.com/ydemartino/spray-test/pull/1

Объект протокола json должен быть объявлен, прежде чем его можно будет использовать неявно. Я не совсем уверен, почему компилятор не может это понять, но перемещение объявления объекта наверх исправило это.

Для вашего реального проекта обязательно объявите пакеты в каждом файле, а затем используйте эти пакеты в операторах импорта.

person Gangstead    schedule 11.07.2014
comment
Вау, спасибо! Я тоже не могу понять, почему мы должны объявлять это раньше... Во всяком случае, была проблема с версией scala, я попробовал тот же код, изменив зависимости на 2.11, и он не скомпилируется с ошибкой, которая у меня была раньше... - person ydemartino; 12.07.2014

Переместите свою модель за пределы протокола json и сделайте ее обычным объектом (а не объектом case)

case class Answer(code: Int, content: String)

object MasterJsonProtocol extends DefaultJsonProtocol {
  implicit val anwserFormat = jsonFormat2(Answer)
}

Изменить

Также очистите свой импорт:

class WHttpService extends Actor with HttpService with ActorLogging {

  implicit def actorRefFactory = context

  def receive = runRoute(route)

  lazy val route = logRequest(showReq _) {
    // Way too much imports but I tried all I could find
    import MasterJsonProtocol._
    import spray.httpx.SprayJsonSupport._

    path("server" / Segment / DoubleNumber / DoubleNumber) { (login, first, second) =>
      get {
          complete {
            Answer(1, "test")
          }
      }
    }
  }

  private def showReq(req : HttpRequest) = LogEntry(req.uri, InfoLevel)
}
person Gangstead    schedule 11.07.2014
comment
Эй, спасибо за ответ, я сделал то, что вы сказали, превратил его в объект (на самом деле я не заметил, что это был объект case), удалил с помощью SprayJsonSupport и переместил модель наружу, но я получаю точно такую ​​​​же ошибку. - person ydemartino; 11.07.2014
comment
Эй, я пробовал с очисткой импорта. То же самое. В моей среде IDE два из них выделены серым цветом как неиспользуемый оператор импорта, мне не хватает зависимости, чтобы это работало? - person ydemartino; 12.07.2014
comment
Какую версию Scala вы используете? - person Gangstead; 12.07.2014
comment
Scala версии 2.11.1 с jdk 1.8.05. Я переключаюсь на jdk 1.7.60, чтобы проверить, не портит ли java мою сборку, но получил тот же результат. - person ydemartino; 12.07.2014

В моем случае имя неразрешимого экземпляра неявного формата конфликтовало с локальным определением, поэтому оно было затенено. Компилятор милостиво умолчал об этом. Только обнаружил это случайно после нескольких часов тряски головой.

person Nikita Volkov    schedule 21.10.2016