我正在使用Play Framework(2.2.6)/ scala / mongoDB处理Web应用程序,我遇到了reactivemongo.bson.BSONObjectID
的问题。 (我是ReactiveMongo和Scala的初学者)
我的控制器包含以下代码:
val actForm = Form(tuple(
"name" -> optional(of[String]),
"shortcode" -> optional(of[String]),
"ccam" -> mapping(
"code" -> optional(of[String]),
"description" -> optional(of[String]),
"_id" -> optional(of[BSONObjectID])
)(CCAMAct.apply)(CCAMAct.unapply)
));
def addAct = AsyncStack(AuthorityKey -> Secretary) { implicit request =>
val user = loggedIn
actForm.bindFromRequest.fold(
errors => Future.successful(BadRequest(errors.errorsAsJson)), {
case (name, shortcode, ccam) =>
val newact = Json.obj(
"id" -> BSONObjectID.generate,
"name" -> name,
"shortcode" -> shortcode,
"ccam" -> ccam
)
settings.update(
Json.obj("practiceId" -> user.practiceId.get),
Json.obj("$addToSet" -> Json.obj("acts" -> Json.obj("acte" -> newact)))
).map { lastError => Ok(Json.toJson(newact)) }
})
}
CCAMAct 类的定义如下:
import models.db.Indexable
import play.api.libs.json._
import reactivemongo.bson.BSONObjectID
import reactivemongo.api.indexes.{Index, IndexType}
import models.db.{MongoModel, Indexable}
import scala.concurrent.Future
import play.modules.reactivemongo.json.BSONFormats._
import models.practice.Practice
import play.api.libs.functional.syntax._
case class CCAMAct(code:Option[String],
description:Option[String],
_id: Option[BSONObjectID] = None) extends MongoModel {}
object CCAMAct extends Indexable {
private val logger = play.api.Logger(classOf[CommonSetting]).logger
import play.api.Play.current
import play.modules.reactivemongo.ReactiveMongoPlugin._
import play.modules.reactivemongo.json.collection.JSONCollection
import scala.concurrent.ExecutionContext.Implicits.global
def ccam: JSONCollection = db.collection("ccam")
implicit val ccamFormat = Json.format[CCAMAct]
def index() = Future.sequence(
List (
Index(Seq("description" -> IndexType.Text))
).map(ccam.indexesManager.ensure)
).onComplete { indexes => logger.info("Text index on CCAM ends") }
}
因此编译器抛出了这个错误:
Cannot find Formatter type class for reactivemongo.bson.BSONObjectID. Perhaps you will need to import play.api.data.format.Formats._
"_id" -> optional(of[BSONObjectID])
^
(当然我已经导入了“play.api.data.format.Formats ._”)
我还尝试在网络上的类似帖子中添加自定义格式化程序。
object Format extends Format[BSONObjectID] {
def writes(objectId: BSONObjectID): JsValue = JsString(objectId.stringify)
def reads(json: JsValue): JsResult[BSONObjectID] = json match {
case JsString(x) => {
val maybeOID: Try[BSONObjectID] = BSONObjectID.parse(x)
if(maybeOID.isSuccess)
JsSuccess(maybeOID.get)
else {
JsError("Expected BSONObjectID as JsString")
}
}
case _ => JsError("Expected BSONObjectID as JsString")
}
}
......没有任何成功。
[更新后的帖子]
最后我无法找到播放表单类型(用于处理控制器中的POST请求)以映射包含BSONObjectID类型的类...
任何人都知道解决这个问题的干净解决方案吗?
答案 0 :(得分:1)
来自ReactiveMongo的BSON类型的JSON public Publisher(Jedis publisherJedis, String channels, String clusterName) {
this.publisherJedis = publisherJedis;
this.channels = channels;
this.clusterName = clusterName;
}
public void start() {
log.info("publishing on channel +odown");
try {
while(true) {
if(JedisPoolFactory.getMasterDown(clusterName)) {
publisherJedis.publish("+odown", "master down, master down");
}
}
} catch(Exception ex) {
log.error("failure with end of stream catching.", ex);
}
}
不是由Format
中的Play本身提供,而是由Play的ReactiveMongo插件提供。
Formats._