-1

我想在以下代码中将message类型scala.Seq[Scala.Document]为 JSON 格式的变量转换为:

path("getMessages"){
          get {
            parameters('roomname.as[String]) {
              (roomname) =>
                try {
                  val messagesByGroupName = MongoDatabase.collectionForChat.find(equal("groupChatName",roomname)).toFuture()
                  val messages = Await.result(messagesByGroupName,60.seconds)
                  println("Messages:"+messages)
                  complete(messages)
                }
                catch {
                  case e:TimeoutException =>
                    complete("Reading file timeout.")
            }
          }
        }

但它在完成(消息)行上给了我错误。它不接受该类型的消息。

我尝试使用以下方法将其转换为 JSON:

import play.api.libs.json._

object MyJsonProtocol{
  implicit object ChatFormat extends Format[Chat] {
    def writes(c: Chat) : JsValue = {
      val chatSeq = Seq (
        "sender" -> JsString(c.sender),
        "receiver" -> JsString(c.receiver),
        "message" -> JsString(c.message),
        "groupChatName" -> JsString(c.groupChatName),
      )
      JsObject(chatSeq)
    }


    def reads(value: JsValue) = {
      JsSuccess(Chat("","","",""))
    }
  }
}

但它不起作用。

我的Chat.scala课程如下:

import play.api.libs.json.{Json, Reads, Writes}

class Chat(var sender:String,var receiver:String,var message:String, var groupChatName:String){
  def setSenderName(senderName:String) = {
    sender = senderName
  }
  def setReceiverName(receiverName:String) = {
    receiver = receiverName
  }
  def setMessage(getMessage:String) = {
    message = getMessage
  }
  def setGroupChatName(chatName:String) = {
    groupChatName = chatName
  }
}

object Chat {
  def apply(sender: String, receiver: String, message: String, groupname: String): Chat
  = new Chat(sender, receiver, message,groupname)

  def unapply(arg: Chat): Option[(String, String, String,String)] = ???
  implicit val requestReads: Reads[Chat] = Json.reads[Chat]
  implicit val requestWrites: Writes[Chat] = Json.writes[Chat]
}

我也无法弄清楚在unapply方法中要写什么。我是 scala 和 akka 的新手。

编辑: 我的MongoDatabase.scala集合如下:

object MongoDatabase {
  val chatCodecProvider = Macros.createCodecProvider[Chat]()

  val codecRegistry = CodecRegistries.fromRegistries(
    CodecRegistries.fromProviders(chatCodecProvider),
    DEFAULT_CODEC_REGISTRY
  )
  implicit val system = ActorSystem("Scala_jwt-App")
  implicit val executor: ExecutionContext = system.dispatcher
  val mongoClient: MongoClient = MongoClient()
  val databaseName = sys.env("database_name")
  // Getting mongodb database
  val database: MongoDatabase = mongoClient.getDatabase(databaseName).withCodecRegistry(codecRegistry)
  val registrationCollection = sys.env("register_collection_name")
  val chatCollection = sys.env("chat_collection")
  // Getting mongodb collection
  val collectionForUserRegistration: MongoCollection[Document] = database.getCollection(registrationCollection)
  collectionForUserRegistration.drop()
  val collectionForChat: MongoCollection[Document] = database.getCollection(chatCollection)
  collectionForChat.drop()
}

如果尝试改变 val collectionForChat: MongoCollection[Document] = database.getCollection(chatCollection)

val collectionForChat: MongoCollection[Chat] = database.getCollection[Chat](chatCollection)

然后我在下面的saveChatMessage()方法中出现错误:

def saveChatMessage(sendMessageRequest: Chat) : String = {
    val senderToReceiverMessage : Document = Document(
      "sender" -> sendMessageRequest.sender,
      "receiver" -> sendMessageRequest.receiver,
      "message" -> sendMessageRequest.message,
      "groupChatName" -> sendMessageRequest.groupChatName)
    val chatAddedFuture = MongoDatabase.collectionForChat.insertOne(senderToReceiverMessage).toFuture()
    Await.result(chatAddedFuture,60.seconds)
    "Message sent"
  }

val chatAddedFuture = MongoDatabase.collectionForChat.insertOne(senderToReceiverMessage).toFuture()这条线上,因为它接受Seq[Document]类型的数据,我正在尝试添加Seq[Chat]类型的数据

4

2 回答 2

0

我将假设MongoDatabase.collectionForChat.find(equal("groupChatName",roomname))返回Seq[Chat], 或Chat. 两者都是一样的玩。

您有 2 个选项:

  1. 在伴随对象上添加默认格式:

    object Chat {
        implicit val format: Format[Chat] = Json.format[Chat]
    }
    

    在这种情况下,您可以删除MyJsonProtocol未使用的对象。

  2. 如果您想保留自己的序列化程序(即MyJsonProtocol),则需要重命名MyJsonProtocolChat. 这样complete路由将能够找到隐式格式。

于 2021-01-14T10:22:55.183 回答
0
  1. 为您要发送的消息对象创建案例类,例如:
case class MyMessage(sender: String, receiver: String, message: String, groupChatName: String)
  1. 您应该为案例类的类型创建格式
implicit val MessageTypeFormat = Json.format[MyMessage]
  1. 如果完成应该获得 JSON 类型 - 然后在 MyMessage 的实例myMessage时调用完成。myMessage
complete(Json.toJson(myMessage))
于 2021-01-14T11:44:42.683 回答